diff options
author | Lua Team <team@lua.org> | 1997-07-01 12:00:00 +0000 |
---|---|---|
committer | repogen <> | 1997-07-01 12:00:00 +0000 |
commit | 4f8c5d0f284e1f4da717aea5008915f185cd2e05 (patch) | |
tree | 5671acf8a2cacf0c0524ce96d22959590a3aa5af /src | |
parent | 47a298a24ad3a8202440051de5938618502302a0 (diff) | |
download | lua-github-4f8c5d0f284e1f4da717aea5008915f185cd2e05.tar.gz |
Lua 3.03.0
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 18 | ||||
-rw-r--r-- | src/auxlib.c | 81 | ||||
-rw-r--r-- | src/auxlib.h | 30 | ||||
-rw-r--r-- | src/fallback.c | 395 | ||||
-rw-r--r-- | src/fallback.h | 72 | ||||
-rw-r--r-- | src/func.c | 42 | ||||
-rw-r--r-- | src/func.h | 5 | ||||
-rw-r--r-- | src/hash.c | 281 | ||||
-rw-r--r-- | src/hash.h | 33 | ||||
-rw-r--r-- | src/inout.c | 448 | ||||
-rw-r--r-- | src/inout.h | 25 | ||||
-rw-r--r-- | src/lex.c | 219 | ||||
-rw-r--r-- | src/lex.h | 7 | ||||
-rw-r--r-- | src/lua.stx | 63 | ||||
-rw-r--r-- | src/luac/dump.c | 30 | ||||
-rw-r--r-- | src/luac/luac.c | 139 | ||||
-rw-r--r-- | src/luac/luac.h | 11 | ||||
-rw-r--r-- | src/luac/print.c | 233 | ||||
-rw-r--r-- | src/luac/print.h | 9 | ||||
-rw-r--r-- | src/luamem.c | 159 | ||||
-rw-r--r-- | src/luamem.h (renamed from src/mem.h) | 6 | ||||
-rw-r--r-- | src/mem.c | 58 | ||||
-rw-r--r-- | src/opcode.c | 886 | ||||
-rw-r--r-- | src/opcode.h | 71 | ||||
-rw-r--r-- | src/parser.c | 660 | ||||
-rw-r--r-- | src/table.c | 180 | ||||
-rw-r--r-- | src/table.h | 11 | ||||
-rw-r--r-- | src/tree.c | 118 | ||||
-rw-r--r-- | src/tree.h | 18 | ||||
-rw-r--r-- | src/undump.c | 145 | ||||
-rw-r--r-- | src/undump.h | 15 | ||||
-rw-r--r-- | src/zio.c | 79 | ||||
-rw-r--r-- | src/zio.h | 48 |
33 files changed, 2966 insertions, 1629 deletions
diff --git a/src/Makefile b/src/Makefile index 1ac2ab85..9fe13c83 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,19 +4,23 @@ LUA= .. include $(LUA)/config -OBJS= fallback.o\ +OBJS= auxlib.o\ + fallback.o\ func.o\ hash.o\ inout.o\ lex.o\ - mem.o\ + luamem.o\ opcode.o\ parser.o\ table.o\ tree.o\ - undump.o + undump.o\ + zio.o -SRCS= fallback.c\ +SRCS= auxlib.c\ + auxlib.h\ + fallback.c\ fallback.h\ func.c\ func.h\ @@ -26,8 +30,8 @@ SRCS= fallback.c\ inout.h\ lex.c\ lex.h\ - mem.c\ - mem.h\ + luamem.c\ + luamem.h\ opcode.c\ opcode.h\ parser.c\ @@ -39,6 +43,8 @@ SRCS= fallback.c\ types.h\ undump.c\ undump.h\ + zio.c\ + zio.h\ lua.stx SLIB= $(LIB)/liblua.a diff --git a/src/auxlib.c b/src/auxlib.c new file mode 100644 index 00000000..e6f71f29 --- /dev/null +++ b/src/auxlib.c @@ -0,0 +1,81 @@ +char *rcs_auxlib="$Id: auxlib.c,v 1.5 1997/04/14 15:30:03 roberto Exp $"; + +#include <stdio.h> +#include <stdarg.h> +#include <string.h> + +#include "lua.h" +#include "auxlib.h" +#include "luadebug.h" + + + +int luaI_findstring (char *name, char *list[]) +{ + int i; + for (i=0; list[i]; i++) + if (strcmp(list[i], name) == 0) + return i; + return -1; /* name not found */ +} + + +void luaL_arg_check(int cond, int numarg, char *extramsg) +{ + if (!cond) { + char *funcname; + lua_getobjname(lua_stackedfunction(0), &funcname); + if (funcname == NULL) + funcname = "???"; + if (extramsg == NULL) + luaL_verror("bad argument #%d to function `%s'", numarg, funcname); + else + luaL_verror("bad argument #%d to function `%s' (%s)", + numarg, funcname, extramsg); + } +} + +char *luaL_check_string (int numArg) +{ + lua_Object o = lua_getparam(numArg); + luaL_arg_check(lua_isstring(o), numArg, "string expected"); + return lua_getstring(o); +} + +char *luaL_opt_string (int numArg, char *def) +{ + return (lua_getparam(numArg) == LUA_NOOBJECT) ? def : + luaL_check_string(numArg); +} + +double luaL_check_number (int numArg) +{ + lua_Object o = lua_getparam(numArg); + luaL_arg_check(lua_isnumber(o), numArg, "number expected"); + return lua_getnumber(o); +} + + +double luaL_opt_number (int numArg, double def) +{ + return (lua_getparam(numArg) == LUA_NOOBJECT) ? def : + luaL_check_number(numArg); +} + +void luaL_openlib (struct luaL_reg *l, int n) +{ + int i; + for (i=0; i<n; i++) + lua_register(l[i].name, l[i].func); +} + + +void luaL_verror (char *fmt, ...) +{ + char buff[1000]; + va_list argp; + va_start(argp, fmt); + vsprintf(buff, fmt, argp); + va_end(argp); + lua_error(buff); +} diff --git a/src/auxlib.h b/src/auxlib.h new file mode 100644 index 00000000..09020b46 --- /dev/null +++ b/src/auxlib.h @@ -0,0 +1,30 @@ +/* +** $Id: auxlib.h,v 1.3 1997/04/07 14:48:53 roberto Exp $ +*/ + +#ifndef auxlib_h +#define auxlib_h + +#include "lua.h" + +struct luaL_reg { + char *name; + lua_CFunction func; +}; + +void luaL_openlib (struct luaL_reg *l, int n); +void luaL_arg_check(int cond, int numarg, char *extramsg); +char *luaL_check_string (int numArg); +char *luaL_opt_string (int numArg, char *def); +double luaL_check_number (int numArg); +double luaL_opt_number (int numArg, double def); +void luaL_verror (char *fmt, ...); + + + +/* -- private part (only for Lua modules */ + +int luaI_findstring (char *name, char *list[]); + + +#endif diff --git a/src/fallback.c b/src/fallback.c index 5718f5c1..5a0b5a5b 100644 --- a/src/fallback.c +++ b/src/fallback.c @@ -3,130 +3,37 @@ ** TecCGraf - PUC-Rio */ -char *rcs_fallback="$Id: fallback.c,v 1.25 1996/04/25 14:10:00 roberto Exp $"; +char *rcs_fallback="$Id: fallback.c,v 2.9 1997/06/23 18:27:53 roberto Exp $"; #include <stdio.h> #include <string.h> -#include "mem.h" +#include "auxlib.h" +#include "luamem.h" #include "fallback.h" #include "opcode.h" #include "lua.h" #include "table.h" +#include "tree.h" +#include "hash.h" -static void errorFB (void); -static void indexFB (void); -static void gettableFB (void); -static void arithFB (void); -static void concatFB (void); -static void orderFB (void); -static void GDFB (void); -static void funcFB (void); - -/* -** Warning: This list must be in the same order as the #define's -*/ -struct FB luaI_fallBacks[] = { -{"error", {LUA_T_CFUNCTION, {errorFB}}, 1, 0}, -{"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1}, -{"gettable", {LUA_T_CFUNCTION, {gettableFB}}, 2, 1}, -{"arith", {LUA_T_CFUNCTION, {arithFB}}, 3, 1}, -{"order", {LUA_T_CFUNCTION, {orderFB}}, 3, 1}, -{"concat", {LUA_T_CFUNCTION, {concatFB}}, 2, 1}, -{"settable", {LUA_T_CFUNCTION, {gettableFB}}, 3, 0}, -{"gc", {LUA_T_CFUNCTION, {GDFB}}, 1, 0}, -{"function", {LUA_T_CFUNCTION, {funcFB}}, -1, -1}, - /* no fixed number of params or results */ -{"getglobal", {LUA_T_CFUNCTION, {indexFB}}, 1, 1} - /* same default behavior of index FB */ -}; - -#define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB)) - -void luaI_setfallback (void) -{ - int i; - char *name = lua_getstring(lua_getparam(1)); - lua_Object func = lua_getparam(2); - if (name == NULL || !lua_isfunction(func)) - lua_error("incorrect argument to function `setfallback'"); - for (i=0; i<N_FB; i++) - { - if (strcmp(luaI_fallBacks[i].kind, name) == 0) - { - luaI_pushobject(&luaI_fallBacks[i].function); - luaI_fallBacks[i].function = *luaI_Address(func); - return; - } - } - /* name not found */ - lua_error("incorrect argument to function `setfallback'"); -} - - -static void errorFB (void) -{ - lua_Object o = lua_getparam(1); - if (lua_isstring(o)) - fprintf (stderr, "lua: %s\n", lua_getstring(o)); - else - fprintf(stderr, "lua: unknown error\n"); -} - - -static void indexFB (void) -{ - lua_pushnil(); -} - - -static void gettableFB (void) -{ - lua_error("indexed expression not a table"); -} - - -static void arithFB (void) -{ - lua_error("unexpected type at conversion to number"); -} - -static void concatFB (void) -{ - lua_error("unexpected type at conversion to string"); -} - - -static void orderFB (void) -{ - lua_error("unexpected type at comparison"); -} - -static void GDFB (void) { } - -static void funcFB (void) -{ - lua_error("call expression not a function"); -} - - -/* +/* ------------------------------------------- ** Reference routines */ static struct ref { - Object o; + TObject o; enum {LOCK, HOLD, FREE, COLLECTED} status; } *refArray = NULL; static int refSize = 0; -int luaI_ref (Object *object, int lock) +int luaI_ref (TObject *object, int lock) { int i; int oldSize; - if (tag(object) == LUA_T_NIL) + if (ttype(object) == LUA_T_NIL) return -1; /* special ref for nil */ for (i=0; i<refSize; i++) if (refArray[i].status == FREE) @@ -151,9 +58,9 @@ void lua_unref (int ref) } -Object *luaI_getref (int ref) +TObject *luaI_getref (int ref) { - static Object nul = {LUA_T_NIL, {0}}; + static TObject nul = {LUA_T_NIL, {0}}; if (ref == -1) return &nul; if (ref >= 0 && ref < refSize && @@ -164,7 +71,7 @@ Object *luaI_getref (int ref) } -void luaI_travlock (int (*fn)(Object *)) +void luaI_travlock (int (*fn)(TObject *)) { int i; for (i=0; i<refSize; i++) @@ -181,11 +88,281 @@ void luaI_invalidaterefs (void) refArray[i].status = COLLECTED; } -char *luaI_travfallbacks (int (*fn)(Object *)) + +/* ------------------------------------------- +* Internal Methods +*/ + +char *luaI_eventname[] = { /* ORDER IM */ + "gettable", "settable", "index", "getglobal", "setglobal", "add", + "sub", "mul", "div", "pow", "unm", "lt", "le", "gt", "ge", + "concat", "gc", "function", + NULL +}; + + + +static int luaI_checkevent (char *name, char *list[]) +{ + int e = luaI_findstring(name, list); + if (e < 0) + luaL_verror("`%s' is not a valid event name", name); + return e; +} + + +struct IM *luaI_IMtable = NULL; + +static int IMtable_size = 0; +static int last_tag = LUA_T_NIL; /* ORDER LUA_T */ + + +/* events in LUA_T_LINE are all allowed, since this is used as a +* 'placeholder' for "default" fallbacks +*/ +static char validevents[NUM_TYPES][IM_N] = { /* ORDER LUA_T, ORDER IM */ +{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */ +{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_LINE */ +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_CMARK */ +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* LUA_T_MARK */ +{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CFUNCTION */ +{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_FUNCTION */ +{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */ +{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */ +{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */ +{1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */ +}; + +static int validevent (lua_Type t, int e) +{ /* ORDER LUA_T */ + return (t < LUA_T_NIL) ? 1 : validevents[-t][e]; +} + + +static void init_entry (int tag) { int i; - for (i=0; i<N_FB; i++) - if (fn(&luaI_fallBacks[i].function)) - return luaI_fallBacks[i].kind; + for (i=0; i<IM_N; i++) + ttype(luaI_getim(tag, i)) = LUA_T_NIL; +} + +void luaI_initfallbacks (void) +{ + if (luaI_IMtable == NULL) { + int i; + IMtable_size = NUM_TYPES+10; + luaI_IMtable = newvector(IMtable_size, struct IM); + for (i=LUA_T_NIL; i<=LUA_T_USERDATA; i++) + init_entry(i); + } +} + +int lua_newtag (void) +{ + --last_tag; + if ((-last_tag) >= IMtable_size) { + luaI_initfallbacks(); + IMtable_size = growvector(&luaI_IMtable, IMtable_size, + struct IM, memEM, MAX_INT); + } + init_entry(last_tag); + return last_tag; +} + + +static void checktag (int tag) +{ + if (!(last_tag <= tag && tag <= 0)) + luaL_verror("%d is not a valid tag", tag); +} + +void luaI_realtag (int tag) +{ + if (!(last_tag <= tag && tag < LUA_T_NIL)) + luaL_verror("tag %d is not result of `newtag'", tag); +} + + +void luaI_settag (int tag, TObject *o) +{ + luaI_realtag(tag); + switch (ttype(o)) { + case LUA_T_ARRAY: + o->value.a->htag = tag; + break; + case LUA_T_USERDATA: + o->value.ts->tag = tag; + break; + default: + luaL_verror("cannot change the tag of a %s", luaI_typenames[-ttype(o)]); + } +} + + +int luaI_efectivetag (TObject *o) +{ + lua_Type t = ttype(o); + if (t == LUA_T_USERDATA) { + int tag = o->value.ts->tag; + return (tag >= 0) ? LUA_T_USERDATA : tag; + } + else if (t == LUA_T_ARRAY) + return o->value.a->htag; + else return t; +} + + +void luaI_gettagmethod (void) +{ + int t = (int)luaL_check_number(1); + int e = luaI_checkevent(luaL_check_string(2), luaI_eventname); + checktag(t); + if (validevent(t, e)) + luaI_pushobject(luaI_getim(t,e)); +} + + +void luaI_settagmethod (void) +{ + int t = (int)luaL_check_number(1); + int e = luaI_checkevent(luaL_check_string(2), luaI_eventname); + lua_Object func = lua_getparam(3); + checktag(t); + if (!validevent(t, e)) + luaL_verror("cannot change internal method `%s' for tag %d", + luaI_eventname[e], t); + luaL_arg_check(lua_isnil(func) || lua_isfunction(func), + 3, "function expected"); + luaI_pushobject(luaI_getim(t,e)); + *luaI_getim(t, e) = *luaI_Address(func); +} + + +static void stderrorim (void) +{ + lua_Object s = lua_getparam(1); + if (lua_isstring(s)) + fprintf(stderr, "lua: %s\n", lua_getstring(s)); +} + +static TObject errorim = {LUA_T_CFUNCTION, {stderrorim}}; + + +TObject *luaI_geterrorim (void) +{ + return &errorim; +} + +void luaI_seterrormethod (void) +{ + lua_Object func = lua_getparam(1); + luaL_arg_check(lua_isnil(func) || lua_isfunction(func), + 1, "function expected"); + luaI_pushobject(&errorim); + errorim = *luaI_Address(func); +} + +char *luaI_travfallbacks (int (*fn)(TObject *)) +{ + int e; + if (fn(&errorim)) + return "error"; + for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { /* ORDER IM */ + int t; + for (t=0; t>=last_tag; t--) + if (fn(luaI_getim(t,e))) + return luaI_eventname[e]; + } return NULL; } + + +/* +* =================================================================== +* compatibility with old fallback system +*/ +#if LUA_COMPAT2_5 + +static void errorFB (void) +{ + lua_Object o = lua_getparam(1); + if (lua_isstring(o)) + fprintf (stderr, "lua: %s\n", lua_getstring(o)); + else + fprintf(stderr, "lua: unknown error\n"); +} + + +static void nilFB (void) { } + + +static void typeFB (void) +{ + lua_error("unexpected type"); +} + + +static void fillvalids (IMS e, TObject *func) +{ + int t; + for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++) + if (validevent(t, e)) + *luaI_getim(t, e) = *func; +} + + +void luaI_setfallback (void) +{ + static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL}; + TObject oldfunc; + lua_CFunction replace; + char *name = luaL_check_string(1); + lua_Object func = lua_getparam(2); + luaI_initfallbacks(); + luaL_arg_check(lua_isfunction(func), 2, "function expected"); + switch (luaI_findstring(name, oldnames)) { + case 0: /* old error fallback */ + oldfunc = errorim; + errorim = *luaI_Address(func); + replace = errorFB; + break; + case 1: /* old getglobal fallback */ + oldfunc = *luaI_getim(LUA_T_NIL, IM_GETGLOBAL); + *luaI_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaI_Address(func); + replace = nilFB; + break; + case 2: { /* old arith fallback */ + int i; + oldfunc = *luaI_getim(LUA_T_NUMBER, IM_POW); + for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */ + fillvalids(i, luaI_Address(func)); + replace = typeFB; + break; + } + case 3: { /* old order fallback */ + int i; + oldfunc = *luaI_getim(LUA_T_LINE, IM_LT); + for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */ + fillvalids(i, luaI_Address(func)); + replace = typeFB; + break; + } + default: { + int e; + if ((e = luaI_findstring(name, luaI_eventname)) >= 0) { + oldfunc = *luaI_getim(LUA_T_LINE, e); + fillvalids(e, luaI_Address(func)); + replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; + } + else { + luaL_verror("`%s' is not a valid fallback name", name); + replace = NULL; /* to avoid warnings */ + } + } + } + if (oldfunc.ttype != LUA_T_NIL) + luaI_pushobject(&oldfunc); + else + lua_pushcfunction(replace); +} +#endif diff --git a/src/fallback.h b/src/fallback.h index 71f150f7..7e314c9f 100644 --- a/src/fallback.h +++ b/src/fallback.h @@ -1,5 +1,5 @@ /* -** $Id: fallback.h,v 1.13 1996/04/25 14:10:00 roberto Exp $ +** $Id: fallback.h,v 1.23 1997/04/24 22:59:57 roberto Exp $ */ #ifndef fallback_h @@ -8,30 +8,58 @@ #include "lua.h" #include "opcode.h" -extern struct FB { - char *kind; - Object function; - int nParams; - int nResults; -} luaI_fallBacks[]; - -#define FB_ERROR 0 -#define FB_INDEX 1 -#define FB_GETTABLE 2 -#define FB_ARITH 3 -#define FB_ORDER 4 -#define FB_CONCAT 5 -#define FB_SETTABLE 6 -#define FB_GC 7 -#define FB_FUNCTION 8 -#define FB_GETGLOBAL 9 +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER IM" +*/ +typedef enum { + IM_GETTABLE = 0, + IM_SETTABLE, + IM_INDEX, + IM_GETGLOBAL, + IM_SETGLOBAL, + IM_ADD, + IM_SUB, + IM_MUL, + IM_DIV, + IM_POW, + IM_UNM, + IM_LT, + IM_LE, + IM_GT, + IM_GE, + IM_CONCAT, + IM_GC, + IM_FUNCTION +} IMS; + +#define IM_N 18 + + +extern struct IM { + TObject int_method[IM_N]; +} *luaI_IMtable; + +extern char *luaI_eventname[]; + +#define luaI_getim(tag,event) (&luaI_IMtable[-(tag)].int_method[event]) +#define luaI_getimbyObj(o,e) (luaI_getim(luaI_efectivetag(o),(e))) void luaI_setfallback (void); -int luaI_ref (Object *object, int lock); -Object *luaI_getref (int ref); -void luaI_travlock (int (*fn)(Object *)); +int luaI_ref (TObject *object, int lock); +TObject *luaI_getref (int ref); +void luaI_travlock (int (*fn)(TObject *)); void luaI_invalidaterefs (void); -char *luaI_travfallbacks (int (*fn)(Object *)); +char *luaI_travfallbacks (int (*fn)(TObject *)); + +void luaI_settag (int tag, TObject *o); +void luaI_realtag (int tag); +TObject *luaI_geterrorim (void); +int luaI_efectivetag (TObject *o); +void luaI_settagmethod (void); +void luaI_gettagmethod (void); +void luaI_seterrormethod (void); +void luaI_initfallbacks (void); #endif @@ -2,9 +2,10 @@ #include "luadebug.h" #include "table.h" -#include "mem.h" +#include "luamem.h" #include "func.h" #include "opcode.h" +#include "inout.h" static TFunc *function_root = NULL; @@ -23,7 +24,7 @@ void luaI_initTFunc (TFunc *f) f->size = 0; f->code = NULL; f->lineDefined = 0; - f->fileName = NULL; + f->fileName = lua_parsedfile; f->locvars = NULL; } @@ -49,47 +50,56 @@ void luaI_freefunc (TFunc *f) luaI_free (f); } + +void luaI_funcfree (TFunc *l) +{ + while (l) { + TFunc *next = l->next; + luaI_freefunc(l); + l = next; + } +} + /* ** Garbage collection function. -** This function traverse the function list freeing unindexed functions */ -Long luaI_funccollector (void) +TFunc *luaI_funccollector (long *acum) { TFunc *curr = function_root; TFunc *prev = NULL; - Long counter = 0; - while (curr) - { + TFunc *frees = NULL; + long counter = 0; + while (curr) { TFunc *next = curr->next; - if (!curr->marked) - { + if (!curr->marked) { if (prev == NULL) function_root = next; else prev->next = next; - luaI_freefunc (curr); + curr->next = frees; + frees = curr; ++counter; } - else - { + else { curr->marked = 0; prev = curr; } curr = next; } - return counter; + *acum += counter; + return frees; } void lua_funcinfo (lua_Object func, char **filename, int *linedefined) { - Object *f = luaI_Address(func); - if (f->tag == LUA_T_MARK || f->tag == LUA_T_FUNCTION) + TObject *f = luaI_Address(func); + if (f->ttype == LUA_T_MARK || f->ttype == LUA_T_FUNCTION) { *filename = f->value.tf->fileName; *linedefined = f->value.tf->lineDefined; } - else if (f->tag == LUA_T_CMARK || f->tag == LUA_T_CFUNCTION) + else if (f->ttype == LUA_T_CMARK || f->ttype == LUA_T_CFUNCTION) { *filename = "(C)"; *linedefined = -1; @@ -1,5 +1,5 @@ /* -** $Id: func.h,v 1.8 1996/03/14 15:54:20 roberto Exp $ +** $Id: func.h,v 1.9 1997/05/14 18:38:29 roberto Exp $ */ #ifndef func_h @@ -30,7 +30,8 @@ typedef struct TFunc LocVar *locvars; } TFunc; -Long luaI_funccollector (void); +TFunc *luaI_funccollector (long *cont); +void luaI_funcfree (TFunc *l); void luaI_insertfunction (TFunc *f); void luaI_initTFunc (TFunc *f); @@ -3,14 +3,15 @@ ** hash manager for lua */ -char *rcs_hash="$Id: hash.c,v 2.32 1996/11/18 13:48:44 roberto Exp $"; +char *rcs_hash="$Id: hash.c,v 2.43 1997/05/14 18:38:29 roberto Exp $"; -#include "mem.h" +#include "luamem.h" #include "opcode.h" #include "hash.h" #include "table.h" #include "lua.h" +#include "auxlib.h" #define nhash(t) ((t)->nhash) @@ -24,13 +25,15 @@ char *rcs_hash="$Id: hash.c,v 2.32 1996/11/18 13:48:44 roberto Exp $"; #define REHASH_LIMIT 0.70 /* avoid more than this % full */ +#define TagDefault LUA_T_ARRAY; + static Hash *listhead = NULL; /* hash dimensions values */ static Long dimensions[] = - {3L, 5L, 7L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L, + {5L, 11L, 23L, 47L, 97L, 197L, 397L, 797L, 1597L, 3203L, 6421L, 12853L, 25717L, 51437L, 102811L, 205619L, 411233L, 822433L, 1644817L, 3289613L, 6579211L, 13158023L, MAX_INT}; @@ -46,16 +49,32 @@ int luaI_redimension (int nhash) return 0; /* to avoid warnings */ } -static int hashindex (Hash *t, Object *ref) /* hash function */ + +int lua_equalObj (TObject *t1, TObject *t2) +{ + if (ttype(t1) != ttype(t2)) return 0; + switch (ttype(t1)) + { + case LUA_T_NIL: return 1; + case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); + case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2); + case LUA_T_ARRAY: return avalue(t1) == avalue(t2); + case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf; + case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2); + default: + lua_error("internal error in `lua_equalObj'"); + return 0; /* UNREACHEABLE */ + } +} + + +static long int hashindex (TObject *ref) { long int h; - switch (tag(ref)) { - case LUA_T_NIL: - lua_error ("unexpected type to index table"); - h = 0; /* UNREACHEABLE */ + switch (ttype(ref)) { case LUA_T_NUMBER: h = (long int)nvalue(ref); break; - case LUA_T_STRING: + case LUA_T_STRING: case LUA_T_USERDATA: h = tsvalue(ref)->hash; break; case LUA_T_FUNCTION: h = (IntPoint)ref->value.tf; break; @@ -63,38 +82,29 @@ static int hashindex (Hash *t, Object *ref) /* hash function */ h = (IntPoint)fvalue(ref); break; case LUA_T_ARRAY: h = (IntPoint)avalue(ref); break; - default: /* user data */ - h = (IntPoint)uvalue(ref); break; + default: + lua_error ("unexpected type to index table"); + h = 0; /* UNREACHEABLE */ } if (h < 0) h = -h; - return h%nhash(t); /* make it a valid index */ + return h; } -int lua_equalObj (Object *t1, Object *t2) + +static int present (Hash *t, TObject *key) { - if (tag(t1) != tag(t2)) return 0; - switch (tag(t1)) - { - case LUA_T_NIL: return 1; - case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); - case LUA_T_STRING: return svalue(t1) == svalue(t2); - case LUA_T_ARRAY: return avalue(t1) == avalue(t2); - case LUA_T_FUNCTION: return t1->value.tf == t2->value.tf; - case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2); - default: return uvalue(t1) == uvalue(t2); + long int h = hashindex(key); + int tsize = nhash(t); + int h1 = h%tsize; + TObject *rf = ref(node(t, h1)); + if (ttype(rf) != LUA_T_NIL && !lua_equalObj(key, rf)) { + int h2 = h%(tsize-2) + 1; + do { + h1 = (h1+h2)%tsize; + rf = ref(node(t, h1)); + } while (ttype(rf) != LUA_T_NIL && !lua_equalObj(key, rf)); } -} - -static int present (Hash *t, Object *ref) -{ - int h = hashindex(t, ref); - while (tag(ref(node(t, h))) != LUA_T_NIL) - { - if (lua_equalObj(ref, ref(node(t, h)))) - return h; - h = (h+1) % nhash(t); - } - return h; + return h1; } @@ -106,7 +116,7 @@ static Node *hashnodecreate (int nhash) int i; Node *v = newvector (nhash, Node); for (i=0; i<nhash; i++) - tag(ref(&v[i])) = LUA_T_NIL; + ttype(ref(&v[i])) = LUA_T_NIL; return v; } @@ -121,6 +131,7 @@ static Hash *hashcreate (int nhash) nhash(t) = nhash; nuse(t) = 0; markarray(t) = 0; + t->htag = TagDefault; return t; } @@ -146,7 +157,7 @@ void lua_hashmark (Hash *h) for (i=0; i<nhash(h); i++) { Node *n = node(h,i); - if (tag(ref(n)) != LUA_T_NIL) + if (ttype(ref(n)) != LUA_T_NIL) { lua_markobject(&n->ref); lua_markobject(&n->val); @@ -156,49 +167,50 @@ void lua_hashmark (Hash *h) } -static void call_fallbacks (void) +void luaI_hashcallIM (Hash *l) { - Hash *curr_array; - Object t; - tag(&t) = LUA_T_ARRAY; - for (curr_array = listhead; curr_array; curr_array = curr_array->next) - if (markarray(curr_array) != 1) - { - avalue(&t) = curr_array; - luaI_gcFB(&t); - } - tag(&t) = LUA_T_NIL; - luaI_gcFB(&t); /* end of list */ + TObject t; + ttype(&t) = LUA_T_ARRAY; + for (; l; l=l->next) { + avalue(&t) = l; + luaI_gcIM(&t); + } } - -/* -** Garbage collection to arrays -** Delete all unmarked arrays. -*/ -Long lua_hashcollector (void) + +void luaI_hashfree (Hash *frees) { - Hash *curr_array = listhead, *prev = NULL; - Long counter = 0; - call_fallbacks(); - while (curr_array != NULL) - { - Hash *next = curr_array->next; - if (markarray(curr_array) != 1) - { - if (prev == NULL) listhead = next; - else prev->next = next; - hashdelete(curr_array); - ++counter; + while (frees) { + Hash *next = frees->next; + hashdelete(frees); + frees = next; } - else - { - markarray(curr_array) = 0; - prev = curr_array; +} + + +Hash *luaI_hashcollector (long *acum) +{ + Hash *curr_array = listhead, *prev = NULL, *frees = NULL; + long counter = 0; + while (curr_array != NULL) { + Hash *next = curr_array->next; + if (markarray(curr_array) != 1) { + if (prev == NULL) + listhead = next; + else + prev->next = next; + curr_array->next = frees; + frees = curr_array; + ++counter; + } + else { + markarray(curr_array) = 0; + prev = curr_array; + } + curr_array = next; } - curr_array = next; - } - return counter; + *acum += counter; + return frees; } @@ -220,32 +232,45 @@ Hash *lua_createarray (int nhash) /* -** Re-hash +** Rehash: +** Check if table has deleted slots. It it has, it does not need to +** grow, since rehash will reuse them. */ +static int emptyslots (Hash *t) +{ + int i; + for (i=nhash(t)-1; i>=0; i--) { + Node *n = node(t, i); + if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) == LUA_T_NIL) + return 1; + } + return 0; +} + static void rehash (Hash *t) { - int i; - int nold = nhash(t); - Node *vold = nodevector(t); - nhash(t) = luaI_redimension(nhash(t)); - nodevector(t) = hashnodecreate(nhash(t)); - for (i=0; i<nold; i++) - { - Node *n = vold+i; - if (tag(ref(n)) != LUA_T_NIL && tag(val(n)) != LUA_T_NIL) - *node(t, present(t, ref(n))) = *n; /* copy old node to new hahs */ - } - luaI_free(vold); + int nold = nhash(t); + Node *vold = nodevector(t); + int i; + if (!emptyslots(t)) + nhash(t) = luaI_redimension(nhash(t)); + nodevector(t) = hashnodecreate(nhash(t)); + for (i=0; i<nold; i++) { + Node *n = vold+i; + if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL) + *node(t, present(t, ref(n))) = *n; /* copy old node to new hash */ + } + luaI_free(vold); } /* ** If the hash node is present, return its pointer, otherwise return ** null. */ -Object *lua_hashget (Hash *t, Object *ref) +TObject *lua_hashget (Hash *t, TObject *ref) { int h = present(t, ref); - if (tag(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h)); + if (ttype(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h)); else return NULL; } @@ -254,25 +279,19 @@ Object *lua_hashget (Hash *t, Object *ref) ** If the hash node is present, return its pointer, otherwise create a new ** node for the given reference and also return its pointer. */ -Object *lua_hashdefine (Hash *t, Object *ref) +TObject *lua_hashdefine (Hash *t, TObject *ref) { - int h; - Node *n; - h = present(t, ref); - n = node(t, h); - if (tag(ref(n)) == LUA_T_NIL) - { - nuse(t)++; - if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT) - { - rehash(t); - h = present(t, ref); - n = node(t, h); + Node *n = node(t, present(t, ref)); + if (ttype(ref(n)) == LUA_T_NIL) { + nuse(t)++; + if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT) { + rehash(t); + n = node(t, present(t, ref)); + } + *ref(n) = *ref; + ttype(val(n)) = LUA_T_NIL; } - *ref(n) = *ref; - tag(val(n)) = LUA_T_NIL; - } - return (val(n)); + return (val(n)); } @@ -284,36 +303,30 @@ Object *lua_hashdefine (Hash *t, Object *ref) */ static void hashnext (Hash *t, int i) { - if (i >= nhash(t)) - return; - while (tag(ref(node(t,i))) == LUA_T_NIL || tag(val(node(t,i))) == LUA_T_NIL) - { - if (++i >= nhash(t)) - return; - } - luaI_pushobject(ref(node(t,i))); - luaI_pushobject(val(node(t,i))); + Node *n; + int tsize = nhash(t); + if (i >= tsize) + return; + n = node(t, i); + while (ttype(ref(n)) == LUA_T_NIL || ttype(val(n)) == LUA_T_NIL) { + if (++i >= tsize) + return; + n = node(t, i); + } + luaI_pushobject(ref(node(t,i))); + luaI_pushobject(val(node(t,i))); } void lua_next (void) { - Hash *t; - lua_Object o = lua_getparam(1); - lua_Object r = lua_getparam(2); - if (o == LUA_NOOBJECT || r == LUA_NOOBJECT) - lua_error ("too few arguments to function `next'"); - if (lua_getparam(3) != LUA_NOOBJECT) - lua_error ("too many arguments to function `next'"); - if (!lua_istable(o)) - lua_error ("first argument of function `next' is not a table"); - t = avalue(luaI_Address(o)); - if (lua_isnil(r)) - { - hashnext(t, 0); - } - else - { - int h = present (t, luaI_Address(r)); - hashnext(t, h+1); - } + Hash *t; + lua_Object o = lua_getparam(1); + lua_Object r = lua_getparam(2); + luaL_arg_check(lua_istable(o), 1, "table expected"); + luaL_arg_check(r != LUA_NOOBJECT, 2, "value expected"); + t = avalue(luaI_Address(o)); + if (lua_isnil(r)) + hashnext(t, 0); + else + hashnext(t, present(t, luaI_Address(r))+1); } @@ -1,7 +1,7 @@ /* ** hash.h ** hash manager for lua -** $Id: hash.h,v 2.12 1996/05/06 14:30:27 roberto Exp $ +** $Id: hash.h,v 2.16 1997/05/14 18:38:29 roberto Exp $ */ #ifndef hash_h @@ -10,29 +10,30 @@ #include "types.h" #include "opcode.h" -typedef struct node -{ - Object ref; - Object val; +typedef struct node { + TObject ref; + TObject val; } Node; -typedef struct Hash -{ - struct Hash *next; - Node *node; - int nhash; - int nuse; - char mark; +typedef struct Hash { + struct Hash *next; + Node *node; + int nhash; + int nuse; + int htag; + char mark; } Hash; -int lua_equalObj (Object *t1, Object *t2); +int lua_equalObj (TObject *t1, TObject *t2); int luaI_redimension (int nhash); Hash *lua_createarray (int nhash); void lua_hashmark (Hash *h); -Long lua_hashcollector (void); -Object *lua_hashget (Hash *t, Object *ref); -Object *lua_hashdefine (Hash *t, Object *ref); +Hash *luaI_hashcollector (long *count); +void luaI_hashcallIM (Hash *l); +void luaI_hashfree (Hash *frees); +TObject *lua_hashget (Hash *t, TObject *ref); +TObject *lua_hashdefine (Hash *t, TObject *ref); void lua_next (void); #endif diff --git a/src/inout.c b/src/inout.c index 0aa551c0..5d710610 100644 --- a/src/inout.c +++ b/src/inout.c @@ -5,18 +5,24 @@ ** Also provides some predefined lua functions. */ -char *rcs_inout="$Id: inout.c,v 2.43 1996/09/25 12:57:22 roberto Exp $"; +char *rcs_inout="$Id: inout.c,v 2.69 1997/06/27 22:38:49 roberto Exp $"; #include <stdio.h> #include <string.h> +#include "auxlib.h" +#include "fallback.h" +#include "hash.h" +#include "inout.h" #include "lex.h" +#include "lua.h" +#include "luamem.h" +#include "luamem.h" #include "opcode.h" -#include "inout.h" #include "table.h" #include "tree.h" -#include "lua.h" -#include "mem.h" +#include "undump.h" +#include "zio.h" /* Exported variables */ @@ -24,92 +30,93 @@ Word lua_linenumber; char *lua_parsedfile; -static FILE *fp; -static char *st; +char *luaI_typenames[] = { /* ORDER LUA_T */ + "userdata", "line", "cmark", "mark", "function", + "function", "table", "string", "number", "nil", + NULL +}; -/* -** Function to get the next character from the input file -*/ -static int fileinput (void) -{ - int c = fgetc(fp); - return (c == EOF) ? 0 : c; -} -/* -** Function to get the next character from the input string -*/ -static int stringinput (void) + +void luaI_setparsedfile (char *name) { - return *st++; + lua_parsedfile = luaI_createfixedstring(name)->str; } -/* -** Function to open a file to be input unit. -** Return the file. -*/ -FILE *lua_openfile (char *fn) + +int lua_doFILE (FILE *f, int bin) { - lua_setinput (fileinput); - if (fn == NULL) - { - fp = stdin; - fn = "(stdin)"; - } - else - fp = fopen (fn, "r"); - if (fp == NULL) - return NULL; - lua_parsedfile = luaI_createfixedstring(fn)->str; - return fp; -} + ZIO z; + luaZ_Fopen(&z, f); + if (bin) + return luaI_undump(&z); + else { + lua_setinput(&z); + return lua_domain(); + } +} -/* -** Function to close an opened file -*/ -void lua_closefile (void) + +int lua_dofile (char *filename) { - if (fp != NULL && fp != stdin) - { - fclose (fp); - fp = NULL; - } -} + int status; + int c; + FILE *f = (filename == NULL) ? stdin : fopen(filename, "r"); + if (f == NULL) + return 2; + luaI_setparsedfile(filename?filename:"(stdin)"); + c = fgetc(f); + ungetc(c, f); + if (c == ID_CHUNK) { + f = freopen(filename, "rb", f); /* set binary mode */ + status = lua_doFILE(f, 1); + } + else { + if (c == '#') + while ((c=fgetc(f)) != '\n') /* skip first line */; + status = lua_doFILE(f, 0); + } + if (f != stdin) + fclose(f); + return status; +} + + -/* -** Function to open a string to be input unit -*/ #define SIZE_PREF 20 /* size of string prefix to appear in error messages */ -void lua_openstring (char *s) -{ - char buff[SIZE_PREF+25]; - lua_setinput(stringinput); - st = s; - strcpy(buff, "(dostring) >> "); - strncat(buff, s, SIZE_PREF); - if (strlen(s) > SIZE_PREF) strcat(buff, "..."); - lua_parsedfile = luaI_createfixedstring(buff)->str; -} -/* -** Function to close an opened string -*/ -void lua_closestring (void) + +int lua_dobuffer (char *buff, int size) { + int status; + ZIO z; + luaI_setparsedfile("(buffer)"); + luaZ_mopen(&z, buff, size); + status = luaI_undump(&z); + return status; } -static void check_arg (int cond, char *func) +int lua_dostring (char *str) { - if (!cond) - { - char buff[100]; - sprintf(buff, "incorrect argument to function `%s'", func); - lua_error(buff); - } + int status; + char buff[SIZE_PREF+25]; + char *temp; + ZIO z; + if (str == NULL) return 1; + sprintf(buff, "(dostring) >> %.20s", str); + temp = strchr(buff, '\n'); + if (temp) *temp = 0; /* end string after first line */ + luaI_setparsedfile(buff); + luaZ_sopen(&z, str); + lua_setinput(&z); + status = lua_domain(); + return status; } + + static int passresults (void) { int arg = 0; @@ -118,30 +125,53 @@ static int passresults (void) lua_pushobject(obj); return arg-1; } + + +static void packresults (void) +{ + int arg = 0; + lua_Object obj; + lua_Object table = lua_createtable(); + while ((obj = lua_getresult(++arg)) != LUA_NOOBJECT) { + lua_pushobject(table); + lua_pushnumber(arg); + lua_pushobject(obj); + lua_rawsettable(); + } + lua_pushobject(table); + lua_pushstring("n"); + lua_pushnumber(arg-1); + lua_rawsettable(); + lua_pushobject(table); /* final result */ +} /* ** Internal function: do a string */ -void lua_internaldostring (void) +static void lua_internaldostring (void) { - lua_Object obj = lua_getparam (1); - if (lua_isstring(obj) && lua_dostring(lua_getstring(obj)) == 0) + lua_Object err = lua_getparam(2); + if (err != LUA_NOOBJECT) { /* set new error method */ + luaL_arg_check(lua_isnil(err) || lua_isfunction(err), 2, + "must be a valid error handler"); + lua_pushobject(err); + err = lua_seterrormethod(); + } + if (lua_dostring(luaL_check_string(1)) == 0) if (passresults() == 0) lua_pushuserdata(NULL); /* at least one result to signal no errors */ + if (err != LUA_NOOBJECT) { /* restore old error method */ + lua_pushobject(err); + lua_seterrormethod(); + } } /* ** Internal function: do a file */ -void lua_internaldofile (void) +static void lua_internaldofile (void) { - lua_Object obj = lua_getparam (1); - char *fname = NULL; - if (lua_isstring(obj)) - fname = lua_getstring(obj); - else if (obj != LUA_NOOBJECT) - lua_error("invalid argument to function `dofile'"); - /* else fname = NULL */ + char *fname = luaL_opt_string(1, NULL); if (lua_dofile(fname) == 0) if (passresults() == 0) lua_pushuserdata(NULL); /* at least one result to signal no errors */ @@ -150,36 +180,28 @@ void lua_internaldofile (void) static char *tostring (lua_Object obj) { - char *buff = luaI_buffer(20); - if (lua_isstring(obj)) /* get strings and numbers */ - return lua_getstring(obj); - else switch(lua_type(obj)) - { - case LUA_T_FUNCTION: - sprintf(buff, "function: %p", (luaI_Address(obj))->value.tf); - break; - case LUA_T_CFUNCTION: - sprintf(buff, "cfunction: %p", lua_getcfunction(obj)); - break; - case LUA_T_ARRAY: - sprintf(buff, "table: %p", avalue(luaI_Address(obj))); - break; - case LUA_T_NIL: - sprintf(buff, "nil"); - break; - default: - sprintf(buff, "userdata: %p", lua_getuserdata(obj)); - break; + TObject *o = luaI_Address(obj); + switch (ttype(o)) { + case LUA_T_NUMBER: case LUA_T_STRING: + return lua_getstring(obj); + case LUA_T_ARRAY: case LUA_T_FUNCTION: + case LUA_T_CFUNCTION: case LUA_T_NIL: + return luaI_typenames[-ttype(o)]; + case LUA_T_USERDATA: { + char *buff = luaI_buffer(30); + sprintf(buff, "userdata: %p", o->value.ts->u.v); + return buff; + } + default: return "<unknown object>"; } - return buff; } -void luaI_tostring (void) +static void luaI_tostring (void) { lua_pushstring(tostring(lua_getparam(1))); } -void luaI_print (void) +static void luaI_print (void) { int i = 1; lua_Object obj; @@ -187,45 +209,18 @@ void luaI_print (void) printf("%s\n", tostring(obj)); } -/* -** Internal function: return an object type. -*/ -void luaI_type (void) +static void luaI_type (void) { lua_Object o = lua_getparam(1); - int t; - if (o == LUA_NOOBJECT) - lua_error("no parameter to function 'type'"); - t = lua_type(o); - switch (t) - { - case LUA_T_NIL : - lua_pushliteral("nil"); - break; - case LUA_T_NUMBER : - lua_pushliteral("number"); - break; - case LUA_T_STRING : - lua_pushliteral("string"); - break; - case LUA_T_ARRAY : - lua_pushliteral("table"); - break; - case LUA_T_FUNCTION : - case LUA_T_CFUNCTION : - lua_pushliteral("function"); - break; - default : - lua_pushliteral("userdata"); - break; - } - lua_pushnumber(t); + luaL_arg_check(o != LUA_NOOBJECT, 1, "no argument"); + lua_pushstring(luaI_typenames[-ttype(luaI_Address(o))]); + lua_pushnumber(lua_tag(o)); } - + /* ** Internal function: convert an object to a number */ -void lua_obj2number (void) +static void lua_obj2number (void) { lua_Object o = lua_getparam(1); if (lua_isnumber(o)) @@ -233,68 +228,181 @@ void lua_obj2number (void) } -void luaI_error (void) +static void luaI_error (void) { char *s = lua_getstring(lua_getparam(1)); if (s == NULL) s = "(no message)"; lua_error(s); } -void luaI_assert (void) +static void luaI_assert (void) { lua_Object p = lua_getparam(1); if (p == LUA_NOOBJECT || lua_isnil(p)) lua_error("assertion failed!"); } -void luaI_setglobal (void) +static void luaI_setglobal (void) +{ + lua_Object value = lua_getparam(2); + luaL_arg_check(value != LUA_NOOBJECT, 2, NULL); + lua_pushobject(value); + lua_setglobal(luaL_check_string(1)); + lua_pushobject(value); /* return given value */ +} + +static void luaI_rawsetglobal (void) { - lua_Object name = lua_getparam(1); lua_Object value = lua_getparam(2); - check_arg(lua_isstring(name), "setglobal"); + luaL_arg_check(value != LUA_NOOBJECT, 2, NULL); lua_pushobject(value); - lua_storeglobal(lua_getstring(name)); + lua_rawsetglobal(luaL_check_string(1)); lua_pushobject(value); /* return given value */ } -void luaI_getglobal (void) +static void luaI_getglobal (void) { - lua_Object name = lua_getparam(1); - check_arg(lua_isstring(name), "getglobal"); - lua_pushobject(lua_getglobal(lua_getstring(name))); + lua_pushobject(lua_getglobal(luaL_check_string(1))); } -#define MAXPARAMS 256 -void luaI_call (void) +static void luaI_rawgetglobal (void) +{ + lua_pushobject(lua_rawgetglobal(luaL_check_string(1))); +} + +static void luatag (void) +{ + lua_pushnumber(lua_tag(lua_getparam(1))); +} + + +static int getnarg (lua_Object table) +{ + lua_Object temp; + /* temp = table.n */ + lua_pushobject(table); lua_pushstring("n"); temp = lua_gettable(); + return (lua_isnumber(temp) ? lua_getnumber(temp) : MAX_WORD); +} + +static void luaI_call (void) { lua_Object f = lua_getparam(1); lua_Object arg = lua_getparam(2); - lua_Object temp, params[MAXPARAMS]; + int withtable = (strcmp(luaL_opt_string(3, ""), "pack") == 0); int narg, i; - check_arg(lua_istable(arg), "call"); - check_arg(lua_isfunction(f), "call"); - /* narg = arg.n */ - lua_pushobject(arg); - lua_pushstring("n"); - temp = lua_getsubscript(); - narg = lua_isnumber(temp) ? lua_getnumber(temp) : MAXPARAMS+1; - /* read arg[1...n] */ + luaL_arg_check(lua_isfunction(f), 1, "function expected"); + luaL_arg_check(lua_istable(arg), 2, "table expected"); + narg = getnarg(arg); + /* push arg[1...n] */ for (i=0; i<narg; i++) { - if (i>=MAXPARAMS) - lua_error("argument list too long in function `call'"); - lua_pushobject(arg); - lua_pushnumber(i+1); - params[i] = lua_getsubscript(); - if (narg == MAXPARAMS+1 && lua_isnil(params[i])) { - narg = i; + lua_Object temp; + /* temp = arg[i+1] */ + lua_pushobject(arg); lua_pushnumber(i+1); temp = lua_gettable(); + if (narg == MAX_WORD && lua_isnil(temp)) break; - } + lua_pushobject(temp); } - /* push parameters and do the call */ - for (i=0; i<narg; i++) - lua_pushobject(params[i]); if (lua_callfunction(f)) lua_error(NULL); + else if (withtable) + packresults(); else passresults(); } + +static void luaIl_settag (void) +{ + lua_Object o = lua_getparam(1); + luaL_arg_check(lua_istable(o), 1, "table expected"); + lua_pushobject(o); + lua_settag(luaL_check_number(2)); +} + +static void luaIl_newtag (void) +{ + lua_pushnumber(lua_newtag()); +} + +static void rawgettable (void) +{ + lua_Object t = lua_getparam(1); + lua_Object i = lua_getparam(2); + luaL_arg_check(t != LUA_NOOBJECT, 1, NULL); + luaL_arg_check(i != LUA_NOOBJECT, 2, NULL); + lua_pushobject(t); + lua_pushobject(i); + lua_pushobject(lua_rawgettable()); +} + +static void rawsettable (void) +{ + lua_Object t = lua_getparam(1); + lua_Object i = lua_getparam(2); + lua_Object v = lua_getparam(3); + luaL_arg_check(t != LUA_NOOBJECT && i != LUA_NOOBJECT && v != LUA_NOOBJECT, + 0, NULL); + lua_pushobject(t); + lua_pushobject(i); + lua_pushobject(v); + lua_rawsettable(); +} + + +static void luaI_collectgarbage (void) +{ + lua_pushnumber(lua_collectgarbage(luaL_opt_number(1, 0))); +} + + +/* +** Internal functions +*/ +static struct { + char *name; + lua_CFunction func; +} int_funcs[] = { + {"assert", luaI_assert}, + {"call", luaI_call}, + {"collectgarbage", luaI_collectgarbage}, + {"dofile", lua_internaldofile}, + {"dostring", lua_internaldostring}, + {"error", luaI_error}, + {"getglobal", luaI_getglobal}, + {"newtag", luaIl_newtag}, + {"next", lua_next}, + {"nextvar", luaI_nextvar}, + {"print", luaI_print}, + {"rawgetglobal", luaI_rawgetglobal}, + {"rawgettable", rawgettable}, + {"rawsetglobal", luaI_rawsetglobal}, + {"rawsettable", rawsettable}, + {"seterrormethod", luaI_seterrormethod}, +#if LUA_COMPAT2_5 + {"setfallback", luaI_setfallback}, +#endif + {"setglobal", luaI_setglobal}, + {"settagmethod", luaI_settagmethod}, + {"gettagmethod", luaI_gettagmethod}, + {"settag", luaIl_settag}, + {"tonumber", lua_obj2number}, + {"tostring", luaI_tostring}, + {"tag", luatag}, + {"type", luaI_type} +}; + +#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0])) + + +void luaI_predefine (void) +{ + int i; + Word n; + for (i=0; i<INTFUNCSIZE; i++) { + n = luaI_findsymbolbyname(int_funcs[i].name); + s_ttype(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func; + } + n = luaI_findsymbolbyname("_VERSION"); + s_ttype(n) = LUA_T_STRING; s_tsvalue(n) = lua_createstring(LUA_VERSION); +} + + diff --git a/src/inout.h b/src/inout.h index a26f8e99..b2fb2cd2 100644 --- a/src/inout.h +++ b/src/inout.h @@ -1,5 +1,5 @@ /* -** $Id: inout.h,v 1.16 1996/05/28 21:07:32 roberto Exp $ +** $Id: inout.h,v 1.20 1997/06/19 18:04:34 roberto Exp $ */ @@ -14,21 +14,12 @@ extern Word lua_linenumber; extern Word lua_debugline; extern char *lua_parsedfile; -FILE *lua_openfile (char *fn); -void lua_closefile (void); -void lua_openstring (char *s); -void lua_closestring (void); - -void lua_internaldofile (void); -void lua_internaldostring (void); -void luaI_tostring (void); -void luaI_print (void); -void luaI_type (void); -void lua_obj2number (void); -void luaI_error (void); -void luaI_assert (void); -void luaI_setglobal (void); -void luaI_getglobal (void); -void luaI_call (void); +void luaI_setparsedfile (char *name); + +void luaI_predefine (void); + +int lua_dobuffer (char *buff, int size); +int lua_doFILE (FILE *f, int bin); + #endif @@ -1,10 +1,11 @@ -char *rcs_lex = "$Id: lex.c,v 2.39 1996/11/08 19:08:30 roberto Exp $"; +char *rcs_lex = "$Id: lex.c,v 3.5 1997/06/16 16:50:22 roberto Exp $"; #include <ctype.h> #include <string.h> -#include "mem.h" +#include "auxlib.h" +#include "luamem.h" #include "tree.h" #include "table.h" #include "lex.h" @@ -12,33 +13,58 @@ char *rcs_lex = "$Id: lex.c,v 2.39 1996/11/08 19:08:30 roberto Exp $"; #include "luadebug.h" #include "parser.h" -#define MINBUFF 260 +#define MINBUFF 250 -#define next() (current = input()) +static int current; /* look ahead character */ +static ZIO *lex_z; + + +#define next() (current = zgetc(lex_z)) #define save(x) (yytext[tokensize++] = (x)) #define save_and_next() (save(current), next()) -static int current; /* look ahead character */ -static Input input; /* input function */ +#define MAX_IFS 5 + +/* "ifstate" keeps the state of each nested $if the lexical is dealing with. */ + +static struct { + int elsepart; /* true if its in the $else part */ + int condition; /* true if $if condition is true */ + int skip; /* true if part must be skiped */ +} ifstate[MAX_IFS]; + +static int iflevel; /* level of nested $if's */ -void lua_setinput (Input fn) +void lua_setinput (ZIO *z) { current = '\n'; lua_linenumber = 0; - input = fn; + iflevel = 0; + ifstate[0].skip = 0; + ifstate[0].elsepart = 1; /* to avoid a free $else */ + lex_z = z; } -void luaI_syntaxerror (char *s) + +static void luaI_auxsyntaxerror (char *s) +{ + luaL_verror("%s;\n> at line %d in file %s", + s, lua_linenumber, lua_parsedfile); +} + +static void luaI_auxsynterrbf (char *s, char *token) { - char msg[256]; - char *token = luaI_buffer(1); if (token[0] == 0) token = "<eof>"; - sprintf (msg,"%s;\n> last token read: \"%s\" at line %d in file %s", + luaL_verror("%s;\n> last token read: \"%s\" at line %d in file %s", s, token, lua_linenumber, lua_parsedfile); - lua_error (msg); +} + +void luaI_syntaxerror (char *s) +{ + luaI_auxsynterrbf(s, luaI_buffer(1)); } @@ -78,26 +104,122 @@ void luaI_addReserved (void) } } -static int inclinenumber (int pragma_allowed) + +/* +** Pragma handling +*/ + +#define PRAGMASIZE 20 + +static void skipspace (void) +{ + while (current == ' ' || current == '\t') next(); +} + + +static int checkcond (char *buff) +{ + static char *opts[] = {"nil", "1"}; + int i = luaI_findstring(buff, opts); + if (i >= 0) return i; + else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') + return luaI_globaldefined(buff); + else { + luaI_auxsynterrbf("invalid $if condition", buff); + return 0; /* to avoid warnings */ + } +} + + +static void readname (char *buff) +{ + int i = 0; + skipspace(); + while (isalnum((unsigned char)current) || current == '_') { + if (i >= PRAGMASIZE) { + buff[PRAGMASIZE] = 0; + luaI_auxsynterrbf("pragma too long", buff); + } + buff[i++] = current; + next(); + } + buff[i] = 0; +} + + +static void inclinenumber (void); + + +static void ifskip (void) +{ + while (ifstate[iflevel].skip) { + if (current == '\n') + inclinenumber(); + else if (current == EOZ) + luaI_auxsyntaxerror("input ends inside a $if"); + else next(); + } +} + + +static void inclinenumber (void) { + static char *pragmas [] = + {"debug", "nodebug", "endinput", "end", "ifnot", "if", "else", NULL}; + next(); /* skip '\n' */ ++lua_linenumber; - if (pragma_allowed && current == '$') { /* is a pragma? */ - char *buff = luaI_buffer(MINBUFF+1); - int i = 0; + if (current == '$') { /* is a pragma? */ + char buff[PRAGMASIZE+1]; + int ifnot = 0; + int skip = ifstate[iflevel].skip; next(); /* skip $ */ - while (isalnum(current)) { - if (i >= MINBUFF) luaI_syntaxerror("pragma too long"); - buff[i++] = current; - next(); + readname(buff); + switch (luaI_findstring(buff, pragmas)) { + case 0: /* debug */ + if (!skip) lua_debug = 1; + break; + case 1: /* nodebug */ + if (!skip) lua_debug = 0; + break; + case 2: /* endinput */ + if (!skip) { + current = EOZ; + iflevel = 0; /* to allow $endinput inside a $if */ + } + break; + case 3: /* end */ + if (iflevel-- == 0) + luaI_auxsyntaxerror("unmatched $endif"); + break; + case 4: /* ifnot */ + ifnot = 1; + /* go through */ + case 5: /* if */ + if (iflevel == MAX_IFS-1) + luaI_auxsyntaxerror("too many nested `$ifs'"); + readname(buff); + iflevel++; + ifstate[iflevel].elsepart = 0; + ifstate[iflevel].condition = checkcond(buff) ? !ifnot : ifnot; + ifstate[iflevel].skip = skip || !ifstate[iflevel].condition; + break; + case 6: /* else */ + if (ifstate[iflevel].elsepart) + luaI_auxsyntaxerror("unmatched $else"); + ifstate[iflevel].elsepart = 1; + ifstate[iflevel].skip = + ifstate[iflevel-1].skip || ifstate[iflevel].condition; + break; + default: + luaI_auxsynterrbf("invalid pragma", buff); } - buff[i] = 0; - if (strcmp(buff, "debug") == 0) - lua_debug = 1; - else if (strcmp(buff, "nodebug") == 0) - lua_debug = 0; - else luaI_syntaxerror("invalid pragma"); + skipspace(); + if (current == '\n') /* pragma must end with a '\n' ... */ + inclinenumber(); + else if (current != EOZ) /* or eof */ + luaI_auxsyntaxerror("invalid pragma format"); + ifskip(); } - return lua_linenumber; } static int read_long_string (char *yytext, int buffsize) @@ -110,7 +232,7 @@ static int read_long_string (char *yytext, int buffsize) yytext = luaI_buffer(buffsize *= 2); switch (current) { - case 0: + case EOZ: save(0); return WRONGTOKEN; case '[': @@ -131,8 +253,8 @@ static int read_long_string (char *yytext, int buffsize) } continue; case '\n': - save_and_next(); - inclinenumber(0); + save('\n'); + inclinenumber(); continue; default: save_and_next(); @@ -162,8 +284,8 @@ int luaY_lex (void) switch (current) { case '\n': - next(); - linelasttoken = inclinenumber(1); + inclinenumber(); + linelasttoken = lua_linenumber; continue; case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */ @@ -173,7 +295,7 @@ int luaY_lex (void) case '-': save_and_next(); if (current != '-') return '-'; - do { next(); } while (current != '\n' && current != 0); + do { next(); } while (current != '\n' && current != EOZ); continue; case '[': @@ -216,7 +338,7 @@ int luaY_lex (void) yytext = luaI_buffer(buffsize *= 2); switch (current) { - case 0: + case EOZ: case '\n': save(0); return WRONGTOKEN; @@ -227,7 +349,7 @@ int luaY_lex (void) case 'n': save('\n'); next(); break; case 't': save('\t'); next(); break; case 'r': save('\r'); next(); break; - case '\n': save_and_next(); inclinenumber(0); break; + case '\n': save('\n'); inclinenumber(); break; default : save_and_next(); break; } break; @@ -258,7 +380,9 @@ int luaY_lex (void) case '_': { TaggedString *ts; - do { save_and_next(); } while (isalnum(current) || current == '_'); + do { + save_and_next(); + } while (isalnum((unsigned char)current) || current == '_'); save(0); ts = lua_createstring(yytext); if (ts->marked > 2) @@ -280,7 +404,7 @@ int luaY_lex (void) } else return CONC; /* .. */ } - else if (!isdigit(current)) return '.'; + else if (!isdigit((unsigned char)current)) return '.'; /* current is a digit: goes through to number */ a=0.0; goto fraction; @@ -291,7 +415,7 @@ int luaY_lex (void) do { a=10.0*a+(current-'0'); save_and_next(); - } while (isdigit(current)); + } while (isdigit((unsigned char)current)); if (current == '.') { save_and_next(); if (current == '.') @@ -300,7 +424,7 @@ int luaY_lex (void) } fraction: { double da=0.1; - while (isdigit(current)) + while (isdigit((unsigned char)current)) { a+=(current-'0')*da; da/=10.0; @@ -314,11 +438,12 @@ int luaY_lex (void) save_and_next(); neg=(current=='-'); if (current == '+' || current == '-') save_and_next(); - if (!isdigit(current)) { save(0); return WRONGTOKEN; } + if (!isdigit((unsigned char)current)) { + save(0); return WRONGTOKEN; } do { e=10.0*e+(current-'0'); save_and_next(); - } while (isdigit(current)); + } while (isdigit((unsigned char)current)); for (ea=neg?0.1:10.0; e>0; e>>=1) { if (e & 1) a*=ea; @@ -330,11 +455,15 @@ int luaY_lex (void) return NUMBER; } - default: /* also end of program (0) */ - { + case EOZ: + save(0); + if (iflevel > 0) + luaI_syntaxerror("missing $endif"); + return 0; + + default: save_and_next(); return yytext[0]; - } } } } @@ -1,16 +1,15 @@ /* ** lex.h ** TecCGraf - PUC-Rio -** $Id: lex.h,v 1.3 1996/11/08 12:49:35 roberto Exp $ +** $Id: lex.h,v 1.4 1997/06/16 16:50:22 roberto Exp $ */ #ifndef lex_h #define lex_h +#include "zio.h" -typedef int (*Input) (void); - -void lua_setinput (Input fn); +void lua_setinput (ZIO *z); void luaI_syntaxerror (char *s); int luaY_lex (void); void luaI_addReserved (void); diff --git a/src/lua.stx b/src/lua.stx index 00752604..3a1bf62c 100644 --- a/src/lua.stx +++ b/src/lua.stx @@ -1,13 +1,13 @@ %{ -char *rcs_luastx = "$Id: lua.stx,v 3.41 1996/11/08 12:49:35 roberto Exp $"; +char *rcs_luastx = "$Id: lua.stx,v 3.47 1997/06/19 17:46:12 roberto Exp $"; #include <stdio.h> #include <stdlib.h> #include <string.h> #include "luadebug.h" -#include "mem.h" +#include "luamem.h" #include "lex.h" #include "opcode.h" #include "hash.h" @@ -50,8 +50,6 @@ static TaggedString *localvar[MAXLOCALS]; /* store local variable names */ static int nlocalvar=0; /* number of local variables */ #define MAXFIELDS FIELDS_PER_FLUSH*2 -static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ -static int nfields=0; int lua_debug = 0; @@ -103,22 +101,11 @@ static void code_word_at (Byte *p, int n) memcpy(p, &w, sizeof(Word)); } -static void push_field (Word name) -{ - if (nfields < MAXFIELDS) - fields[nfields++] = name; - else - yyerror ("too many fields in nested constructors"); -} - static void flush_record (int n) { - int i; if (n == 0) return; - code_byte(STORERECORD); + code_byte(STOREMAP); code_byte(n); - for (i=0; i<n; i++) - code_word(fields[--nfields]); } static void flush_list (int m, int n) @@ -161,11 +148,22 @@ static void add_varbuffer (Long var) yyerror ("variable buffer overflow"); } +static void code_string (Word w) +{ + code_byte(PUSHSTRING); + code_word(w); +} + +static void code_constant (TaggedString *s) +{ + code_string(luaI_findconstant(s)); +} + static void code_number (float f) { - Word i = (Word)f; - if (f == (float)i) /* f has an (short) integer value */ - { + Word i; + if (f >= 0 && f <= (float)MAX_WORD && (float)(i=(Word)f) == f) { + /* f has an (short) integer value */ if (i <= 2) code_byte(PUSH0 + i); else if (i <= 255) { @@ -459,7 +457,7 @@ void lua_parse (TFunc *tf) %% /* beginning of rules section */ -chunk : chunklist ret +chunk : chunklist ret ; chunklist : /* empty */ | chunklist stat sc @@ -477,8 +475,7 @@ function : FUNCTION funcname body funcname : var { $$ =$1; init_func(); } | varexp ':' NAME { - code_byte(PUSHSTRING); - code_word(luaI_findconstant($3)); + code_constant($3); $$ = 0; /* indexed variable */ init_func(); add_localvar(luaI_createfixedstring("self")); @@ -492,7 +489,6 @@ body : '(' parlist ')' block END luaI_initTFunc($$); $$->size = pc; $$->code = newvector(pc, Byte); - $$->fileName = lua_parsedfile; $$->lineDefined = $2; memcpy($$->code, basepc, pc*sizeof(Byte)); if (lua_debug) @@ -540,7 +536,7 @@ stat : IF expr1 THEN PrepJump block PrepJump elsepart END lua_codeadjust (0); } } - | functioncall + | functioncall {;} | LOCAL localdeclist decinit { nlocalvar += $2; adjust_mult_assign($2, $3, 0); @@ -605,9 +601,8 @@ expr : '(' expr ')' { $$ = $2; } | NUMBER { code_number($1); $$ = 0; } | STRING { - code_byte(PUSHSTRING); - code_word($1); - $$ = 0; + code_string($1); + $$ = 0; } | NIL {code_byte(PUSHNIL); $$ = 0; } | functioncall { $$ = $1; } @@ -723,12 +718,13 @@ ffieldlist1 : ffield {$$=1;} } ; -ffield : NAME '=' expr1 - { - push_field(luaI_findconstant($1)); - } +ffield : ffieldkey '=' expr1 ; +ffieldkey : '[' expr1 ']' + | NAME { code_constant($1); } + ; + lfieldlist : /* empty */ { $$ = 0; } | lfieldlist1 lastcomma { $$ = $1; } ; @@ -762,9 +758,8 @@ var : singlevar { $$ = $1; } } | varexp '.' NAME { - code_byte(PUSHSTRING); - code_word(luaI_findconstant($3)); - $$ = 0; /* indexed variable */ + code_constant($3); + $$ = 0; /* indexed variable */ } ; diff --git a/src/luac/dump.c b/src/luac/dump.c index 656cc293..73839f38 100644 --- a/src/luac/dump.c +++ b/src/luac/dump.c @@ -3,15 +3,13 @@ ** thread and save bytecodes to file */ -char* rcs_dump="$Id: dump.c,v 1.17 1996/11/18 11:18:29 lhf Exp $"; +char* rcs_dump="$Id: dump.c,v 1.20 1997/06/19 14:56:04 lhf Exp $"; #include <stdio.h> #include <stdlib.h> #include <string.h> #include "luac.h" -static TFunc* lastF=NULL; /* list of functions seen in code */ - static int SawVar(int i, int at) { int old=VarLoc(i); @@ -34,7 +32,7 @@ static void ThreadCode(Byte* code, Byte* end) for (i=0; i<lua_nconstant; i++) StrLoc(i)=0; for (p=code; p!=end;) { - OpCode op=(OpCode)*p; + int op=*p; int at=p-code+1; switch (op) { @@ -89,6 +87,8 @@ static void ThreadCode(Byte* code, Byte* end) case STORELIST0: case ADJUST: case RETCODE: + case VARARGS: + case STOREMAP: p+=2; break; case PUSHWORD: @@ -107,8 +107,11 @@ static void ThreadCode(Byte* code, Byte* end) case PUSHFLOAT: p+=5; /* assumes sizeof(float)==4 */ break; - case PUSHSELF: + case PUSHFUNCTION: + p+=sizeof(TFunc*)+1; + break; case PUSHSTRING: + case PUSHSELF: { Word w; p++; @@ -117,16 +120,6 @@ static void ThreadCode(Byte* code, Byte* end) memcpy(p-2,&w,sizeof(w)); break; } - case PUSHFUNCTION: - { - TFunc* tf; - p++; - get_code(tf,p); - tf->marked=at; - tf->next=NULL; /* TODO: remove? */ - lastF=lastF->next=tf; - break; - } case PUSHGLOBAL: case STOREGLOBAL: { @@ -151,8 +144,8 @@ static void ThreadCode(Byte* code, Byte* end) } break; } - default: - fprintf(stderr,"luac: cannot happen: opcode=%d",*p); + default: /* cannot happen */ + fprintf(stderr,"luac: bad opcode %d at %d\n",*p,(int)(p-code)); exit(1); break; } @@ -186,7 +179,7 @@ static void DumpString(char* s, FILE* D) int n=strlen(s)+1; if ((Word)n != n) { - fprintf(stderr,"luac: string too long: \"%.32s...\"\n",s); + fprintf(stderr,"luac: string too long (%d bytes): \"%.32s...\"\n",n,s); exit(1); } DumpWord(n,D); @@ -220,7 +213,6 @@ static void DumpStrings(FILE* D) void DumpFunction(TFunc* tf, FILE* D) { - lastF=tf; ThreadCode(tf->code,tf->code+tf->size); fputc(ID_FUN,D); DumpSize(tf->size,D); diff --git a/src/luac/luac.c b/src/luac/luac.c index 7546c1bb..713da1fb 100644 --- a/src/luac/luac.c +++ b/src/luac/luac.c @@ -1,25 +1,39 @@ /* ** luac.c -** lua compiler (saves bytecodes to files) +** lua compiler (saves bytecodes to files; also list binary files) */ -char* rcs_luac="$Id: luac.c,v 1.18 1996/11/16 20:14:23 lhf Exp $"; +char* rcs_luac="$Id: luac.c,v 1.23 1997/06/20 20:34:04 lhf Exp $"; #include <stdio.h> #include <stdlib.h> #include <string.h> #include "luac.h" +#include "lex.h" +#include "zio.h" static void compile(char* filename); +static void undump(char* filename); static int listing=0; /* list bytecodes? */ static int dumping=1; /* dump bytecodes? */ +static int undumping=0; /* undump bytecodes? */ static FILE* D; /* output file */ static void usage(void) { - fprintf(stderr,"usage: luac [-dlpv] [-o output] file ...\n"); - exit(0); + fprintf(stderr, + "usage: luac [-c | -u] [-d] [-l] [-p] [-q] [-v] [-o output] file ...\n" + " -c\tcompile (default)\n" + " -u\tundump\n" + " -d\tgenerate debugging information\n" + " -l\tlist (default for -u)\n" + " -o\toutput file for -c (default \"luac.out\")\n" + " -p\tparse only\n" + " -q\tquiet (default for -c)\n" + " -v\tshow version information\n" + ); + exit(1); } #define IS(s) (strcmp(argv[i],s)==0) @@ -34,6 +48,11 @@ int main(int argc, char* argv[]) break; else if (IS("-")) /* use stdin */ break; + else if (IS("-c")) /* compile (and dump) */ + { + dumping=1; + undumping=0; + } else if (IS("-d")) /* debug */ lua_debug=1; else if (IS("-l")) /* list */ @@ -42,6 +61,14 @@ int main(int argc, char* argv[]) d=argv[++i]; else if (IS("-p")) /* parse only (for timing purposes) */ dumping=0; + else if (IS("-q")) /* quiet */ + listing=0; + else if (IS("-u")) /* undump */ + { + dumping=0; + undumping=1; + listing=1; + } else if (IS("-v")) /* show version */ printf("%s %s\n(written by %s)\n\n",LUA_VERSION,LUA_COPYRIGHT,LUA_AUTHORS); else /* unknown option */ @@ -50,56 +77,114 @@ int main(int argc, char* argv[]) --i; /* fake new argv[0] */ argc-=i; argv+=i; - if (argc<2) usage(); - for (i=1; i<argc; i++) - if (IS(d)) + if (dumping) + { + if (argc<2) usage(); + for (i=1; i<argc; i++) /* play safe with output file */ + if (IS(d)) + { + fprintf(stderr,"luac: will not overwrite input file \"%s\"\n",d); + exit(1); + } + D=fopen(d,"wb"); /* must open in binary mode */ + if (D==NULL) { - fprintf(stderr,"luac: will not overwrite input file \"%s\"\n",d); + fprintf(stderr,"luac: cannot open "); + perror(d); exit(1); } - D=(dumping) ? fopen(d,"wb") : stdout; /* must open in binary mode */ - if (D==NULL) + for (i=1; i<argc; i++) compile(IS("-")? NULL : argv[i]); + fclose(D); + } + if (undumping) { - fprintf(stderr,"luac: cannot open "); - perror(d); - exit(1); + if (argc<2) + undump("luac.out"); + else + for (i=1; i<argc; i++) undump(IS("-")? NULL : argv[i]); } - for (i=1; i<argc; i++) compile(IS("-")? NULL : argv[i]); - fclose(D); return 0; } -static void do_dump(TFunc* tf) /* only for tf==main */ +static void do_dump(TFunc* Main) { - if (dumping) DumpHeader(D); - while (tf!=NULL) + TFunc* tf; + LinkFunctions(Main); + if (listing) + { + for (tf=Main; tf!=NULL; tf=tf->next) PrintFunction(tf,Main); + } + if (dumping) { - TFunc* nf; - if (listing) PrintFunction(tf); - if (dumping) DumpFunction(tf,D); - nf=tf->next; /* list only built after first main */ + DumpHeader(D); + for (tf=Main; tf!=NULL; tf=tf->next) DumpFunction(tf,D); + } + for (tf=Main; tf!=NULL; ) + { + TFunc* nf=tf->next; luaI_freefunc(tf); tf=nf; } } -static void do_compile(void) +static void do_compile(ZIO* z) { TFunc* tf=new(TFunc); + lua_setinput(z); luaI_initTFunc(tf); - tf->fileName = lua_parsedfile; + tf->fileName=lua_parsedfile; lua_parse(tf); do_dump(tf); } static void compile(char* filename) { - if (lua_openfile(filename)==NULL) + FILE* f= (filename==NULL) ? stdin : fopen(filename, "r"); + if (f==NULL) + { + fprintf(stderr,"luac: cannot open "); + perror(filename); + exit(1); + } + else + { + ZIO z; + zFopen(&z,f); + luaI_setparsedfile(filename?filename:"(stdin)"); + do_compile(&z); + fclose(f); + } +} + +static void do_undump(ZIO* z) +{ + TFunc* Main; + while ((Main=luaI_undump1(z))) + { + if (listing) + { + TFunc* tf; + for (tf=Main; tf!=NULL; tf=tf->next) + PrintFunction(tf,Main); + } + luaI_freefunc(Main); /* TODO: free others */ + } +} + +static void undump(char* filename) +{ + FILE* f= (filename==NULL) ? stdin : fopen(filename, "rb"); + if (f==NULL) { fprintf(stderr,"luac: cannot open "); perror(filename); exit(1); } - do_compile(); - lua_closefile(); + else + { + ZIO z; + zFopen(&z,f); + do_undump(&z); + fclose(f); + } } diff --git a/src/luac/luac.h b/src/luac/luac.h index ceb311b8..815824ca 100644 --- a/src/luac/luac.h +++ b/src/luac/luac.h @@ -1,24 +1,25 @@ /* ** luac.h ** definitions for luac compiler -** $Id: luac.h,v 1.5 1996/03/08 21:41:47 lhf Exp $ +** $Id: luac.h,v 1.8 1997/06/19 17:32:08 lhf Exp $ */ #include "inout.h" -#include "mem.h" +#include "luamem.h" #include "opcode.h" #include "table.h" #include "undump.h" #define VarStr(i) (lua_table[i].varname->str) -#define VarLoc(i) (lua_table[i].varname->varindex) +#define VarLoc(i) (lua_table[i].varname->u.s.varindex) #define StrStr(i) (lua_constant[i]->str) -#define StrLoc(i) (lua_constant[i]->constindex) +#define StrLoc(i) (lua_constant[i]->u.s.constindex) extern Word lua_ntable; extern Word lua_nconstant; extern int lua_debug; +void LinkFunctions(TFunc* tf); +void PrintFunction(TFunc* tf, TFunc* Main); void DumpHeader(FILE* D); void DumpFunction(TFunc* tf, FILE* D); -void PrintFunction(TFunc* tf); diff --git a/src/luac/print.c b/src/luac/print.c index 0e1d2569..fb7bf8a7 100644 --- a/src/luac/print.c +++ b/src/luac/print.c @@ -3,7 +3,7 @@ ** print bytecodes */ -char* rcs_print="$Id: print.c,v 1.11 1996/11/18 11:24:16 lhf Exp $"; +char* rcs_print="$Id: print.c,v 1.17 1997/06/25 17:07:28 lhf Exp $"; #include <stdio.h> #include <stdlib.h> @@ -11,20 +11,134 @@ char* rcs_print="$Id: print.c,v 1.11 1996/11/18 11:24:16 lhf Exp $"; #include "luac.h" #include "print.h" -static LocVar* V=NULL; - -static char* LocStr(int i) +void LinkFunctions(TFunc* m) { - if (V==NULL) return ""; else return V[i].varname->str; + static TFunc* lastF; /* list of functions seen in code */ + Byte* code=m->code; + Byte* end=code+m->size; + Byte* p; + if (IsMain(m)) lastF=m; + for (p=code; p!=end;) + { + int op=*p; + int at=p-code+1; + switch (op) + { + case PUSHNIL: + case PUSH0: + case PUSH1: + case PUSH2: + case PUSHLOCAL0: + case PUSHLOCAL1: + case PUSHLOCAL2: + case PUSHLOCAL3: + case PUSHLOCAL4: + case PUSHLOCAL5: + case PUSHLOCAL6: + case PUSHLOCAL7: + case PUSHLOCAL8: + case PUSHLOCAL9: + case PUSHINDEXED: + case STORELOCAL0: + case STORELOCAL1: + case STORELOCAL2: + case STORELOCAL3: + case STORELOCAL4: + case STORELOCAL5: + case STORELOCAL6: + case STORELOCAL7: + case STORELOCAL8: + case STORELOCAL9: + case STOREINDEXED0: + case ADJUST0: + case EQOP: + case LTOP: + case LEOP: + case GTOP: + case GEOP: + case ADDOP: + case SUBOP: + case MULTOP: + case DIVOP: + case POWOP: + case CONCOP: + case MINUSOP: + case NOTOP: + case POP: + case RETCODE0: + p++; + break; + case PUSHBYTE: + case PUSHLOCAL: + case STORELOCAL: + case STOREINDEXED: + case STORELIST0: + case ADJUST: + case RETCODE: + case VARARGS: + case STOREMAP: + p+=2; + break; + case PUSHWORD: + case PUSHSTRING: + case PUSHGLOBAL: + case PUSHSELF: + case STOREGLOBAL: + case CREATEARRAY: + case ONTJMP: + case ONFJMP: + case JMP: + case UPJMP: + case IFFJMP: + case IFFUPJMP: + case CALLFUNC: + case SETLINE: + case STORELIST: + p+=3; + break; + case PUSHFLOAT: + p+=5; /* assumes sizeof(float)==4 */ + break; + case PUSHFUNCTION: + { + TFunc* tf; + p++; + get_code(tf,p); + tf->marked=at; + tf->next=NULL; /* TODO: remove? */ + lastF=lastF->next=tf; + break; + } + case STORERECORD: + { + int n=*++p; + p+=2*n+1; + break; + } + default: /* cannot happen */ + fprintf(stderr,"luac: bad opcode %d at %d\n",*p,(int)(p-code)); + exit(1); + break; + } + } } -static void PrintCode(Byte* code, Byte* end) +#define LocStr(i) luaI_getlocalname(tf,i+1,line) + +static void PrintCode(TFunc* tf) { + Byte* code=tf->code; + Byte* end=code+tf->size; Byte* p; + int line=0; for (p=code; p!=end;) { - OpCode op=(OpCode)*p; - if (op>SETLINE) op=SETLINE+1; + int op=*p; + if (op>=NOPCODES) + { + fprintf(stderr,"luac: bad opcode %d at %d\n",op,(int)(p-code)); + exit(1); + } printf("%6d\t%s",(int)(p-code),OpCodeName[op]); switch (op) { @@ -64,7 +178,7 @@ static void PrintCode(Byte* code, Byte* end) case PUSHLOCAL9: { int i=op-PUSHLOCAL0; - printf("\t%d\t; %s",i,LocStr(i)); + if (tf->locvars) printf("\t\t; %s",LocStr(i)); p++; break; } @@ -80,7 +194,7 @@ static void PrintCode(Byte* code, Byte* end) case STORELOCAL9: { int i=op-STORELOCAL0; - printf("\t%d\t; %s",i,LocStr(i)); + if (tf->locvars) printf("\t\t; %s",LocStr(i)); p++; break; } @@ -88,7 +202,7 @@ static void PrintCode(Byte* code, Byte* end) case STORELOCAL: { int i=*(p+1); - printf("\t%d\t; %s",i,LocStr(i)); + if (tf->locvars) printf("\t%d\t; %s",i,LocStr(i)); p+=2; break; } @@ -97,23 +211,40 @@ static void PrintCode(Byte* code, Byte* end) case STORELIST0: case ADJUST: case RETCODE: + case VARARGS: + case STOREMAP: printf("\t%d",*(p+1)); p+=2; break; case PUSHWORD: case CREATEARRAY: + case SETLINE: + { + Word w; + p++; + get_word(w,p); + printf("\t%d",w); + if (op==SETLINE) line=w; + break; + } case ONTJMP: case ONFJMP: case JMP: - case UPJMP: case IFFJMP: + { /* suggested by Norman Ramsey <nr@cs.virginia.edu> */ + Word w; + p++; + get_word(w,p); + printf("\t%d\t\t; to %d",w,(int)(p-code)+w); + break; + } + case UPJMP: case IFFUPJMP: - case SETLINE: - { + { /* suggested by Norman Ramsey <nr@cs.virginia.edu> */ Word w; p++; get_word(w,p); - printf("\t%d",w); + printf("\t%d\t\t; to %d",w,(int)(p-code)-w); break; } case PUSHFLOAT: @@ -170,7 +301,8 @@ static void PrintCode(Byte* code, Byte* end) break; } default: - printf("\tcannot happen: opcode=%d",*p); + printf("\tcannot happen: opcode=%d\n",*p); + fprintf(stderr,"luac: bad opcode %d at %d\n",op,(int)(p-code)); exit(1); break; } @@ -178,13 +310,74 @@ static void PrintCode(Byte* code, Byte* end) } } -void PrintFunction(TFunc* tf) +#undef LocStr + +static void PrintLocals(LocVar* v, int n) { + int i=0; + if (v==NULL || v->varname==NULL) return; + if (n>0) + { + printf("parameters:"); + for (i=0; i<n; v++,i++) printf(" %s[%d@%d]",v->varname->str,i,v->line); + printf("\n"); + } + if (v->varname!=NULL) + { + printf("locals:"); + for (; v->line>=0; v++) + { + if (v->varname==NULL) +#if 0 + printf(" %s[%d@%d]","*",--i,v->line); +#else + --i; +#endif + else + printf(" %s[%d@%d]",v->varname->str,i++,v->line); + } + printf("\n"); + } +} + +void PrintFunction(TFunc* tf, TFunc* Main) +{ + int n=0; if (IsMain(tf)) printf("\nmain of \"%s\" (%d bytes at %p)\n",tf->fileName,tf->size,tf); else - printf("\nfunction \"%s\":%d (%d bytes at %p); used at main+%d\n", + { + Byte* p; + p=tf->code; /* get number of parameters */ + while (*p==SETLINE) p+=3; + if (*p==ADJUST) n=p[1]; + p=Main->code+tf->marked+sizeof(TFunc*); + printf("\nfunction "); + switch (*p) /* try to get name */ + { + case STOREGLOBAL: + { + Word w; + p++; get_word(w,p); printf("%s defined at ",VarStr(w)); + break; + } + case STOREINDEXED0: /* try method definition */ + { + if (p[-11]==PUSHGLOBAL && p[-8]==PUSHSTRING) + { + Word w; + Byte* op=p; + int c=(tf->locvars && n>0 && strcmp(tf->locvars->varname->str,"self")==0) + ? ':' : '.'; + p=op-11; p++; get_word(w,p); printf("%s%c",VarStr(w),c); + p=op-8; p++; get_word(w,p); printf("%s defined at ",StrStr(w)); + } + break; + } + } + printf("\"%s\":%d (%d bytes at %p); used at main+%d\n", tf->fileName,tf->lineDefined,tf->size,tf,tf->marked); - V=tf->locvars; - PrintCode(tf->code,tf->code+tf->size); + } + PrintLocals(tf->locvars,n); + PrintCode(tf); } diff --git a/src/luac/print.h b/src/luac/print.h index 31e2bb89..00e344ca 100644 --- a/src/luac/print.h +++ b/src/luac/print.h @@ -1,10 +1,10 @@ /* ** print.h ** opcode names -** $Id: print.h,v 1.1 1996/02/23 19:04:13 lhf Exp $ +** $Id: print.h,v 1.3 1997/04/14 14:42:50 lhf Exp $ */ -static char* OpCodeName[]={ /* attention: same order as enum in opcode.h */ +static char* OpCodeName[]={ /* ATTENTION: same order as enum in opcode.h */ "PUSHNIL", "PUSH0", "PUSH1", @@ -72,5 +72,8 @@ static char* OpCodeName[]={ /* attention: same order as enum in opcode.h */ "RETCODE0", "RETCODE", "SETLINE", - "" + "VARARGS", + "STOREMAP" }; + +#define NOPCODES (sizeof(OpCodeName)/sizeof(OpCodeName[0])) diff --git a/src/luamem.c b/src/luamem.c new file mode 100644 index 00000000..e4cdd6d9 --- /dev/null +++ b/src/luamem.c @@ -0,0 +1,159 @@ +/* +** mem.c +** TecCGraf - PUC-Rio +*/ + +char *rcs_luamem = "$Id: luamem.c,v 1.16 1997/04/01 21:23:20 roberto Exp $"; + +#include <stdlib.h> + +#include "luamem.h" +#include "lua.h" + + +#define DEBUG 0 + +#if !DEBUG + +void luaI_free (void *block) +{ + if (block) + { + *((char *)block) = -1; /* to catch errors */ + free(block); + } +} + + +void *luaI_realloc (void *oldblock, unsigned long size) +{ + void *block; + size_t s = (size_t)size; + if (s != size) + lua_error("Allocation Error: Block too big"); + block = oldblock ? realloc(oldblock, s) : malloc(s); + if (block == NULL) + lua_error(memEM); + return block; +} + + +int luaI_growvector (void **block, unsigned long nelems, int size, + char *errormsg, unsigned long limit) +{ + if (nelems >= limit) + lua_error(errormsg); + nelems = (nelems == 0) ? 20 : nelems*2; + if (nelems > limit) + nelems = limit; + *block = luaI_realloc(*block, nelems*size); + return (int)nelems; +} + + +void* luaI_buffer (unsigned long size) +{ + static unsigned long buffsize = 0; + static char* buffer = NULL; + if (size > buffsize) + buffer = luaI_realloc(buffer, buffsize=size); + return buffer; +} + +#else +/* DEBUG */ + +#include <stdio.h> + +# define assert(ex) {if (!(ex)){(void)fprintf(stderr, \ + "Assertion failed: file \"%s\", line %d\n", __FILE__, __LINE__);exit(1);}} + +#define MARK 55 + +static unsigned long numblocks = 0; +static unsigned long totalmem = 0; + + +static void message (void) +{ +#define inrange(x,y) ((x) < (((y)*3)/2) && (x) > (((y)*2)/3)) + static int count = 0; + static unsigned long lastnumblocks = 0; + static unsigned long lasttotalmem = 0; + if (!inrange(numblocks, lastnumblocks) || !inrange(totalmem, lasttotalmem) + || count++ >= 5000) + { + fprintf(stderr,"blocks = %lu mem = %luK\n", numblocks, totalmem/1000); + count = 0; + lastnumblocks = numblocks; + lasttotalmem = totalmem; + } +} + + +void luaI_free (void *block) +{ + if (block) + { + unsigned long *b = (unsigned long *)block - 1; + unsigned long size = *b; + assert(*(((char *)b)+size+sizeof(unsigned long)) == MARK); + numblocks--; + totalmem -= size; + free(b); + message(); + } +} + + +void *luaI_realloc (void *oldblock, unsigned long size) +{ + unsigned long *block; + unsigned long realsize = sizeof(unsigned long)+size+sizeof(char); + if (realsize != (size_t)realsize) + lua_error("Allocation Error: Block too big"); + if (oldblock) + { + unsigned long *b = (unsigned long *)oldblock - 1; + unsigned long oldsize = *b; + assert(*(((char *)b)+oldsize+sizeof(unsigned long)) == MARK); + totalmem -= oldsize; + numblocks--; + block = (unsigned long *)realloc(b, realsize); + } + else + block = (unsigned long *)malloc(realsize); + if (block == NULL) + lua_error("not enough memory"); + totalmem += size; + numblocks++; + *block = size; + *(((char *)block)+size+sizeof(unsigned long)) = MARK; + message(); + return block+1; +} + + +int luaI_growvector (void **block, unsigned long nelems, int size, + char *errormsg, unsigned long limit) +{ + if (nelems >= limit) + lua_error(errormsg); + nelems = (nelems == 0) ? 20 : nelems*2; + if (nelems > limit) + nelems = limit; + *block = luaI_realloc(*block, nelems*size); + return (int)nelems; +} + + +void* luaI_buffer (unsigned long size) +{ + static unsigned long buffsize = 0; + static char* buffer = NULL; + if (size > buffsize) + buffer = luaI_realloc(buffer, buffsize=size); + return buffer; +} + +#endif diff --git a/src/mem.h b/src/luamem.h index 86f024fc..86b7c8f0 100644 --- a/src/mem.h +++ b/src/luamem.h @@ -1,11 +1,11 @@ /* ** mem.c ** memory manager for lua -** $Id: mem.h,v 1.8 1996/05/24 14:31:10 roberto Exp $ +** $Id: luamem.h,v 1.9 1997/03/31 14:10:11 roberto Exp $ */ -#ifndef mem_h -#define mem_h +#ifndef luamem_h +#define luamem_h #ifndef NULL #define NULL 0 diff --git a/src/mem.c b/src/mem.c deleted file mode 100644 index 4e3bcc52..00000000 --- a/src/mem.c +++ /dev/null @@ -1,58 +0,0 @@ -/* -** mem.c -** TecCGraf - PUC-Rio -*/ - -char *rcs_mem = "$Id: mem.c,v 1.13 1996/05/24 14:31:10 roberto Exp $"; - -#include <stdlib.h> - -#include "mem.h" -#include "lua.h" - - -void luaI_free (void *block) -{ - if (block) - { - *((int *)block) = -1; /* to catch errors */ - free(block); - } -} - - -void *luaI_realloc (void *oldblock, unsigned long size) -{ - void *block; - size_t s = (size_t)size; - if (s != size) - lua_error("Allocation Error: Block too big"); - block = oldblock ? realloc(oldblock, s) : malloc(s); - if (block == NULL) - lua_error(memEM); - return block; -} - - -int luaI_growvector (void **block, unsigned long nelems, int size, - char *errormsg, unsigned long limit) -{ - if (nelems >= limit) - lua_error(errormsg); - nelems = (nelems == 0) ? 20 : nelems*2; - if (nelems > limit) - nelems = limit; - *block = luaI_realloc(*block, nelems*size); - return (int)nelems; -} - - -void* luaI_buffer (unsigned long size) -{ - static unsigned long buffsize = 0; - static char* buffer = NULL; - if (size > buffsize) - buffer = luaI_realloc(buffer, buffsize=size); - return buffer; -} - diff --git a/src/opcode.c b/src/opcode.c index c3bcf54c..ea18f9ea 100644 --- a/src/opcode.c +++ b/src/opcode.c @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_opcode="$Id: opcode.c,v 3.77 1996/11/18 13:48:44 roberto Exp $"; +char *rcs_opcode="$Id: opcode.c,v 4.15 1997/06/26 21:40:57 roberto Exp $"; #include <setjmp.h> #include <stdio.h> @@ -11,17 +11,18 @@ char *rcs_opcode="$Id: opcode.c,v 3.77 1996/11/18 13:48:44 roberto Exp $"; #include <stdlib.h> #include "luadebug.h" -#include "mem.h" +#include "luamem.h" #include "opcode.h" #include "hash.h" #include "inout.h" #include "table.h" #include "lua.h" #include "fallback.h" -#include "undump.h" +#include "auxlib.h" +#include "lex.h" -#define tonumber(o) ((tag(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0)) -#define tostring(o) ((tag(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) +#define tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (lua_tonumber(o) != 0)) +#define tostring(o) ((ttype(o) != LUA_T_STRING) && (lua_tostring(o) != 0)) #define STACK_SIZE 128 @@ -32,14 +33,14 @@ char *rcs_opcode="$Id: opcode.c,v 3.77 1996/11/18 13:48:44 roberto Exp $"; typedef int StkId; /* index to stack elements */ -static Object initial_stack; +static TObject initial_stack; -static Object *stackLimit = &initial_stack+1; -static Object *stack = &initial_stack; -static Object *top = &initial_stack; +static TObject *stackLimit = &initial_stack+1; +static TObject *stack = &initial_stack; +static TObject *top = &initial_stack; -/* macros to convert from lua_Object to (Object *) and back */ +/* macros to convert from lua_Object to (TObject *) and back */ #define Address(lo) ((lo)+stack-1) #define Ref(st) ((st)-stack+1) @@ -51,13 +52,13 @@ static Object *top = &initial_stack; #define incr_top if (++top >= stackLimit) growstack() struct C_Lua_Stack { - StkId base; /* when Lua calls C or C calls Lua, points to */ - /* the first slot after the last parameter. */ - int num; /* when Lua calls C, has the number of parameters; */ - /* when C calls Lua, has the number of results. */ + StkId base; /* when Lua calls C or C calls Lua, points to */ + /* the first slot after the last parameter. */ + StkId lua2C; /* points to first element of "array" lua2C */ + int num; /* size of "array" lua2C */ }; -static struct C_Lua_Stack CLS_current = {0, 0}; +static struct C_Lua_Stack CLS_current = {0, 0, 0}; static jmp_buf *errorJmp = NULL; /* current error recover point */ @@ -72,7 +73,7 @@ static void do_call (StkId base, int nResults); -Object *luaI_Address (lua_Object o) +TObject *luaI_Address (lua_Object o) { return Address(o); } @@ -84,7 +85,7 @@ Object *luaI_Address (lua_Object o) static void lua_initstack (void) { Long maxstack = STACK_SIZE; - stack = newvector(maxstack, Object); + stack = newvector(maxstack, TObject); stackLimit = stack+maxstack; top = stack; *(top++) = initial_stack; @@ -105,7 +106,7 @@ static void growstack (void) static int limit = STACK_LIMIT; StkId t = top-stack; Long stacksize = stackLimit - stack; - stacksize = growvector(&stack, stacksize, Object, stackEM, limit+100); + stacksize = growvector(&stack, stacksize, TObject, stackEM, limit+100); stackLimit = stack+stacksize; top = stack + t; if (stacksize >= limit) @@ -134,16 +135,16 @@ static char *lua_strconc (char *l, char *r) ** Convert, if possible, to a number object. ** Return 0 if success, not 0 if error. */ -static int lua_tonumber (Object *obj) +static int lua_tonumber (TObject *obj) { float t; char c; - if (tag(obj) != LUA_T_STRING) + if (ttype(obj) != LUA_T_STRING) return 1; else if (sscanf(svalue(obj), "%f %c",&t, &c) == 1) { nvalue(obj) = t; - tag(obj) = LUA_T_NUMBER; + ttype(obj) = LUA_T_NUMBER; return 0; } else @@ -152,39 +153,54 @@ static int lua_tonumber (Object *obj) /* -** Convert, if possible, to a string tag +** Convert, if possible, to a string ttype ** Return 0 in success or not 0 on error. */ -static int lua_tostring (Object *obj) +static int lua_tostring (TObject *obj) { - char s[256]; - if (tag(obj) != LUA_T_NUMBER) - return 1; - if ((int) nvalue(obj) == nvalue(obj)) - sprintf (s, "%d", (int) nvalue(obj)); - else - sprintf (s, "%g", nvalue(obj)); - tsvalue(obj) = lua_createstring(s); - tag(obj) = LUA_T_STRING; - return 0; + if (ttype(obj) != LUA_T_NUMBER) + return 1; + else { + char s[60]; + real f = nvalue(obj); + int i; + if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i=(int)f) == f) + sprintf (s, "%d", i); + else + sprintf (s, "%g", nvalue(obj)); + tsvalue(obj) = lua_createstring(s); + ttype(obj) = LUA_T_STRING; + return 0; + } } /* ** Adjust stack. Set top to the given value, pushing NILs if needed. */ -static void adjust_top (StkId newtop) +static void adjust_top_aux (StkId newtop) { - Object *nt; + TObject *nt; lua_checkstack(stack+newtop); nt = stack+newtop; /* warning: previous call may change stack */ - while (top < nt) tag(top++) = LUA_T_NIL; - top = nt; /* top could be bigger than newtop */ + while (top < nt) ttype(top++) = LUA_T_NIL; } + +#define adjust_top(newtop) { if (newtop <= top-stack) \ + top = stack+newtop; \ + else adjust_top_aux(newtop); } + #define adjustC(nParams) adjust_top(CLS_current.base+nParams) +static void checkCparams (int nParams) +{ + if (top-stack < CLS_current.base+nParams) + lua_error("API error - wrong number of arguments in C2lua stack"); +} + + /* ** Open a hole below "nelems" from the top. */ @@ -197,13 +213,37 @@ static void open_stack (int nelems) } +static lua_Object put_luaObject (TObject *o) +{ + open_stack((top-stack)-CLS_current.base); + stack[CLS_current.base++] = *o; + return CLS_current.base; /* this is +1 real position (see Ref) */ +} + + +static lua_Object put_luaObjectonTop (void) +{ + open_stack((top-stack)-CLS_current.base); + stack[CLS_current.base++] = *(--top); + return CLS_current.base; /* this is +1 real position (see Ref) */ +} + + +lua_Object lua_pop (void) +{ + checkCparams(1); + return put_luaObjectonTop(); +} + + + /* ** call Line hook */ static void lineHook (int line) { struct C_Lua_Stack oldCLS = CLS_current; - StkId old_top = CLS_current.base = top-stack; + StkId old_top = CLS_current.lua2C = CLS_current.base = top-stack; CLS_current.num = 0; (*lua_linehook)(line); top = stack+old_top; @@ -218,13 +258,13 @@ static void lineHook (int line) static void callHook (StkId base, lua_Type type, int isreturn) { struct C_Lua_Stack oldCLS = CLS_current; - StkId old_top = CLS_current.base = top-stack; + StkId old_top = CLS_current.lua2C = CLS_current.base = top-stack; CLS_current.num = 0; if (isreturn) (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); else { - Object *f = stack+base-1; + TObject *f = stack+base-1; if (type == LUA_T_MARK) (*lua_callhook)(Ref(f), f->value.tf->fileName, f->value.tf->lineDefined); else @@ -246,6 +286,7 @@ static StkId callC (lua_CFunction func, StkId base) StkId firstResult; CLS_current.num = (top-stack) - base; /* incorporate parameters on the stack */ + CLS_current.lua2C = base; CLS_current.base = base+CLS_current.num; /* == top-stack */ if (lua_callhook) callHook(base, LUA_T_CMARK, 0); @@ -257,15 +298,11 @@ static StkId callC (lua_CFunction func, StkId base) return firstResult; } -/* -** Call the specified fallback, putting it on the stack below its arguments -*/ -static void callFB (int fb) +static void callIM (TObject *f, int nParams, int nResults) { - int nParams = luaI_fallBacks[fb].nParams; open_stack(nParams); - *(top-nParams-1) = luaI_fallBacks[fb].function; - do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults); + *(top-nParams-1) = *f; + do_call((top-stack)-nParams, nResults); } @@ -278,28 +315,28 @@ static void callFB (int fb) static void do_call (StkId base, int nResults) { StkId firstResult; - Object *func = stack+base-1; + TObject *func = stack+base-1; int i; - if (tag(func) == LUA_T_CFUNCTION) - { - tag(func) = LUA_T_CMARK; + if (ttype(func) == LUA_T_CFUNCTION) { + ttype(func) = LUA_T_CMARK; firstResult = callC(fvalue(func), base); } - else if (tag(func) == LUA_T_FUNCTION) - { - tag(func) = LUA_T_MARK; + else if (ttype(func) == LUA_T_FUNCTION) { + ttype(func) = LUA_T_MARK; firstResult = lua_execute(func->value.tf->code, base); } - else - { /* func is not a function */ - /* Call the fallback for invalid functions */ + else { /* func is not a function */ + /* Check the tag method for invalid functions */ + TObject *im = luaI_getimbyObj(func, IM_FUNCTION); + if (ttype(im) == LUA_T_NIL) + lua_error("call expression not a function"); open_stack((top-stack)-(base-1)); - stack[base-1] = luaI_fallBacks[FB_FUNCTION].function; + stack[base-1] = *im; do_call(base, nResults); return; } /* adjust the number of results */ - if (nResults != MULT_RET && top - (stack+firstResult) != nResults) + if (nResults != MULT_RET) adjust_top(firstResult+nResults); /* move results to base-1 (to erase parameters and function) */ base--; @@ -316,58 +353,110 @@ static void do_call (StkId base, int nResults) */ static void pushsubscript (void) { - if (tag(top-2) != LUA_T_ARRAY) - callFB(FB_GETTABLE); - else - { - Object *h = lua_hashget(avalue(top-2), top-1); - if (h == NULL || tag(h) == LUA_T_NIL) - callFB(FB_INDEX); - else - { - --top; - *(top-1) = *h; + TObject *im; + if (ttype(top-2) != LUA_T_ARRAY) /* not a table, get "gettable" method */ + im = luaI_getimbyObj(top-2, IM_GETTABLE); + else { /* object is a table... */ + int tg = (top-2)->value.a->htag; + im = luaI_getim(tg, IM_GETTABLE); + if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */ + TObject *h = lua_hashget(avalue(top-2), top-1); + if (h != NULL && ttype(h) != LUA_T_NIL) { + --top; + *(top-1) = *h; + } + else if (ttype(im=luaI_getim(tg, IM_INDEX)) != LUA_T_NIL) + callIM(im, 2, 1); + else { + --top; + ttype(top-1) = LUA_T_NIL; + } + return; } + /* else it has a "gettable" method, go through to next command */ + } + /* object is not a table, or it has a "gettable" method */ + if (ttype(im) != LUA_T_NIL) + callIM(im, 2, 1); + else + lua_error("indexed expression not a table"); +} + + +lua_Object lua_rawgettable (void) +{ + checkCparams(2); + if (ttype(top-2) != LUA_T_ARRAY) + lua_error("indexed expression not a table in raw gettable"); + else { + TObject *h = lua_hashget(avalue(top-2), top-1); + --top; + if (h != NULL) + *(top-1) = *h; + else + ttype(top-1) = LUA_T_NIL; } + return put_luaObjectonTop(); } /* ** Function to store indexed based on values at the top +** mode = 0: raw store (without internal methods) +** mode = 1: normal store (with internal methods) +** mode = 2: "deep stack" store (with internal methods) */ -static void storesubscript (void) +static void storesubscript (TObject *t, int mode) { - if (tag(top-3) != LUA_T_ARRAY) - callFB(FB_SETTABLE); - else - { - Object *h = lua_hashdefine (avalue(top-3), top-2); - *h = *(top-1); - top -= 3; - } + TObject *im = (mode == 0) ? NULL : luaI_getimbyObj(t, IM_SETTABLE); + if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) { + TObject *h = lua_hashdefine(avalue(t), t+1); + *h = *(top-1); + top -= (mode == 2) ? 1 : 3; + } + else { /* object is not a table, and/or has a specific "settable" method */ + if (im && ttype(im) != LUA_T_NIL) { + if (mode == 2) { + lua_checkstack(top+2); + *(top+1) = *(top-1); + *(top) = *(t+1); + *(top-1) = *t; + top += 2; + } + callIM(im, 3, 0); + } + else + lua_error("indexed expression not a table"); + } } static void getglobal (Word n) { - *top = lua_table[n].object; - incr_top; - if (tag(top-1) == LUA_T_NIL) - { /* must call getglobal fallback */ - tag(top-1) = LUA_T_STRING; - tsvalue(top-1) = lua_table[n].varname; - callFB(FB_GETGLOBAL); + TObject *value = &lua_table[n].object; + TObject *im = luaI_getimbyObj(value, IM_GETGLOBAL); + if (ttype(im) == LUA_T_NIL) { /* default behavior */ + *top = *value; + incr_top; } + else { + ttype(top) = LUA_T_STRING; + tsvalue(top) = lua_table[n].varname; + incr_top; + *top = *value; + incr_top; + callIM(im, 2, 1); + } } /* ** Traverse all objects on stack */ -void lua_travstack (int (*fn)(Object *)) +void lua_travstack (int (*fn)(TObject *)) { - Object *o; - for (o = top-1; o >= stack; o--) - fn (o); + StkId i; + for (i = (top-1)-stack; i>=0; i--) + fn (stack+i); } @@ -377,8 +466,11 @@ void lua_travstack (int (*fn)(Object *)) static void lua_message (char *s) { - lua_pushstring(s); - callFB(FB_ERROR); + TObject *im = luaI_geterrorim(); + if (ttype(im) != LUA_T_NIL) { + lua_pushstring(s); + callIM(im, 1, 0); + } } /* @@ -399,25 +491,25 @@ void lua_error (char *s) lua_Function lua_stackedfunction (int level) { - Object *p = top; - while (--p >= stack) - if (p->tag == LUA_T_MARK || p->tag == LUA_T_CMARK) + StkId i; + for (i = (top-1)-stack; i>=0; i--) + if (stack[i].ttype == LUA_T_MARK || stack[i].ttype == LUA_T_CMARK) if (level-- == 0) - return Ref(p); + return Ref(stack+i); return LUA_NOOBJECT; } int lua_currentline (lua_Function func) { - Object *f = Address(func); - return (f+1 < top && (f+1)->tag == LUA_T_LINE) ? (f+1)->value.i : -1; + TObject *f = Address(func); + return (f+1 < top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1; } lua_Object lua_getlocal (lua_Function func, int local_number, char **name) { - Object *f = luaI_Address(func); + TObject *f = luaI_Address(func); *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func)); if (*name) { @@ -431,9 +523,9 @@ lua_Object lua_getlocal (lua_Function func, int local_number, char **name) int lua_setlocal (lua_Function func, int local_number) { - Object *f = Address(func); + TObject *f = Address(func); char *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func)); - adjustC(1); + checkCparams(1); --top; if (name) { @@ -446,6 +538,29 @@ int lua_setlocal (lua_Function func, int local_number) return 0; } +/* +** Call the function at CLS_current.base, and incorporate results on +** the Lua2C structure. +*/ +static void do_callinc (int nResults) +{ + StkId base = CLS_current.base; + do_call(base+1, nResults); + CLS_current.lua2C = base; /* position of the new results */ + CLS_current.num = (top-stack) - base; /* number of results */ + CLS_current.base = base + CLS_current.num; /* incorporate results on stack */ +} + + +static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults) +{ + StkId base = (top-stack)-nParams; + open_stack(nParams); + stack[base].ttype = LUA_T_CFUNCTION; + stack[base].value.f = f; + do_call(base+1, nResults); +} + /* ** Execute a protected call. Assumes that function is at CLS_current.base and @@ -458,15 +573,11 @@ static int do_protectedrun (int nResults) struct C_Lua_Stack oldCLS = CLS_current; jmp_buf *oldErr = errorJmp; errorJmp = &myErrorJmp; - if (setjmp(myErrorJmp) == 0) - { - do_call(CLS_current.base+1, nResults); - CLS_current.num = (top-stack) - CLS_current.base; /* number of results */ - CLS_current.base += CLS_current.num; /* incorporate results on the stack */ + if (setjmp(myErrorJmp) == 0) { + do_callinc(nResults); status = 0; } - else - { /* an error occurred: restore CLS_current and top */ + else { /* an error occurred: restore CLS_current and top */ CLS_current = oldCLS; top = stack+CLS_current.base; status = 1; @@ -479,13 +590,14 @@ int luaI_dorun (TFunc *tf) { int status; adjustC(1); /* one slot for the pseudo-function */ - stack[CLS_current.base].tag = LUA_T_FUNCTION; + stack[CLS_current.base].ttype = LUA_T_FUNCTION; stack[CLS_current.base].value.tf = tf; status = do_protectedrun(MULT_RET); return status; } -static int do_protectedmain (void) + +int lua_domain (void) { TFunc tf; int status; @@ -493,23 +605,21 @@ static int do_protectedmain (void) jmp_buf *oldErr = errorJmp; errorJmp = &myErrorJmp; luaI_initTFunc(&tf); - tf.fileName = lua_parsedfile; - if (setjmp(myErrorJmp) == 0) - { + if (setjmp(myErrorJmp) == 0) { lua_parse(&tf); - status = luaI_dorun(&tf); + status = 0; } - else - { - status = 1; + else { adjustC(0); /* erase extra slot */ + status = 1; } + if (status == 0) + status = luaI_dorun(&tf); errorJmp = oldErr; luaI_free(tf.code); return status; } - /* ** Execute the given lua function. Return 0 on success or 1 on error. */ @@ -526,71 +636,31 @@ int lua_callfunction (lua_Object function) } -int lua_call (char *funcname) +lua_Object lua_gettagmethod (int tag, char *event) { - Word n = luaI_findsymbolbyname(funcname); - open_stack((top-stack)-CLS_current.base); - stack[CLS_current.base] = s_object(n); - return do_protectedrun(MULT_RET); + lua_pushnumber(tag); + lua_pushstring(event); + do_unprotectedrun(luaI_gettagmethod, 2, 1); + return put_luaObjectonTop(); } - -/* -** Open file, generate opcode and execute global statement. Return 0 on -** success or non 0 on error. -*/ -int lua_dofile (char *filename) +lua_Object lua_settagmethod (int tag, char *event) { - int status; - int c; - FILE *f = lua_openfile(filename); - if (f == NULL) - return 2; - c = fgetc(f); - ungetc(c, f); - if (c == ID_CHUNK) { - f = freopen(filename, "rb", f); /* set binary mode */ - status = luaI_undump(f); - } - else { - if (c == '#') - while ((c=fgetc(f)) != '\n') /* skip first line */; - status = do_protectedmain(); - } - lua_closefile(); - return status; + TObject newmethod; + checkCparams(1); + newmethod = *(--top); + lua_pushnumber(tag); + lua_pushstring(event); + *top = newmethod; incr_top; + do_unprotectedrun(luaI_settagmethod, 3, 1); + return put_luaObjectonTop(); } -/* -** Generate opcode stored on string and execute global statement. Return 0 on -** success or non 0 on error. -*/ -int lua_dostring (char *str) +lua_Object lua_seterrormethod (void) { - int status; - if (str == NULL) - return 1; - lua_openstring(str); - status = do_protectedmain(); - lua_closestring(); - return status; -} - - -/* -** API: set a function as a fallback -*/ -lua_Object lua_setfallback (char *name, lua_CFunction fallback) -{ - adjustC(1); /* one slot for the pseudo-function */ - stack[CLS_current.base].tag = LUA_T_CFUNCTION; - stack[CLS_current.base].value.f = luaI_setfallback; - lua_pushstring(name); - lua_pushcfunction(fallback); - if (do_protectedrun(1) == 0) - return (Ref(top-1)); - else - return LUA_NOOBJECT; + checkCparams(1); + do_unprotectedrun(luaI_seterrormethod, 1, 1); + return put_luaObjectonTop(); } @@ -598,12 +668,11 @@ lua_Object lua_setfallback (char *name, lua_CFunction fallback) ** API: receives on the stack the table and the index. ** returns the value. */ -lua_Object lua_getsubscript (void) +lua_Object lua_gettable (void) { - adjustC(2); + checkCparams(2); pushsubscript(); - CLS_current.base++; /* incorporate object in the stack */ - return (Ref(top-1)); + return put_luaObjectonTop(); } @@ -633,13 +702,25 @@ void lua_endblock (void) adjustC(0); } +void lua_settag (int tag) +{ + checkCparams(1); + luaI_settag(tag, --top); +} + /* ** API: receives on the stack the table, the index, and the new value. */ -void lua_storesubscript (void) +void lua_settable (void) { - adjustC(3); - storesubscript(); + checkCparams(3); + storesubscript(top-3, 1); +} + +void lua_rawsettable (void) +{ + checkCparams(3); + storesubscript(top-3, 0); } /* @@ -647,40 +728,59 @@ void lua_storesubscript (void) */ lua_Object lua_createtable (void) { - adjustC(0); - avalue(top) = lua_createarray(0); - tag(top) = LUA_T_ARRAY; - incr_top; - CLS_current.base++; /* incorporate object in the stack */ - return Ref(top-1); + TObject o; + avalue(&o) = lua_createarray(0); + ttype(&o) = LUA_T_ARRAY; + return put_luaObject(&o); } /* ** Get a parameter, returning the object handle or LUA_NOOBJECT on error. ** 'number' must be 1 to get the first parameter. */ -lua_Object lua_getparam (int number) +lua_Object lua_lua2C (int number) +{ + if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT; + /* Ref(stack+(CLS_current.lua2C+number-1)) == + stack+(CLS_current.lua2C+number-1)-stack+1 == */ + return CLS_current.lua2C+number; +} + +int lua_isnil (lua_Object o) +{ + return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_NIL); +} + +int lua_istable (lua_Object o) +{ + return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_ARRAY); +} + +int lua_isuserdata (lua_Object o) { - if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT; - /* Ref(stack+(CLS_current.base-CLS_current.num+number-1)) == - stack+(CLS_current.base-CLS_current.num+number-1)-stack+1 == */ - return CLS_current.base-CLS_current.num+number; + return (o!= LUA_NOOBJECT) && (ttype(Address(o)) == LUA_T_USERDATA); } -int lua_isnumber (lua_Object object) +int lua_iscfunction (lua_Object o) { - return (object != LUA_NOOBJECT) && (tonumber(Address(object)) == 0); + int t = lua_tag(o); + return (t == LUA_T_CMARK) || (t == LUA_T_CFUNCTION); } -int lua_isstring (lua_Object object) +int lua_isnumber (lua_Object o) { - int t = lua_type(object); + return (o!= LUA_NOOBJECT) && (tonumber(Address(o)) == 0); +} + +int lua_isstring (lua_Object o) +{ + int t = lua_tag(o); return (t == LUA_T_STRING) || (t == LUA_T_NUMBER); } -int lua_isfunction (lua_Object object) +int lua_isfunction (lua_Object o) { - int t = lua_type(object); + int t = lua_tag(o); return (t == LUA_T_FUNCTION) || (t == LUA_T_CFUNCTION) || (t == LUA_T_MARK) || (t == LUA_T_CMARK); } @@ -700,57 +800,44 @@ real lua_getnumber (lua_Object object) */ char *lua_getstring (lua_Object object) { - if (object == LUA_NOOBJECT) return NULL; - if (tostring (Address(object))) return NULL; - else return (svalue(Address(object))); + if (object == LUA_NOOBJECT || tostring (Address(object))) + return NULL; + else return (svalue(Address(object))); } -/* -** Given an object handle, return its cfuntion pointer. On error, return NULL. -*/ -lua_CFunction lua_getcfunction (lua_Object object) + +void *lua_getuserdata (lua_Object object) { - if (object == LUA_NOOBJECT || ((tag(Address(object)) != LUA_T_CFUNCTION) && - (tag(Address(object)) != LUA_T_CMARK))) - return NULL; - else return (fvalue(Address(object))); + if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA) + return NULL; + else return tsvalue(Address(object))->u.v; } + /* -** Given an object handle, return its user data. On error, return NULL. +** Given an object handle, return its cfuntion pointer. On error, return NULL. */ -void *lua_getuserdata (lua_Object object) +lua_CFunction lua_getcfunction (lua_Object object) { - if (object == LUA_NOOBJECT || tag(Address(object)) < LUA_T_USERDATA) + if (object == LUA_NOOBJECT || ((ttype(Address(object)) != LUA_T_CFUNCTION) && + (ttype(Address(object)) != LUA_T_CMARK))) return NULL; - else return (uvalue(Address(object))); + else return (fvalue(Address(object))); } lua_Object lua_getref (int ref) { - Object *o = luaI_getref(ref); + TObject *o = luaI_getref(ref); if (o == NULL) return LUA_NOOBJECT; - adjustC(0); - luaI_pushobject(o); - CLS_current.base++; /* incorporate object in the stack */ - return Ref(top-1); -} - - -void lua_pushref (int ref) -{ - Object *o = luaI_getref(ref); - if (o == NULL) - lua_error("access to invalid (possibly garbage collected) reference"); - luaI_pushobject(o); + return put_luaObject(o); } int lua_ref (int lock) { - adjustC(1); + checkCparams(1); return luaI_ref(--top, lock); } @@ -761,20 +848,50 @@ int lua_ref (int lock) */ lua_Object lua_getglobal (char *name) { - adjustC(0); - getglobal(luaI_findsymbolbyname(name)); - CLS_current.base++; /* incorporate object in the stack */ - return Ref(top-1); + getglobal(luaI_findsymbolbyname(name)); + return put_luaObjectonTop(); +} + + +lua_Object lua_rawgetglobal (char *name) +{ + return put_luaObject(&lua_table[luaI_findsymbolbyname(name)].object); } + /* ** Store top of the stack at a global variable array field. */ -void lua_storeglobal (char *name) +static void setglobal (Word n) +{ + TObject *oldvalue = &lua_table[n].object; + TObject *im = luaI_getimbyObj(oldvalue, IM_SETGLOBAL); + if (ttype(im) == LUA_T_NIL) /* default behavior */ + s_object(n) = *(--top); + else { + TObject newvalue = *(top-1); + ttype(top-1) = LUA_T_STRING; + tsvalue(top-1) = lua_table[n].varname; + *top = *oldvalue; + incr_top; + *top = newvalue; + incr_top; + callIM(im, 3, 0); + } +} + + +void lua_setglobal (char *name) { - Word n = luaI_findsymbolbyname(name); - adjustC(1); - s_object(n) = *(--top); + checkCparams(1); + setglobal(luaI_findsymbolbyname(name)); +} + +void lua_rawsetglobal (char *name) +{ + Word n = luaI_findsymbolbyname(name); + checkCparams(1); + s_object(n) = *(--top); } /* @@ -782,60 +899,59 @@ void lua_storeglobal (char *name) */ void lua_pushnil (void) { - tag(top) = LUA_T_NIL; - incr_top; + ttype(top) = LUA_T_NIL; + incr_top; } /* -** Push an object (tag=number) to stack. +** Push an object (ttype=number) to stack. */ void lua_pushnumber (real n) { - tag(top) = LUA_T_NUMBER; nvalue(top) = n; + ttype(top) = LUA_T_NUMBER; nvalue(top) = n; incr_top; } /* -** Push an object (tag=string) to stack. +** Push an object (ttype=string) to stack. */ void lua_pushstring (char *s) { if (s == NULL) - tag(top) = LUA_T_NIL; + ttype(top) = LUA_T_NIL; else { tsvalue(top) = lua_createstring(s); - tag(top) = LUA_T_STRING; + ttype(top) = LUA_T_STRING; } incr_top; } -/*>>>>>>>>>#undef lua_pushliteral -void lua_pushliteral(char *s) { lua_pushstring(s); }*/ + /* -** Push an object (tag=cfunction) to stack. +** Push an object (ttype=cfunction) to stack. */ void lua_pushcfunction (lua_CFunction fn) { - tag(top) = LUA_T_CFUNCTION; fvalue(top) = fn; + ttype(top) = LUA_T_CFUNCTION; fvalue(top) = fn; incr_top; } -/* -** Push an object (tag=userdata) to stack. -*/ + + void lua_pushusertag (void *u, int tag) { - if (tag < LUA_T_USERDATA) - lua_error("invalid tag in `lua_pushusertag'"); - tag(top) = tag; uvalue(top) = u; - incr_top; + if (tag < 0 && tag != LUA_ANYTAG) + luaI_realtag(tag); /* error if tag is not valid */ + tsvalue(top) = luaI_createudata(u, tag); + ttype(top) = LUA_T_USERDATA; + incr_top; } /* ** Push an object on the stack. */ -void luaI_pushobject (Object *o) +void luaI_pushobject (TObject *o) { *top = *o; incr_top; @@ -847,78 +963,102 @@ void luaI_pushobject (Object *o) void lua_pushobject (lua_Object o) { if (o == LUA_NOOBJECT) - lua_error("attempt to push a NOOBJECT"); + lua_error("API error - attempt to push a NOOBJECT"); *top = *Address(o); - if (tag(top) == LUA_T_MARK) tag(top) = LUA_T_FUNCTION; - else if (tag(top) == LUA_T_CMARK) tag(top) = LUA_T_CFUNCTION; + if (ttype(top) == LUA_T_MARK) ttype(top) = LUA_T_FUNCTION; + else if (ttype(top) == LUA_T_CMARK) ttype(top) = LUA_T_CFUNCTION; incr_top; } -int lua_type (lua_Object o) +int lua_tag (lua_Object lo) { - if (o == LUA_NOOBJECT) - return LUA_T_NIL; - else - return tag(Address(o)); + if (lo == LUA_NOOBJECT) return LUA_T_NIL; + else { + TObject *o = Address(lo); + lua_Type t = ttype(o); + if (t == LUA_T_USERDATA) + return o->value.ts->tag; + else if (t == LUA_T_ARRAY) + return o->value.a->htag; + else return t; + } } -void luaI_gcFB (Object *o) +void luaI_gcIM (TObject *o) { - *top = *o; - incr_top; - callFB(FB_GC); + TObject *im = luaI_getimbyObj(o, IM_GC); + if (ttype(im) != LUA_T_NIL) { + *top = *o; + incr_top; + callIM(im, 1, 0); + } +} + + +static void call_binTM (IMS event, char *msg) +{ + TObject *im = luaI_getimbyObj(top-2, event); /* try first operand */ + if (ttype(im) == LUA_T_NIL) { + im = luaI_getimbyObj(top-1, event); /* try second operand */ + if (ttype(im) == LUA_T_NIL) { + im = luaI_getim(0, event); /* try a 'global' i.m. */ + if (ttype(im) == LUA_T_NIL) + lua_error(msg); + } + } + lua_pushstring(luaI_eventname[event]); + callIM(im, 3, 1); } -static void call_arith (char *op) +static void call_arith (IMS event) { - lua_pushstring(op); - callFB(FB_ARITH); + call_binTM(event, "unexpected type at arithmetic operation"); } -static void comparison (lua_Type tag_less, lua_Type tag_equal, - lua_Type tag_great, char *op) + +static void comparison (lua_Type ttype_less, lua_Type ttype_equal, + lua_Type ttype_great, IMS op) { - Object *l = top-2; - Object *r = top-1; + TObject *l = top-2; + TObject *r = top-1; int result; - if (tag(l) == LUA_T_NUMBER && tag(r) == LUA_T_NUMBER) + if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; - else if (tostring(l) || tostring(r)) - { - lua_pushstring(op); - callFB(FB_ORDER); + else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING) + result = strcmp(svalue(l), svalue(r)); + else { + call_binTM(op, "unexpected type at comparison"); return; } - else - result = strcmp(svalue(l), svalue(r)); top--; nvalue(top-1) = 1; - tag(top-1) = (result < 0) ? tag_less : (result == 0) ? tag_equal : tag_great; + ttype(top-1) = (result < 0) ? ttype_less : + (result == 0) ? ttype_equal : ttype_great; } static void adjust_varargs (StkId first_extra_arg) { - Object arg; - Object *firstelem = stack+first_extra_arg; + TObject arg; + TObject *firstelem = stack+first_extra_arg; int nvararg = top-firstelem; int i; if (nvararg < 0) nvararg = 0; avalue(&arg) = lua_createarray(nvararg+1); /* +1 for field 'n' */ - tag(&arg) = LUA_T_ARRAY; + ttype(&arg) = LUA_T_ARRAY; for (i=0; i<nvararg; i++) { - Object index; - tag(&index) = LUA_T_NUMBER; + TObject index; + ttype(&index) = LUA_T_NUMBER; nvalue(&index) = i+1; *(lua_hashdefine(avalue(&arg), &index)) = *(firstelem+i); } /* store counter in field "n" */ { - Object index, extra; - tag(&index) = LUA_T_STRING; + TObject index, extra; + ttype(&index) = LUA_T_STRING; tsvalue(&index) = lua_createstring("n"); - tag(&extra) = LUA_T_NUMBER; + ttype(&extra) = LUA_T_NUMBER; nvalue(&extra) = nvararg; *(lua_hashdefine(avalue(&arg), &index)) = extra; } @@ -942,22 +1082,22 @@ static StkId lua_execute (Byte *pc, StkId base) OpCode opcode; switch (opcode = (OpCode)*pc++) { - case PUSHNIL: tag(top) = LUA_T_NIL; incr_top; break; + case PUSHNIL: ttype(top) = LUA_T_NIL; incr_top; break; case PUSH0: case PUSH1: case PUSH2: - tag(top) = LUA_T_NUMBER; + ttype(top) = LUA_T_NUMBER; nvalue(top) = opcode-PUSH0; incr_top; break; case PUSHBYTE: - tag(top) = LUA_T_NUMBER; nvalue(top) = *pc++; incr_top; break; + ttype(top) = LUA_T_NUMBER; nvalue(top) = *pc++; incr_top; break; case PUSHWORD: { Word w; get_word(w,pc); - tag(top) = LUA_T_NUMBER; nvalue(top) = w; + ttype(top) = LUA_T_NUMBER; nvalue(top) = w; incr_top; } break; @@ -966,7 +1106,7 @@ static StkId lua_execute (Byte *pc, StkId base) { real num; get_float(num,pc); - tag(top) = LUA_T_NUMBER; nvalue(top) = num; + ttype(top) = LUA_T_NUMBER; nvalue(top) = num; incr_top; } break; @@ -975,7 +1115,7 @@ static StkId lua_execute (Byte *pc, StkId base) { Word w; get_word(w,pc); - tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w]; + ttype(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w]; incr_top; } break; @@ -985,7 +1125,7 @@ static StkId lua_execute (Byte *pc, StkId base) TFunc *f; get_code(f,pc); luaI_insertfunction(f); /* may take part in GC */ - top->tag = LUA_T_FUNCTION; + top->ttype = LUA_T_FUNCTION; top->value.tf = f; incr_top; } @@ -1013,10 +1153,10 @@ static StkId lua_execute (Byte *pc, StkId base) case PUSHSELF: { - Object receiver = *(top-1); + TObject receiver = *(top-1); Word w; get_word(w,pc); - tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w]; + ttype(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w]; incr_top; pushsubscript(); *top = receiver; @@ -1037,47 +1177,32 @@ static StkId lua_execute (Byte *pc, StkId base) { Word w; get_word(w,pc); - s_object(w) = *(--top); + setglobal(w); } break; case STOREINDEXED0: - storesubscript(); + storesubscript(top-3, 1); break; - case STOREINDEXED: - { - int n = *pc++; - if (tag(top-3-n) != LUA_T_ARRAY) - { - lua_checkstack(top+2); - *(top+1) = *(top-1); - *(top) = *(top-2-n); - *(top-1) = *(top-3-n); - top += 2; - callFB(FB_SETTABLE); - } - else - { - Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); - *h = *(top-1); - top--; - } + case STOREINDEXED: { + int n = *pc++; + storesubscript(top-3-n, 2); + break; } - break; case STORELIST0: case STORELIST: { int m, n; - Object *arr; + TObject *arr; if (opcode == STORELIST0) m = 0; else m = *(pc++) * FIELDS_PER_FLUSH; n = *(pc++); arr = top-n-1; while (n) { - tag(top) = LUA_T_NUMBER; nvalue(top) = n+m; + ttype(top) = LUA_T_NUMBER; nvalue(top) = n+m; *(lua_hashdefine (avalue(arr), top)) = *(top-1); top--; n--; @@ -1085,15 +1210,15 @@ static StkId lua_execute (Byte *pc, StkId base) } break; - case STORERECORD: + case STORERECORD: /* opcode obsolete: supersed by STOREMAP */ { int n = *(pc++); - Object *arr = top-n-1; + TObject *arr = top-n-1; while (n) { Word w; get_word(w,pc); - tag(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w]; + ttype(top) = LUA_T_STRING; tsvalue(top) = lua_constant[w]; *(lua_hashdefine (avalue(arr), top)) = *(top-1); top--; n--; @@ -1101,13 +1226,25 @@ static StkId lua_execute (Byte *pc, StkId base) } break; + case STOREMAP: { + int n = *(pc++); + TObject *arr = top-(2*n)-1; + while (n--) { + *(lua_hashdefine (avalue(arr), top-2)) = *(top-1); + top-=2; + } + } + break; + case ADJUST0: adjust_top(base); break; - case ADJUST: - adjust_top(base + *(pc++)); + case ADJUST: { + StkId newtop = base + *(pc++); + adjust_top(newtop); break; + } case VARARGS: adjust_varargs(base + *(pc++)); @@ -1118,7 +1255,7 @@ static StkId lua_execute (Byte *pc, StkId base) Word size; get_word(size,pc); avalue(top) = lua_createarray(size); - tag(top) = LUA_T_ARRAY; + ttype(top) = LUA_T_ARRAY; incr_top; } break; @@ -1127,33 +1264,33 @@ static StkId lua_execute (Byte *pc, StkId base) { int res = lua_equalObj(top-2, top-1); --top; - tag(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; + ttype(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; nvalue(top-1) = 1; } break; case LTOP: - comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, "lt"); + comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); break; case LEOP: - comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, "le"); + comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); break; case GTOP: - comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, "gt"); + comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); break; case GEOP: - comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, "ge"); + comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); break; case ADDOP: { - Object *l = top-2; - Object *r = top-1; + TObject *l = top-2; + TObject *r = top-1; if (tonumber(r) || tonumber(l)) - call_arith("add"); + call_arith(IM_ADD); else { nvalue(l) += nvalue(r); @@ -1164,10 +1301,10 @@ static StkId lua_execute (Byte *pc, StkId base) case SUBOP: { - Object *l = top-2; - Object *r = top-1; + TObject *l = top-2; + TObject *r = top-1; if (tonumber(r) || tonumber(l)) - call_arith("sub"); + call_arith(IM_SUB); else { nvalue(l) -= nvalue(r); @@ -1178,10 +1315,10 @@ static StkId lua_execute (Byte *pc, StkId base) case MULTOP: { - Object *l = top-2; - Object *r = top-1; + TObject *l = top-2; + TObject *r = top-1; if (tonumber(r) || tonumber(l)) - call_arith("mul"); + call_arith(IM_MUL); else { nvalue(l) *= nvalue(r); @@ -1192,10 +1329,10 @@ static StkId lua_execute (Byte *pc, StkId base) case DIVOP: { - Object *l = top-2; - Object *r = top-1; + TObject *l = top-2; + TObject *r = top-1; if (tonumber(r) || tonumber(l)) - call_arith("div"); + call_arith(IM_DIV); else { nvalue(l) /= nvalue(r); @@ -1205,36 +1342,34 @@ static StkId lua_execute (Byte *pc, StkId base) break; case POWOP: - call_arith("pow"); + call_arith(IM_POW); break; - case CONCOP: - { - Object *l = top-2; - Object *r = top-1; - if (tostring(r) || tostring(l)) - callFB(FB_CONCAT); - else - { - tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); - --top; - } + case CONCOP: { + TObject *l = top-2; + TObject *r = top-1; + if (tostring(l) || tostring(r)) + call_binTM(IM_CONCAT, "unexpected type for concatenation"); + else { + tsvalue(l) = lua_createstring(lua_strconc(svalue(l),svalue(r))); + --top; + } } break; case MINUSOP: if (tonumber(top-1)) { - tag(top) = LUA_T_NIL; + ttype(top) = LUA_T_NIL; incr_top; - call_arith("unm"); + call_arith(IM_UNM); } else nvalue(top-1) = - nvalue(top-1); break; case NOTOP: - tag(top-1) = (tag(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; + ttype(top-1) = (ttype(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; nvalue(top-1) = 1; break; @@ -1242,15 +1377,15 @@ static StkId lua_execute (Byte *pc, StkId base) { Word w; get_word(w,pc); - if (tag(top-1) != LUA_T_NIL) pc += w; + if (ttype(top-1) != LUA_T_NIL) pc += w; } break; - case ONFJMP: + case ONFJMP: { Word w; get_word(w,pc); - if (tag(top-1) == LUA_T_NIL) pc += w; + if (ttype(top-1) == LUA_T_NIL) pc += w; } break; @@ -1275,7 +1410,7 @@ static StkId lua_execute (Byte *pc, StkId base) Word w; get_word(w,pc); top--; - if (tag(top) == LUA_T_NIL) pc += w; + if (ttype(top) == LUA_T_NIL) pc += w; } break; @@ -1284,7 +1419,7 @@ static StkId lua_execute (Byte *pc, StkId base) Word w; get_word(w,pc); top--; - if (tag(top) == LUA_T_NIL) pc -= w; + if (ttype(top) == LUA_T_NIL) pc -= w; } break; @@ -1309,12 +1444,12 @@ static StkId lua_execute (Byte *pc, StkId base) { Word line; get_word(line,pc); - if ((stack+base-1)->tag != LUA_T_LINE) + if ((stack+base-1)->ttype != LUA_T_LINE) { /* open space for LINE value */ open_stack((top-stack)-base); base++; - (stack+base-1)->tag = LUA_T_LINE; + (stack+base-1)->ttype = LUA_T_LINE; } (stack+base-1)->value.i = line; if (lua_linehook) @@ -1328,3 +1463,16 @@ static StkId lua_execute (Byte *pc, StkId base) } } + +#if COMPAT2_5 +/* +** API: set a function as a fallback +*/ +lua_Object lua_setfallback (char *name, lua_CFunction fallback) +{ + lua_pushstring(name); + lua_pushcfunction(fallback); + do_unprotectedrun(luaI_setfallback, 2, 1); + return put_luaObjectonTop(); +} +#endif diff --git a/src/opcode.h b/src/opcode.h index 381efbc8..0b63de96 100644 --- a/src/opcode.h +++ b/src/opcode.h @@ -1,6 +1,6 @@ /* ** TeCGraf - PUC-Rio -** $Id: opcode.h,v 3.24 1996/11/01 12:46:59 roberto Exp $ +** $Id: opcode.h,v 3.34 1997/06/16 16:50:22 roberto Exp $ */ #ifndef opcode_h @@ -14,6 +14,28 @@ #define FIELDS_PER_FLUSH 40 +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER LUA_T" +*/ +typedef enum +{ + LUA_T_NIL = -9, + LUA_T_NUMBER = -8, + LUA_T_STRING = -7, + LUA_T_ARRAY = -6, /* array==table */ + LUA_T_FUNCTION = -5, + LUA_T_CFUNCTION= -4, + LUA_T_MARK = -3, + LUA_T_CMARK = -2, + LUA_T_LINE = -1, + LUA_T_USERDATA = 0 +} lua_Type; + +#define NUM_TYPES 10 + + +extern char *luaI_typenames[]; typedef enum { /* name parm before after side effect @@ -38,7 +60,7 @@ PUSHLOCAL6,/* - LOC[6] */ PUSHLOCAL7,/* - LOC[7] */ PUSHLOCAL8,/* - LOC[8] */ PUSHLOCAL9,/* - LOC[9] */ -PUSHLOCAL,/* w - LOC[w] */ +PUSHLOCAL,/* b - LOC[b] */ PUSHGLOBAL,/* w - VAR[w] */ PUSHINDEXED,/* i t t[i] */ PUSHSELF,/* w t t t[STR[w]] */ @@ -52,14 +74,14 @@ STORELOCAL6,/* x - LOC[6]=x */ STORELOCAL7,/* x - LOC[7]=x */ STORELOCAL8,/* x - LOC[8]=x */ STORELOCAL9,/* x - LOC[9]=x */ -STORELOCAL,/* w x - LOC[w]=x */ +STORELOCAL,/* b x - LOC[b]=x */ STOREGLOBAL,/* w x - VAR[w]=x */ STOREINDEXED0,/* v i t - t[i]=v */ STOREINDEXED,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ -STORELIST0,/* w v_w...v_1 t - t[i]=v_i */ -STORELIST,/* w n v_w...v_1 t - t[i+n*FPF]=v_i */ -STORERECORD,/* n - w_n...w_1 v_n...v_1 t - t[STR[w_i]]=v_i */ +STORELIST0,/* b v_b...v_1 t - t[i]=v_i */ +STORELIST,/* b c v_b...v_1 t - t[i+c*FPF]=v_i */ +STORERECORD,/* b + w_b...w_1 v_b...v_1 t - t[STR[w_i]]=v_i */ ADJUST0,/* - - TOP=BASE */ ADJUST,/* b - - TOP=BASE+b */ CREATEARRAY,/* w - newarray(size = w) */ @@ -76,19 +98,19 @@ POWOP,/* y x x^y */ CONCOP,/* y x x..y */ MINUSOP,/* x -x */ NOTOP,/* x (x==nil)? 1 : nil */ -ONTJMP,/* w x - (x!=nil)? PC+=w */ -ONFJMP,/* w x - (x==nil)? PC+=w */ +ONTJMP,/* w x - (x!=nil)? PC+=w */ +ONFJMP,/* w x - (x==nil)? PC+=w */ JMP,/* w - - PC+=w */ -UPJMP,/* w - - PC-=w */ -IFFJMP,/* w x - (x==nil)? PC+=w */ +UPJMP,/* w - - PC-=w */ +IFFJMP,/* w x - (x==nil)? PC+=w */ IFFUPJMP,/* w x - (x==nil)? PC-=w */ POP,/* x - */ -CALLFUNC,/* n m v_n...v_1 f r_m...r_1 f(v1,...,v_n) */ +CALLFUNC,/* b c v_b...v_1 f r_c...r_1 f(v1,...,v_b) */ RETCODE0, RETCODE,/* b - - */ SETLINE,/* w - - LINE=w */ -VARARGS/* b v_n...v_1 {v_1...v_n;n=n} */ - +VARARGS,/* b v_b...v_1 {v_1...v_b;n=b} */ +STOREMAP/* b v_b k_b ...v_1 k_1 t - t[k_i]=v_i */ } OpCode; @@ -102,29 +124,27 @@ typedef union TaggedString *ts; TFunc *tf; struct Hash *a; - void *u; int i; } Value; -typedef struct Object +typedef struct TObject { - lua_Type tag; + lua_Type ttype; Value value; -} Object; +} TObject; /* Macros to access structure members */ -#define tag(o) ((o)->tag) +#define ttype(o) ((o)->ttype) #define nvalue(o) ((o)->value.n) #define svalue(o) ((o)->value.ts->str) #define tsvalue(o) ((o)->value.ts) #define avalue(o) ((o)->value.a) #define fvalue(o) ((o)->value.f) -#define uvalue(o) ((o)->value.u) /* Macros to access symbol table */ #define s_object(i) (lua_table[i].object) -#define s_tag(i) (tag(&s_object(i))) +#define s_ttype(i) (ttype(&s_object(i))) #define s_nvalue(i) (nvalue(&s_object(i))) #define s_svalue(i) (svalue(&s_object(i))) #define s_tsvalue(i) (tsvalue(&s_object(i))) @@ -141,10 +161,11 @@ typedef struct Object /* Exported functions */ void lua_parse (TFunc *tf); /* from "lua.stx" module */ void luaI_codedebugline (int line); /* from "lua.stx" module */ -void lua_travstack (int (*fn)(Object *)); -Object *luaI_Address (lua_Object o); -void luaI_pushobject (Object *o); -void luaI_gcFB (Object *o); +void lua_travstack (int (*fn)(TObject *)); +TObject *luaI_Address (lua_Object o); +void luaI_pushobject (TObject *o); +void luaI_gcIM (TObject *o); int luaI_dorun (TFunc *tf); +int lua_domain (void); #endif diff --git a/src/parser.c b/src/parser.c index c91ee00e..ad5f8d68 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,14 +10,14 @@ static char luaY_sccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; #define YYPREFIX "luaY_" #line 2 "lua.stx" -char *rcs_luastx = "$Id: parser.c,v 1.1 1996/11/21 16:11:40 lhf Exp $"; +char *rcs_luastx = "$Id: parser.c,v 1.1 1997/06/30 18:59:03 lhf Exp $"; #include <stdio.h> #include <stdlib.h> #include <string.h> #include "luadebug.h" -#include "mem.h" +#include "luamem.h" #include "lex.h" #include "opcode.h" #include "hash.h" @@ -60,8 +60,6 @@ static TaggedString *localvar[MAXLOCALS]; /* store local variable names */ static int nlocalvar=0; /* number of local variables */ #define MAXFIELDS FIELDS_PER_FLUSH*2 -static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ -static int nfields=0; int lua_debug = 0; @@ -113,22 +111,11 @@ static void code_word_at (Byte *p, int n) memcpy(p, &w, sizeof(Word)); } -static void push_field (Word name) -{ - if (nfields < MAXFIELDS) - fields[nfields++] = name; - else - luaY_error ("too many fields in nested constructors"); -} - static void flush_record (int n) { - int i; if (n == 0) return; - code_byte(STORERECORD); + code_byte(STOREMAP); code_byte(n); - for (i=0; i<n; i++) - code_word(fields[--nfields]); } static void flush_list (int m, int n) @@ -171,11 +158,22 @@ static void add_varbuffer (Long var) luaY_error ("variable buffer overflow"); } +static void code_string (Word w) +{ + code_byte(PUSHSTRING); + code_word(w); +} + +static void code_constant (TaggedString *s) +{ + code_string(luaI_findconstant(s)); +} + static void code_number (float f) { - Word i = (Word)f; - if (f == (float)i) /* f has an (short) integer value */ - { + Word i; + if (f >= 0 && f <= (float)MAX_WORD && (float)(i=(Word)f) == f) { + /* f has an (short) integer value */ if (i <= 2) code_byte(PUSH0 + i); else if (i <= 255) { @@ -418,7 +416,7 @@ void lua_parse (TFunc *tf) } -#line 414 "lua.stx" +#line 412 "lua.stx" typedef union { int vInt; @@ -429,7 +427,7 @@ typedef union TFunc *pFunc; TaggedString *pTStr; } YYSTYPE; -#line 433 "y.tab.c" +#line 431 "y.tab.c" #define WRONGTOKEN 257 #define NIL 258 #define IF 259 @@ -467,8 +465,9 @@ short luaY_lhs[] = { -1, 38, 5, 39, 5, 40, 37, 4, 8, 8, 7, 7, 2, 2, 3, 41, 3, 17, 17, 18, 18, 19, 19, 42, 9, 9, 14, 14, 43, 43, 12, - 12, 13, 13, 44, 15, 15, 16, 16, 6, 6, - 20, 20, 20, 21, 29, 10, 10, 11, 11, + 12, 13, 13, 44, 45, 45, 15, 15, 16, 16, + 6, 6, 20, 20, 20, 21, 29, 10, 10, 11, + 11, }; short luaY_len[] = { 2, 2, 0, 3, 2, 3, 1, 3, 5, 0, 3, @@ -479,113 +478,114 @@ short luaY_len[] = { 2, 0, 5, 0, 5, 0, 4, 2, 1, 3, 3, 1, 0, 1, 1, 0, 4, 0, 1, 1, 3, 1, 1, 0, 3, 2, 0, 2, 0, 1, 0, - 2, 1, 3, 3, 0, 2, 1, 3, 1, 3, - 1, 4, 3, 1, 1, 1, 3, 0, 2, + 2, 1, 3, 3, 3, 1, 0, 2, 1, 3, + 1, 3, 1, 4, 3, 1, 1, 1, 3, 0, + 2, }; short luaY_defred[] = { 2, - 0, 0, 0, 14, 16, 0, 0, 0, 94, 19, - 0, 0, 0, 91, 1, 0, 4, 0, 48, 46, - 47, 0, 0, 0, 49, 29, 95, 0, 0, 44, - 0, 0, 24, 0, 0, 0, 0, 96, 0, 0, + 0, 0, 0, 14, 16, 0, 0, 0, 96, 19, + 0, 0, 0, 93, 1, 0, 4, 0, 48, 46, + 47, 0, 0, 0, 49, 29, 97, 0, 0, 44, + 0, 0, 24, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 57, 61, 12, 3, 0, 0, 0, 0, 0, 0, 28, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 27, 65, 0, 0, 20, 0, - 5, 0, 0, 0, 0, 0, 59, 0, 93, 30, + 5, 0, 0, 0, 0, 0, 59, 0, 95, 30, 24, 51, 53, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 73, 0, - 0, 82, 28, 0, 0, 0, 0, 97, 72, 71, - 0, 0, 69, 7, 60, 92, 28, 0, 0, 0, - 56, 0, 75, 0, 0, 86, 24, 0, 25, 0, - 0, 24, 0, 0, 0, 0, 0, 0, 83, 0, - 74, 0, 28, 17, 10, 0, 70, 24, 0, 0, - 77, 0, 0, 8, 22, 0, 13, 81, 15, 28, - 24, 28, 0, 23, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, + 0, 0, 82, 0, 28, 0, 0, 0, 0, 99, + 72, 71, 0, 0, 69, 7, 60, 94, 28, 0, + 0, 0, 56, 0, 75, 0, 0, 88, 0, 24, + 0, 25, 0, 0, 24, 0, 0, 0, 0, 85, + 86, 83, 0, 74, 0, 0, 28, 17, 10, 0, + 70, 24, 0, 0, 77, 0, 0, 8, 22, 0, + 13, 81, 15, 28, 24, 28, 0, 23, }; short luaY_dgoto[] = { 1, - 91, 34, 35, 25, 26, 11, 46, 12, 107, 39, - 79, 161, 108, 151, 109, 110, 121, 122, 123, 27, + 91, 34, 35, 25, 26, 11, 46, 12, 108, 39, + 79, 165, 109, 154, 110, 111, 123, 124, 125, 27, 14, 41, 81, 2, 15, 16, 49, 17, 28, 73, - 115, 37, 160, 32, 33, 74, 30, 128, 129, 31, - 116, 134, 133, 112, + 117, 37, 164, 32, 33, 74, 30, 130, 131, 31, + 118, 136, 135, 113, 114, }; short luaY_sindex[] = { 0, - 0, 332, -38, 0, 0, -38, -239, -223, 0, 0, - -23, 17, 0, 0, 0, 3, 0, 137, 0, 0, - 0, -38, -38, -38, 0, 0, 0, 137, 547, 0, - -25, -38, 0, 3, 45, 0, 212, 0, -22, 0, - 52, 140, -38, -223, -38, 0, 0, 0, 0, -166, - -38, -154, 40, 40, 102, 0, 0, 0, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -34, 481, -130, 0, 0, 0, -38, -129, 0, -194, - 0, -123, 45, 0, -17, 103, 0, 753, 0, 0, - 0, 0, 0, -30, -30, -30, -30, -30, -30, 95, - 11, 11, 40, 40, 40, 97, 41, 123, 0, 124, - 212, 0, 0, -38, -59, -38, 45, 0, 0, 0, - 128, 131, 0, 0, 0, 0, 0, -38, -38, -38, - 0, -97, 0, 120, -38, 0, 0, 212, 0, 3, - 0, 0, -194, -183, 118, 118, 212, 97, 0, -97, - 0, 212, 0, 0, 0, -85, 0, 0, -38, -82, - 0, 123, -80, 0, 0, 1105, 0, 0, 0, 0, - 0, 0, -183, 0, + 0, 288, -34, 0, 0, -34, -238, -223, 0, 0, + -6, 22, 0, 0, 0, 14, 0, 150, 0, 0, + 0, -34, -34, -34, 0, 0, 0, 150, 547, 0, + -46, -34, 0, 14, 34, 0, 212, 0, -5, 0, + 39, 156, -34, -223, -34, 0, 0, 0, 0, -194, + -34, -193, -4, -4, 48, 0, 0, 0, -34, -34, + -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, + -38, 481, -173, 0, 0, 0, -34, -146, 0, -234, + 0, -138, 34, 0, -15, 96, 0, 753, 0, 0, + 0, 0, 0, -30, -30, -30, -30, -30, -30, -20, + -12, -12, -4, -4, -4, 0, -34, 16, 95, 0, + 98, 212, 0, 82, 0, -34, 328, -34, 34, 0, + 0, 0, 103, 101, 0, 0, 0, 0, 0, -34, + -34, 1181, 0, -91, 0, 92, -34, 0, -34, 0, + 212, 0, 14, 0, 0, -234, -233, 118, 118, 0, + 0, 0, -91, 0, 212, 212, 0, 0, 0, -105, + 0, 0, -34, -103, 0, 95, -101, 0, 0, 1105, + 0, 0, 0, 0, 0, 0, -233, 0, }; short luaY_rindex[] = { 0, - 0, 191, 69, 0, 0, 173, 0, 0, 0, 0, - 0, 69, 150, 0, 0, 146, 0, -36, 0, 0, - 0, 69, 69, 69, 0, 0, 0, 1, 0, 0, - 0, 69, 0, 47, 461, 436, 0, 0, 197, 130, - 0, 0, 69, 0, -33, 0, 0, 0, 0, 0, - 69, 0, 24, 59, 1181, 0, 0, 0, 69, 69, - 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, - -50, 0, 0, 0, 0, 0, 69, 0, 0, 152, - 0, 0, 311, -21, 0, 0, 0, 0, 0, 0, + 0, 169, 52, 0, 0, 173, 0, 0, 0, 0, + 0, 52, 508, 0, 0, 146, 0, -36, 0, 0, + 0, 52, 52, 52, 0, 0, 0, 1, 0, 0, + 0, 52, 0, 47, 461, 436, 0, 0, 197, 76, + 0, 0, 52, 0, -32, 0, 0, 0, 0, 0, + 52, 0, 24, 59, 1195, 0, 0, 0, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + -27, 0, 0, 0, 0, 0, 52, 0, 0, 129, + 0, 0, 311, 142, 0, 0, 0, 0, 0, 0, 0, 0, 0, 746, 776, 799, 821, 844, 866, 505, - 383, 410, 88, 112, 359, 1174, 0, 74, 0, -40, - -26, 0, 0, 69, -230, 69, 921, 0, 0, 0, - 0, 160, 0, 0, 0, 0, 0, 69, 69, 69, - 0, 77, 0, 78, -9, 0, 0, 939, 0, 289, - 474, 0, 0, -60, 894, 1137, -16, 0, 0, 89, - 0, -10, 0, 0, 0, 0, 0, 0, 69, 0, - 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, -60, 0, + 383, 410, 88, 112, 359, 1174, 52, 0, 51, 0, + -40, -10, 0, 0, 0, 52, -153, 52, 921, 0, + 0, 0, 0, 144, 0, 0, 0, 0, 0, 52, + 52, 0, 0, 62, 0, 64, -26, 0, 52, 0, + 939, 0, 682, 474, 0, 0, -77, 894, 1137, 0, + 0, 0, 66, 0, 13, -18, 0, 0, 0, 0, + 0, 0, 52, 0, 0, 51, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -77, 0, }; short luaY_gindex[] = { 0, - -31, 171, 85, -2, 48, 0, 0, 0, 0, 0, - 0, 0, 67, 0, 0, 0, 0, 0, 75, 8, - 0, 0, 0, 0, 104, 107, -29, 0, 12, -61, - 0, 1260, 50, 0, 0, 0, 213, 0, 0, 0, - 0, 0, -107, 94, + 53, 147, -23, 3, 134, 0, 0, 0, 0, 0, + 0, 0, 40, 0, 0, 0, 0, 0, 49, 6, + 0, 0, 0, 0, 81, 83, -16, 0, 8, -70, + 0, 1445, 27, 0, 0, 0, 187, 0, 0, 0, + 0, 0, -108, 67, 0, }; -#define YYTABLESIZE 1462 -short luaY_table[] = { 10, - 45, 24, 136, 58, 75, 24, 22, 62, 85, 13, - 22, 68, 66, 18, 67, 40, 69, 87, 78, 42, - 44, 78, 90, 43, 95, 92, 93, 84, 52, 127, - 26, 26, 87, 88, 38, 26, 26, 43, 77, 90, - 58, 45, 45, 45, 45, 45, 11, 45, 88, 79, - 9, 84, 68, 36, 168, 85, 45, 69, 50, 45, - 45, 48, 45, 70, 43, 43, 43, 43, 43, 95, - 43, 55, 55, 51, 85, 153, 119, 158, 159, 120, - 156, 137, 43, 43, 78, 43, 58, 39, 76, 55, - 36, 80, 36, 45, 45, 144, 165, 71, 87, 50, - 50, 50, 50, 50, 70, 50, 154, 87, 84, 172, - 155, 40, 10, 55, 88, 79, 43, 50, 50, 89, - 50, 163, 13, 58, 36, 45, 18, 83, 39, 39, - 39, 39, 39, 70, 39, 114, 68, 66, 171, 67, - 173, 69, 90, 125, 118, 11, 39, 39, 43, 39, - 124, 50, 40, 40, 40, 40, 40, 130, 40, 68, - 66, 117, 67, 141, 69, 131, 132, 135, 142, 6, - 40, 40, 62, 40, 143, 95, 148, 62, 150, 61, - 39, 164, 52, 50, 167, 52, 169, 95, 70, 95, - 26, 55, 67, 89, 50, 95, 98, 82, 78, 3, - 68, 79, 76, 4, 40, 5, 21, 95, 6, 7, - 89, 70, 39, 80, 9, 86, 162, 157, 139, 19, - 95, 140, 174, 19, 47, 149, 0, 51, 0, 0, - 51, 62, 0, 20, 21, 9, 40, 20, 21, 106, - 95, 0, 0, 0, 23, 0, 0, 0, 23, 0, - 65, 0, 0, 68, 66, 98, 67, 0, 69, 45, +#define YYTABLESIZE 1608 +short luaY_table[] = { 107, + 45, 24, 138, 58, 10, 24, 22, 13, 62, 18, + 22, 68, 66, 40, 67, 42, 69, 75, 78, 83, + 129, 68, 66, 43, 67, 84, 69, 162, 163, 68, + 52, 87, 79, 89, 69, 38, 121, 44, 78, 122, + 58, 45, 45, 45, 45, 45, 11, 45, 89, 84, + 9, 85, 107, 119, 43, 77, 90, 172, 50, 45, + 45, 45, 45, 70, 43, 43, 43, 43, 43, 157, + 43, 90, 48, 70, 160, 51, 71, 76, 80, 87, + 89, 70, 43, 43, 78, 43, 58, 39, 90, 70, + 55, 169, 116, 45, 45, 55, 55, 87, 79, 50, + 50, 50, 50, 50, 176, 50, 84, 26, 26, 92, + 93, 40, 26, 26, 89, 6, 43, 50, 50, 10, + 50, 97, 13, 58, 18, 45, 159, 120, 39, 39, + 39, 39, 39, 97, 39, 126, 127, 90, 134, 36, + 133, 137, 139, 145, 146, 11, 39, 39, 43, 39, + 153, 50, 40, 40, 40, 40, 40, 55, 40, 68, + 66, 168, 67, 171, 69, 173, 97, 140, 26, 67, + 40, 40, 62, 40, 55, 78, 36, 62, 36, 61, + 39, 147, 151, 50, 68, 92, 79, 97, 76, 21, + 80, 86, 166, 158, 161, 52, 100, 142, 47, 143, + 152, 52, 92, 178, 40, 0, 0, 50, 0, 167, + 36, 70, 39, 82, 0, 0, 0, 0, 0, 19, + 0, 0, 0, 19, 0, 0, 175, 0, 177, 0, + 0, 62, 97, 20, 21, 106, 40, 20, 21, 9, + 51, 0, 0, 0, 23, 0, 51, 0, 23, 0, + 65, 144, 0, 68, 66, 100, 67, 0, 69, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 62, 95, 61, 45, 45, 45, 45, 45, 45, + 45, 62, 0, 61, 45, 45, 45, 45, 45, 45, 45, 45, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 0, 55, 0, 43, 43, 43, 43, 43, 43, 43, 43, 70, 0, 11, 11, 0, @@ -603,25 +603,25 @@ short luaY_table[] = { 10, 41, 0, 0, 37, 0, 37, 37, 37, 0, 0, 0, 0, 0, 62, 62, 64, 0, 0, 62, 62, 0, 37, 37, 0, 37, 0, 0, 0, 0, 0, - 38, 41, 38, 38, 38, 98, 0, 98, 98, 98, - 63, 98, 98, 98, 98, 98, 98, 0, 38, 38, - 98, 38, 0, 66, 0, 37, 64, 29, 29, 64, + 38, 41, 38, 38, 38, 100, 0, 100, 100, 100, + 63, 100, 100, 100, 100, 100, 100, 0, 38, 38, + 100, 38, 0, 66, 0, 37, 64, 29, 29, 64, 29, 0, 29, 41, 0, 0, 57, 58, 59, 60, 63, 64, 65, 0, 64, 29, 0, 29, 0, 0, 0, 63, 38, 0, 42, 0, 0, 37, 0, 0, 0, 0, 0, 0, 66, 29, 29, 66, 29, 63, 29, 0, 68, 66, 0, 67, 0, 69, 0, 29, 0, 0, 66, 29, 38, 29, 0, 0, 0, 0, - 62, 0, 61, 0, 0, 42, 0, 11, 42, 11, - 11, 11, 0, 11, 11, 11, 11, 11, 0, 0, - 0, 0, 11, 42, 42, 0, 42, 29, 0, 18, + 62, 0, 61, 0, 0, 42, 3, 97, 42, 0, + 4, 91, 5, 97, 0, 6, 7, 8, 0, 0, + 0, 9, 0, 42, 42, 97, 42, 29, 91, 18, 0, 18, 18, 18, 70, 18, 18, 18, 18, 18, - 18, 0, 0, 0, 18, 0, 0, 0, 68, 66, - 3, 67, 0, 69, 4, 0, 5, 42, 0, 6, - 7, 8, 0, 0, 0, 9, 62, 0, 61, 0, + 18, 0, 0, 0, 18, 0, 3, 0, 68, 66, + 4, 67, 5, 69, 0, 6, 7, 42, 97, 0, + 0, 9, 0, 0, 0, 0, 62, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, - 0, 0, 41, 41, 41, 41, 41, 41, 41, 41, + 97, 0, 41, 41, 41, 41, 41, 41, 41, 41, 70, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 37, 37, 37, 37, 37, 37, 37, 37, 0, 0, 0, 0, 38, 38, @@ -632,7 +632,7 @@ short luaY_table[] = { 10, 29, 29, 29, 29, 29, 29, 29, 0, 0, 0, 0, 63, 63, 0, 0, 0, 63, 63, 0, 0, 0, 0, 66, 0, 66, 66, 66, 0, 66, 66, - 66, 66, 66, 66, 113, 31, 0, 66, 29, 29, + 66, 66, 66, 66, 115, 31, 0, 66, 29, 29, 29, 29, 29, 29, 29, 57, 58, 59, 60, 63, 64, 65, 0, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 34, 0, 0, 42, 42, @@ -642,7 +642,7 @@ short luaY_table[] = { 10, 0, 0, 62, 0, 61, 0, 34, 0, 0, 34, 32, 57, 58, 59, 60, 63, 64, 65, 0, 0, 0, 0, 0, 0, 34, 34, 0, 34, 31, 33, - 0, 0, 33, 35, 0, 126, 70, 0, 0, 0, + 0, 0, 33, 35, 0, 128, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 33, 0, 33, 32, 0, 0, 32, 36, 0, 0, 34, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 32, @@ -650,12 +650,12 @@ short luaY_table[] = { 10, 0, 33, 0, 52, 0, 0, 0, 0, 0, 0, 34, 0, 35, 35, 0, 35, 36, 0, 0, 36, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, - 99, 0, 0, 33, 36, 36, 0, 36, 0, 0, + 101, 0, 0, 33, 36, 36, 0, 36, 0, 0, 0, 0, 0, 0, 52, 0, 35, 52, 28, 0, - 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, - 0, 0, 52, 0, 0, 0, 0, 0, 36, 0, + 11, 0, 11, 11, 11, 32, 11, 11, 11, 11, + 11, 0, 52, 0, 0, 11, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 31, 31, 31, 31, 31, 31, @@ -675,66 +675,80 @@ short luaY_table[] = { 10, 36, 36, 36, 36, 36, 36, 68, 66, 0, 67, 0, 69, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 62, 0, 61, 52, 52, 52, - 0, 0, 0, 0, 0, 0, 0, 54, 0, 99, - 54, 99, 99, 99, 0, 99, 99, 99, 99, 99, - 99, 0, 0, 0, 99, 54, 0, 28, 70, 28, + 0, 0, 0, 0, 0, 0, 0, 54, 0, 101, + 54, 101, 101, 101, 0, 101, 101, 101, 101, 101, + 101, 0, 0, 0, 101, 54, 0, 28, 70, 28, 28, 28, 0, 28, 28, 28, 28, 28, 28, 0, - 0, 0, 28, 94, 0, 94, 94, 94, 94, 94, - 94, 0, 29, 29, 0, 29, 0, 29, 0, 54, - 0, 94, 94, 94, 0, 94, 0, 0, 0, 0, - 29, 0, 29, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 28, 96, 0, 96, 96, 96, 96, 96, + 96, 0, 68, 66, 0, 67, 0, 69, 0, 54, + 0, 96, 96, 96, 86, 96, 29, 29, 0, 29, + 62, 29, 61, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 29, 0, 29, 0, 0, 0, + 0, 54, 0, 0, 96, 0, 0, 96, 0, 0, + 0, 0, 0, 150, 70, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, + 0, 0, 0, 0, 0, 0, 96, 0, 96, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 54, 29, 0, 94, 0, 0, 94, 0, 0, - 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, - 0, 53, 54, 0, 0, 0, 0, 0, 0, 0, - 0, 72, 0, 0, 0, 0, 94, 0, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 88, 0, 0, 0, 0, 0, 0, 0, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 170, 0, 0, 0, 0, 0, - 0, 0, 0, 138, 0, 0, 0, 0, 0, 57, - 58, 59, 60, 63, 64, 65, 0, 145, 146, 147, - 0, 0, 0, 0, 152, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 174, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, + 58, 59, 60, 63, 64, 65, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, - 54, 54, 54, 0, 0, 0, 0, 0, 166, 0, + 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 29, 96, 96, + 96, 96, 96, 96, 96, 57, 58, 59, 60, 63, + 64, 65, 0, 0, 0, 0, 53, 54, 0, 29, + 29, 29, 29, 29, 29, 29, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, + 0, 0, 0, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 94, 94, - 94, 94, 94, 94, 94, 29, 29, 29, 29, 29, - 29, 29, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 132, 0, 0, 0, 0, 0, 0, 0, 0, + 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 148, 149, 0, 0, 0, 0, + 0, 155, 0, 156, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 170, }; -short luaY_check[] = { 2, - 0, 40, 110, 40, 34, 40, 45, 41, 59, 2, - 45, 42, 43, 2, 45, 8, 47, 44, 59, 8, - 44, 44, 44, 0, 46, 57, 58, 44, 46, 91, - 261, 262, 59, 44, 274, 266, 267, 61, 61, 61, - 40, 41, 42, 43, 44, 45, 0, 47, 59, 59, - 274, 44, 42, 6, 162, 44, 40, 47, 0, 59, - 60, 59, 62, 94, 41, 42, 43, 44, 45, 91, - 47, 24, 123, 91, 125, 137, 271, 261, 262, 274, - 142, 113, 59, 60, 125, 62, 123, 0, 44, 123, - 43, 40, 45, 93, 94, 127, 158, 123, 125, 41, - 42, 43, 44, 45, 94, 47, 138, 274, 125, 171, - 140, 0, 115, 123, 125, 125, 93, 59, 60, 274, - 62, 153, 115, 123, 77, 125, 115, 43, 41, 42, - 43, 44, 45, 94, 47, 266, 42, 43, 170, 45, - 172, 47, 41, 41, 274, 0, 59, 60, 125, 62, - 274, 93, 41, 42, 43, 44, 45, 61, 47, 42, - 43, 77, 45, 116, 47, 125, 44, 44, 41, 40, - 59, 60, 0, 62, 44, 46, 274, 60, 59, 62, - 93, 267, 46, 125, 267, 46, 267, 58, 94, 40, - 0, 123, 41, 44, 58, 46, 0, 58, 125, 259, - 41, 125, 125, 263, 93, 265, 267, 58, 268, 269, - 61, 94, 125, 125, 274, 45, 150, 143, 115, 258, - 91, 115, 173, 258, 12, 132, -1, 91, -1, -1, - 91, 59, -1, 272, 273, 274, 125, 272, 273, 274, - 91, -1, -1, -1, 283, -1, -1, -1, 283, -1, - 281, -1, -1, 42, 43, 59, 45, -1, 47, 259, +short luaY_check[] = { 91, + 0, 40, 111, 40, 2, 40, 45, 2, 41, 2, + 45, 42, 43, 8, 45, 8, 47, 34, 59, 43, + 91, 42, 43, 0, 45, 44, 47, 261, 262, 42, + 46, 59, 59, 44, 47, 274, 271, 44, 44, 274, + 40, 41, 42, 43, 44, 45, 0, 47, 59, 44, + 274, 44, 91, 77, 61, 61, 44, 166, 0, 59, + 60, 40, 62, 94, 41, 42, 43, 44, 45, 140, + 47, 59, 59, 94, 145, 91, 123, 44, 40, 274, + 274, 94, 59, 60, 125, 62, 123, 0, 41, 94, + 123, 162, 266, 93, 94, 123, 123, 125, 125, 41, + 42, 43, 44, 45, 175, 47, 125, 261, 262, 57, + 58, 0, 266, 267, 125, 40, 93, 59, 60, 117, + 62, 46, 117, 123, 117, 125, 143, 274, 41, 42, + 43, 44, 45, 58, 47, 274, 41, 125, 44, 6, + 125, 44, 61, 41, 44, 0, 59, 60, 125, 62, + 59, 93, 41, 42, 43, 44, 45, 24, 47, 42, + 43, 267, 45, 267, 47, 267, 91, 115, 0, 41, + 59, 60, 0, 62, 123, 125, 43, 60, 45, 62, + 93, 129, 274, 125, 41, 44, 125, 46, 125, 267, + 125, 45, 153, 141, 146, 46, 0, 117, 12, 117, + 134, 46, 61, 177, 93, -1, -1, 58, -1, 157, + 77, 94, 125, 58, -1, -1, -1, -1, -1, 258, + -1, -1, -1, 258, -1, -1, 174, -1, 176, -1, + -1, 59, 91, 272, 273, 274, 125, 272, 273, 274, + 91, -1, -1, -1, 283, -1, 91, -1, 283, -1, + 281, 118, -1, 42, 43, 59, 45, -1, 47, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 60, 123, 62, 274, 275, 276, 277, 278, 279, + 270, 60, -1, 62, 274, 275, 276, 277, 278, 279, 280, 281, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, -1, 123, -1, 274, 275, 276, 277, 278, 279, 280, 281, 94, -1, 261, 262, -1, @@ -761,16 +775,16 @@ short luaY_check[] = { 2, -1, -1, -1, -1, 41, 42, 43, 44, 45, 59, 47, -1, 42, 43, -1, 45, -1, 47, -1, 94, -1, -1, 59, 60, 125, 62, -1, -1, -1, -1, - 60, -1, 62, -1, -1, 41, -1, 259, 44, 261, - 262, 263, -1, 265, 266, 267, 268, 269, -1, -1, - -1, -1, 274, 59, 60, -1, 62, 94, -1, 259, + 60, -1, 62, -1, -1, 41, 259, 40, 44, -1, + 263, 44, 265, 46, -1, 268, 269, 270, -1, -1, + -1, 274, -1, 59, 60, 58, 62, 94, 61, 259, -1, 261, 262, 263, 94, 265, 266, 267, 268, 269, - 270, -1, -1, -1, 274, -1, -1, -1, 42, 43, - 259, 45, -1, 47, 263, -1, 265, 93, -1, 268, - 269, 270, -1, -1, -1, 274, 60, -1, 62, -1, + 270, -1, -1, -1, 274, -1, 259, -1, 42, 43, + 263, 45, 265, 47, -1, 268, 269, 93, 91, -1, + -1, 274, -1, -1, -1, -1, 60, -1, 62, -1, -1, -1, -1, -1, -1, -1, -1, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 125, - -1, -1, 274, 275, 276, 277, 278, 279, 280, 281, + 123, -1, 274, 275, 276, 277, 278, 279, 280, 281, 94, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, -1, -1, -1, 274, 275, 276, 277, 278, 279, 280, 281, -1, -1, -1, -1, 259, 260, @@ -801,8 +815,8 @@ short luaY_check[] = { 2, -1, -1, -1, 93, -1, -1, -1, -1, -1, -1, 0, -1, -1, 125, 59, 60, -1, 62, -1, -1, -1, -1, -1, -1, 41, -1, 93, 44, 0, -1, - -1, -1, -1, -1, -1, 125, -1, -1, -1, -1, - -1, -1, 59, -1, -1, -1, -1, -1, 93, -1, + 259, -1, 261, 262, 263, 125, 265, 266, 267, 268, + 269, -1, 59, -1, -1, 274, -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, 125, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 59, -1, -1, -1, -1, -1, -1, 93, -1, -1, -1, @@ -830,30 +844,44 @@ short luaY_check[] = { 2, 262, 263, -1, 265, 266, 267, 268, 269, 270, -1, -1, -1, 274, 40, -1, 42, 43, 44, 45, 46, 47, -1, 42, 43, -1, 45, -1, 47, -1, 93, - -1, 58, 59, 60, -1, 62, -1, -1, -1, -1, - 60, -1, 62, -1, -1, -1, -1, -1, -1, -1, + -1, 58, 59, 60, 61, 62, 42, 43, -1, 45, + 60, 47, 62, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 60, -1, 62, -1, -1, -1, + -1, 125, -1, -1, 91, -1, -1, 94, -1, -1, + -1, -1, -1, 93, 94, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 94, -1, + -1, -1, -1, -1, -1, -1, 123, -1, 125, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 125, 3, -1, 91, -1, -1, 94, -1, -1, - -1, -1, -1, -1, 94, -1, -1, -1, -1, -1, - -1, 22, 23, -1, -1, -1, -1, -1, -1, -1, - -1, 32, -1, -1, -1, -1, 123, -1, 125, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 51, -1, -1, -1, -1, -1, -1, -1, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 260, -1, -1, -1, -1, -1, - -1, -1, -1, 114, -1, -1, -1, -1, -1, 275, - 276, 277, 278, 279, 280, 281, -1, 128, 129, 130, - -1, -1, -1, -1, 135, 259, 260, 261, 262, 263, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 275, + 276, 277, 278, 279, 280, 281, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, -1, -1, -1, - 274, 275, 276, -1, -1, -1, -1, -1, 159, -1, + 274, 275, 276, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 275, 276, + -1, -1, -1, -1, -1, -1, -1, 3, 275, 276, 277, 278, 279, 280, 281, 275, 276, 277, 278, 279, - 280, 281, + 280, 281, -1, -1, -1, -1, 22, 23, -1, 275, + 276, 277, 278, 279, 280, 281, 32, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 51, -1, -1, -1, -1, + -1, -1, -1, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 107, -1, -1, -1, -1, -1, -1, -1, -1, + 116, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 130, 131, -1, -1, -1, -1, + -1, 137, -1, 139, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 163, }; #define YYFINAL 1 #ifndef YYDEBUG @@ -958,7 +986,9 @@ char *luaY_rule[] = { "ffieldlist : ffieldlist1 lastcomma", "ffieldlist1 : ffield", "ffieldlist1 : ffieldlist1 ',' ffield", -"ffield : NAME '=' expr1", +"ffield : ffieldkey '=' expr1", +"ffieldkey : '[' expr1 ']'", +"ffieldkey : NAME", "lfieldlist :", "lfieldlist : lfieldlist1 lastcomma", "lfieldlist1 : expr1", @@ -1139,7 +1169,7 @@ luaY_reduce: switch (luaY_n) { case 5: -#line 470 "lua.stx" +#line 468 "lua.stx" { code_byte(PUSHFUNCTION); code_code(luaY_vsp[0].pFunc); @@ -1147,28 +1177,26 @@ case 5: } break; case 6: -#line 477 "lua.stx" +#line 475 "lua.stx" { luaY_val.vLong =luaY_vsp[0].vLong; init_func(); } break; case 7: -#line 479 "lua.stx" +#line 477 "lua.stx" { - code_byte(PUSHSTRING); - code_word(luaI_findconstant(luaY_vsp[0].pTStr)); + code_constant(luaY_vsp[0].pTStr); luaY_val.vLong = 0; /* indexed variable */ init_func(); add_localvar(luaI_createfixedstring("self")); } break; case 8: -#line 489 "lua.stx" +#line 486 "lua.stx" { codereturn(); luaY_val.pFunc = new(TFunc); luaI_initTFunc(luaY_val.pFunc); luaY_val.pFunc->size = pc; luaY_val.pFunc->code = newvector(pc, Byte); - luaY_val.pFunc->fileName = lua_parsedfile; luaY_val.pFunc->lineDefined = luaY_vsp[-3].vInt; memcpy(luaY_val.pFunc->code, basepc, pc*sizeof(Byte)); if (lua_debug) @@ -1182,15 +1210,15 @@ case 8: } break; case 13: -#line 516 "lua.stx" +#line 512 "lua.stx" { codeIf(luaY_vsp[-4].vLong, luaY_vsp[-2].vLong); } break; case 14: -#line 518 "lua.stx" +#line 514 "lua.stx" {luaY_val.vLong=pc;} break; case 15: -#line 519 "lua.stx" +#line 515 "lua.stx" { basepc[luaY_vsp[-3].vLong] = IFFJMP; code_word_at(basepc+luaY_vsp[-3].vLong+1, pc - (luaY_vsp[-3].vLong + sizeof(Word)+1)); @@ -1199,18 +1227,18 @@ case 15: } break; case 16: -#line 526 "lua.stx" +#line 522 "lua.stx" {luaY_val.vLong=pc;} break; case 17: -#line 527 "lua.stx" +#line 523 "lua.stx" { basepc[luaY_vsp[0].vLong] = IFFUPJMP; code_word_at(basepc+luaY_vsp[0].vLong+1, pc - (luaY_vsp[-4].vLong)); } break; case 18: -#line 533 "lua.stx" +#line 529 "lua.stx" { { int i; @@ -1222,22 +1250,26 @@ case 18: } } break; +case 19: +#line 539 "lua.stx" +{;} +break; case 20: -#line 545 "lua.stx" +#line 541 "lua.stx" { nlocalvar += luaY_vsp[-1].vInt; adjust_mult_assign(luaY_vsp[-1].vInt, luaY_vsp[0].vInt, 0); } break; case 23: -#line 553 "lua.stx" +#line 549 "lua.stx" { codeIf(luaY_vsp[-3].vLong, luaY_vsp[-1].vLong); } break; case 24: -#line 556 "lua.stx" +#line 552 "lua.stx" {luaY_val.vInt = nlocalvar;} break; case 25: -#line 557 "lua.stx" +#line 553 "lua.stx" { if (nlocalvar != luaY_vsp[-2].vInt) { @@ -1251,14 +1283,14 @@ case 25: } break; case 27: -#line 572 "lua.stx" +#line 568 "lua.stx" { adjust_functioncall(luaY_vsp[-1].vLong, MULT_RET); codereturn(); } break; case 28: -#line 579 "lua.stx" +#line 575 "lua.stx" { luaY_val.vLong = pc; code_byte(0); /* open space */ @@ -1266,103 +1298,102 @@ case 28: } break; case 29: -#line 586 "lua.stx" +#line 582 "lua.stx" { adjust_functioncall(luaY_vsp[0].vLong, 1); } break; case 30: -#line 589 "lua.stx" +#line 585 "lua.stx" { luaY_val.vLong = luaY_vsp[-1].vLong; } break; case 31: -#line 590 "lua.stx" +#line 586 "lua.stx" { code_byte(EQOP); luaY_val.vLong = 0; } break; case 32: -#line 591 "lua.stx" +#line 587 "lua.stx" { code_byte(LTOP); luaY_val.vLong = 0; } break; case 33: -#line 592 "lua.stx" +#line 588 "lua.stx" { code_byte(GTOP); luaY_val.vLong = 0; } break; case 34: -#line 593 "lua.stx" +#line 589 "lua.stx" { code_byte(EQOP); code_byte(NOTOP); luaY_val.vLong = 0; } break; case 35: -#line 594 "lua.stx" +#line 590 "lua.stx" { code_byte(LEOP); luaY_val.vLong = 0; } break; case 36: -#line 595 "lua.stx" +#line 591 "lua.stx" { code_byte(GEOP); luaY_val.vLong = 0; } break; case 37: -#line 596 "lua.stx" +#line 592 "lua.stx" { code_byte(ADDOP); luaY_val.vLong = 0; } break; case 38: -#line 597 "lua.stx" +#line 593 "lua.stx" { code_byte(SUBOP); luaY_val.vLong = 0; } break; case 39: -#line 598 "lua.stx" +#line 594 "lua.stx" { code_byte(MULTOP); luaY_val.vLong = 0; } break; case 40: -#line 599 "lua.stx" +#line 595 "lua.stx" { code_byte(DIVOP); luaY_val.vLong = 0; } break; case 41: -#line 600 "lua.stx" +#line 596 "lua.stx" { code_byte(POWOP); luaY_val.vLong = 0; } break; case 42: -#line 601 "lua.stx" +#line 597 "lua.stx" { code_byte(CONCOP); luaY_val.vLong = 0; } break; case 43: -#line 602 "lua.stx" +#line 598 "lua.stx" { code_byte(MINUSOP); luaY_val.vLong = 0;} break; case 44: -#line 603 "lua.stx" +#line 599 "lua.stx" { luaY_val.vLong = 0; } break; case 45: -#line 604 "lua.stx" +#line 600 "lua.stx" { luaY_val.vLong = 0;} break; case 46: -#line 605 "lua.stx" +#line 601 "lua.stx" { code_number(luaY_vsp[0].vFloat); luaY_val.vLong = 0; } break; case 47: -#line 607 "lua.stx" +#line 603 "lua.stx" { - code_byte(PUSHSTRING); - code_word(luaY_vsp[0].vWord); - luaY_val.vLong = 0; + code_string(luaY_vsp[0].vWord); + luaY_val.vLong = 0; } break; case 48: -#line 612 "lua.stx" +#line 607 "lua.stx" {code_byte(PUSHNIL); luaY_val.vLong = 0; } break; case 49: -#line 613 "lua.stx" +#line 608 "lua.stx" { luaY_val.vLong = luaY_vsp[0].vLong; } break; case 50: -#line 614 "lua.stx" +#line 609 "lua.stx" { code_byte(NOTOP); luaY_val.vLong = 0;} break; case 51: -#line 615 "lua.stx" +#line 610 "lua.stx" {code_byte(POP); } break; case 52: -#line 616 "lua.stx" +#line 611 "lua.stx" { basepc[luaY_vsp[-2].vLong] = ONFJMP; code_word_at(basepc+luaY_vsp[-2].vLong+1, pc - (luaY_vsp[-2].vLong + sizeof(Word)+1)); @@ -1370,11 +1401,11 @@ case 52: } break; case 53: -#line 621 "lua.stx" +#line 616 "lua.stx" {code_byte(POP); } break; case 54: -#line 622 "lua.stx" +#line 617 "lua.stx" { basepc[luaY_vsp[-2].vLong] = ONTJMP; code_word_at(basepc+luaY_vsp[-2].vLong+1, pc - (luaY_vsp[-2].vLong + sizeof(Word)+1)); @@ -1382,20 +1413,20 @@ case 54: } break; case 55: -#line 630 "lua.stx" +#line 625 "lua.stx" { code_byte(CREATEARRAY); luaY_val.vLong = pc; code_word(0); } break; case 56: -#line 635 "lua.stx" +#line 630 "lua.stx" { code_word_at(basepc+luaY_vsp[-3].vLong, luaY_vsp[-1].vInt); } break; case 57: -#line 641 "lua.stx" +#line 636 "lua.stx" { code_byte(CALLFUNC); code_byte(luaY_vsp[-1].vInt+luaY_vsp[0].vInt); @@ -1404,11 +1435,11 @@ case 57: } break; case 58: -#line 649 "lua.stx" +#line 644 "lua.stx" { luaY_val.vInt = 0; } break; case 59: -#line 651 "lua.stx" +#line 646 "lua.stx" { code_byte(PUSHSELF); code_word(luaI_findconstant(luaY_vsp[0].pTStr)); @@ -1416,31 +1447,31 @@ case 59: } break; case 60: -#line 659 "lua.stx" +#line 654 "lua.stx" { luaY_val.vInt = adjust_functioncall(luaY_vsp[-1].vLong, 1); } break; case 61: -#line 660 "lua.stx" +#line 655 "lua.stx" { luaY_val.vInt = 1; } break; case 62: -#line 663 "lua.stx" +#line 658 "lua.stx" { luaY_val.vLong = 0; } break; case 63: -#line 664 "lua.stx" +#line 659 "lua.stx" { luaY_val.vLong = luaY_vsp[0].vLong; } break; case 64: -#line 667 "lua.stx" +#line 662 "lua.stx" { if (luaY_vsp[0].vLong != 0) luaY_val.vLong = luaY_vsp[0].vLong; else luaY_val.vLong = -1; } break; case 65: -#line 668 "lua.stx" +#line 663 "lua.stx" { luaY_val.vLong = adjust_functioncall(luaY_vsp[-1].vLong, 1); } break; case 66: -#line 669 "lua.stx" +#line 664 "lua.stx" { if (luaY_vsp[0].vLong == 0) luaY_val.vLong = -(luaY_vsp[-1].vLong + 1); /* -length */ else @@ -1451,19 +1482,19 @@ case 66: } break; case 67: -#line 679 "lua.stx" +#line 674 "lua.stx" { luaY_val.vInt = close_parlist(0); } break; case 68: -#line 680 "lua.stx" +#line 675 "lua.stx" { luaY_val.vInt = close_parlist(luaY_vsp[0].vInt); } break; case 69: -#line 683 "lua.stx" +#line 678 "lua.stx" { luaY_val.vInt = luaY_vsp[0].vInt; } break; case 70: -#line 685 "lua.stx" +#line 680 "lua.stx" { if (luaY_vsp[-2].vInt) lua_error("invalid parameter list"); @@ -1471,113 +1502,110 @@ case 70: } break; case 71: -#line 692 "lua.stx" +#line 687 "lua.stx" { add_localvar(luaY_vsp[0].pTStr); luaY_val.vInt = 0; } break; case 72: -#line 693 "lua.stx" +#line 688 "lua.stx" { luaY_val.vInt = 1; } break; case 73: -#line 697 "lua.stx" +#line 692 "lua.stx" { flush_list(luaY_vsp[0].vInt/FIELDS_PER_FLUSH, luaY_vsp[0].vInt%FIELDS_PER_FLUSH); } break; case 74: -#line 699 "lua.stx" +#line 694 "lua.stx" { luaY_val.vInt = luaY_vsp[-2].vInt+luaY_vsp[0].vInt; } break; case 75: -#line 701 "lua.stx" +#line 696 "lua.stx" { luaY_val.vInt = luaY_vsp[-1].vInt; flush_record(luaY_vsp[-1].vInt%FIELDS_PER_FLUSH); } break; case 76: -#line 705 "lua.stx" +#line 700 "lua.stx" { luaY_val.vInt = 0; } break; case 77: -#line 707 "lua.stx" +#line 702 "lua.stx" { luaY_val.vInt = luaY_vsp[0].vInt; flush_record(luaY_vsp[0].vInt%FIELDS_PER_FLUSH); } break; case 80: -#line 714 "lua.stx" +#line 709 "lua.stx" { luaY_val.vInt = 0; } break; case 81: -#line 715 "lua.stx" +#line 710 "lua.stx" { luaY_val.vInt = luaY_vsp[-1].vInt; } break; case 82: -#line 718 "lua.stx" +#line 713 "lua.stx" {luaY_val.vInt=1;} break; case 83: -#line 720 "lua.stx" +#line 715 "lua.stx" { luaY_val.vInt=luaY_vsp[-2].vInt+1; if (luaY_val.vInt%FIELDS_PER_FLUSH == 0) flush_record(FIELDS_PER_FLUSH); } break; -case 84: -#line 727 "lua.stx" -{ - push_field(luaI_findconstant(luaY_vsp[-2].pTStr)); - } +case 86: +#line 725 "lua.stx" +{ code_constant(luaY_vsp[0].pTStr); } break; -case 85: -#line 732 "lua.stx" +case 87: +#line 728 "lua.stx" { luaY_val.vInt = 0; } break; -case 86: -#line 733 "lua.stx" +case 88: +#line 729 "lua.stx" { luaY_val.vInt = luaY_vsp[-1].vInt; } break; -case 87: -#line 736 "lua.stx" +case 89: +#line 732 "lua.stx" {luaY_val.vInt=1;} break; -case 88: -#line 738 "lua.stx" +case 90: +#line 734 "lua.stx" { luaY_val.vInt=luaY_vsp[-2].vInt+1; if (luaY_val.vInt%FIELDS_PER_FLUSH == 0) flush_list(luaY_val.vInt/FIELDS_PER_FLUSH - 1, FIELDS_PER_FLUSH); } break; -case 89: -#line 746 "lua.stx" +case 91: +#line 742 "lua.stx" { nvarbuffer = 0; add_varbuffer(luaY_vsp[0].vLong); luaY_val.vInt = (luaY_vsp[0].vLong == 0) ? 1 : 0; } break; -case 90: -#line 752 "lua.stx" +case 92: +#line 748 "lua.stx" { add_varbuffer(luaY_vsp[0].vLong); luaY_val.vInt = (luaY_vsp[0].vLong == 0) ? luaY_vsp[-2].vInt + 1 : luaY_vsp[-2].vInt; } break; -case 91: -#line 758 "lua.stx" +case 93: +#line 754 "lua.stx" { luaY_val.vLong = luaY_vsp[0].vLong; } break; -case 92: -#line 760 "lua.stx" +case 94: +#line 756 "lua.stx" { luaY_val.vLong = 0; /* indexed variable */ } break; -case 93: -#line 764 "lua.stx" +case 95: +#line 760 "lua.stx" { - code_byte(PUSHSTRING); - code_word(luaI_findconstant(luaY_vsp[0].pTStr)); - luaY_val.vLong = 0; /* indexed variable */ + code_constant(luaY_vsp[0].pTStr); + luaY_val.vLong = 0; /* indexed variable */ } break; -case 94: -#line 772 "lua.stx" +case 96: +#line 767 "lua.stx" { int local = lua_localname(luaY_vsp[0].pTStr); if (local == -1) /* global var */ @@ -1586,30 +1614,30 @@ case 94: luaY_val.vLong = -(local+1); /* return negative value */ } break; -case 95: -#line 781 "lua.stx" +case 97: +#line 776 "lua.stx" { lua_pushvar(luaY_vsp[0].vLong); } break; -case 96: -#line 784 "lua.stx" +case 98: +#line 779 "lua.stx" {store_localvar(luaY_vsp[0].pTStr, 0); luaY_val.vInt = 1;} break; -case 97: -#line 786 "lua.stx" +case 99: +#line 781 "lua.stx" { store_localvar(luaY_vsp[0].pTStr, luaY_vsp[-2].vInt); luaY_val.vInt = luaY_vsp[-2].vInt+1; } break; -case 98: -#line 792 "lua.stx" +case 100: +#line 787 "lua.stx" { luaY_val.vInt = 0; } break; -case 99: -#line 793 "lua.stx" +case 101: +#line 788 "lua.stx" { luaY_val.vInt = luaY_vsp[0].vLong; } break; -#line 1613 "y.tab.c" +#line 1641 "y.tab.c" } luaY_ssp -= luaY_m; luaY_state = *luaY_ssp; diff --git a/src/table.c b/src/table.c index b2e60a35..6f24ca9b 100644 --- a/src/table.c +++ b/src/table.c @@ -3,9 +3,11 @@ ** Module to control static tables */ -char *rcs_table="$Id: table.c,v 2.58 1996/11/01 12:47:45 roberto Exp $"; +char *rcs_table="$Id: table.c,v 2.72 1997/06/17 18:09:31 roberto Exp $"; -#include "mem.h" +#include "luamem.h" +#include "auxlib.h" +#include "func.h" #include "opcode.h" #include "tree.h" #include "hash.h" @@ -27,49 +29,14 @@ Word lua_nconstant = 0; static Long lua_maxconstant = 0; -#define GARBAGE_BLOCK 50 - -static void lua_nextvar (void); - -/* -** Internal functions -*/ -static struct { - char *name; - lua_CFunction func; -} int_funcs[] = { - {"assert", luaI_assert}, - {"call", luaI_call}, - {"dofile", lua_internaldofile}, - {"dostring", lua_internaldostring}, - {"error", luaI_error}, - {"getglobal", luaI_getglobal}, - {"next", lua_next}, - {"nextvar", lua_nextvar}, - {"print", luaI_print}, - {"setfallback", luaI_setfallback}, - {"setglobal", luaI_setglobal}, - {"tonumber", lua_obj2number}, - {"tostring", luaI_tostring}, - {"type", luaI_type} -}; - -#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0])) +#define GARBAGE_BLOCK 100 void luaI_initsymbol (void) { - int i; - Word n; lua_maxsymbol = BUFFER_BLOCK; lua_table = newvector(lua_maxsymbol, Symbol); - for (i=0; i<INTFUNCSIZE; i++) - { - n = luaI_findsymbolbyname(int_funcs[i].name); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func; - } - n = luaI_findsymbolbyname("_VERSION_"); - s_tag(n) = LUA_T_STRING; s_tsvalue(n) = lua_createstring(LUA_VERSION); + luaI_predefine(); } @@ -92,17 +59,17 @@ void luaI_initconstant (void) */ Word luaI_findsymbol (TaggedString *t) { - if (t->varindex == NOT_USED) + if (t->u.s.varindex == NOT_USED) { if (lua_ntable == lua_maxsymbol) lua_maxsymbol = growvector(&lua_table, lua_maxsymbol, Symbol, symbolEM, MAX_WORD); - t->varindex = lua_ntable; + t->u.s.varindex = lua_ntable; lua_table[lua_ntable].varname = t; - s_tag(lua_ntable) = LUA_T_NIL; + s_ttype(lua_ntable) = LUA_T_NIL; lua_ntable++; } - return t->varindex; + return t->u.s.varindex; } @@ -118,16 +85,16 @@ Word luaI_findsymbolbyname (char *name) */ Word luaI_findconstant (TaggedString *t) { - if (t->constindex == NOT_USED) + if (t->u.s.constindex == NOT_USED) { if (lua_nconstant == lua_maxconstant) lua_maxconstant = growvector(&lua_constant, lua_maxconstant, TaggedString *, constantEM, MAX_WORD); - t->constindex = lua_nconstant; + t->u.s.constindex = lua_nconstant; lua_constant[lua_nconstant] = t; lua_nconstant++; } - return t->constindex; + return t->u.s.constindex; } @@ -145,10 +112,16 @@ TaggedString *luaI_createfixedstring (char *name) } +int luaI_globaldefined (char *name) +{ + return ttype(&lua_table[luaI_findsymbolbyname(name)].object) != LUA_T_NIL; +} + + /* ** Traverse symbol table objects */ -static char *lua_travsymbol (int (*fn)(Object *)) +static char *lua_travsymbol (int (*fn)(TObject *)) { Word i; for (i=0; i<lua_ntable; i++) @@ -161,13 +134,14 @@ static char *lua_travsymbol (int (*fn)(Object *)) /* ** Mark an object if it is a string or a unmarked array. */ -int lua_markobject (Object *o) +int lua_markobject (TObject *o) {/* if already marked, does not change mark value */ - if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked) + if (ttype(o) == LUA_T_USERDATA || + (ttype(o) == LUA_T_STRING && !tsvalue(o)->marked)) tsvalue(o)->marked = 1; - else if (tag(o) == LUA_T_ARRAY) + else if (ttype(o) == LUA_T_ARRAY) lua_hashmark (avalue(o)); - else if ((o->tag == LUA_T_FUNCTION || o->tag == LUA_T_MARK) + else if ((o->ttype == LUA_T_FUNCTION || o->ttype == LUA_T_MARK) && !o->value.tf->marked) o->value.tf->marked = 1; return 0; @@ -176,11 +150,11 @@ int lua_markobject (Object *o) /* * returns 0 if the object is going to be (garbage) collected */ -int luaI_ismarked (Object *o) +int luaI_ismarked (TObject *o) { - switch (o->tag) + switch (o->ttype) { - case LUA_T_STRING: + case LUA_T_STRING: case LUA_T_USERDATA: return o->value.ts->marked; case LUA_T_FUNCTION: return o->value.tf->marked; @@ -192,76 +166,90 @@ int luaI_ismarked (Object *o) } +static void call_nilIM (void) +{ /* signals end of garbage collection */ + TObject t; + ttype(&t) = LUA_T_NIL; + luaI_gcIM(&t); /* end of list */ +} + /* ** Garbage collection. ** Delete all unused strings and arrays. */ -Long luaI_collectgarbage (void) +static long gc_block = GARBAGE_BLOCK; +static long gc_nentity = 0; /* total of strings, arrays, etc */ + +static void markall (void) { - Long recovered = 0; lua_travstack(lua_markobject); /* mark stack objects */ lua_travsymbol(lua_markobject); /* mark symbol table objects */ luaI_travlock(lua_markobject); /* mark locked objects */ luaI_travfallbacks(lua_markobject); /* mark fallbacks */ +} + + +long lua_collectgarbage (long limit) +{ + long recovered = 0; + Hash *freetable; + TaggedString *freestr; + TFunc *freefunc; + markall(); luaI_invalidaterefs(); - recovered += lua_strcollector(); - recovered += lua_hashcollector(); - recovered += luaI_funccollector(); + freetable = luaI_hashcollector(&recovered); + freestr = luaI_strcollector(&recovered); + freefunc = luaI_funccollector(&recovered); + gc_nentity -= recovered; + gc_block = (limit == 0) ? 2*(gc_block-recovered) : gc_nentity+limit; + luaI_hashcallIM(freetable); + luaI_strcallIM(freestr); + call_nilIM(); + luaI_hashfree(freetable); + luaI_strfree(freestr); + luaI_funcfree(freefunc); return recovered; } + void lua_pack (void) { - static unsigned long block = GARBAGE_BLOCK; - static unsigned long nentity = 0; /* total of strings, arrays, etc */ - unsigned long recovered = 0; - if (nentity++ < block) return; - recovered = luaI_collectgarbage(); - block = 2*(block-recovered); - nentity -= recovered; + if (++gc_nentity >= gc_block) + lua_collectgarbage(0); } /* ** Internal function: return next global variable */ -static void lua_nextvar (void) +void luaI_nextvar (void) { - Word next; - lua_Object o = lua_getparam(1); - if (o == LUA_NOOBJECT) - lua_error("too few arguments to function `nextvar'"); - if (lua_getparam(2) != LUA_NOOBJECT) - lua_error("too many arguments to function `nextvar'"); - if (lua_isnil(o)) - next = 0; - else if (!lua_isstring(o)) - { - lua_error("incorrect argument to function `nextvar'"); - return; /* to avoid warnings */ - } - else - next = luaI_findsymbolbyname(lua_getstring(o)) + 1; - while (next < lua_ntable && s_tag(next) == LUA_T_NIL) next++; - if (next < lua_ntable) - { - lua_pushstring(lua_table[next].varname->str); - luaI_pushobject(&s_object(next)); - } + Word next; + if (lua_isnil(lua_getparam(1))) + next = 0; + else + next = luaI_findsymbolbyname(luaL_check_string(1)) + 1; + while (next < lua_ntable && s_ttype(next) == LUA_T_NIL) + next++; + if (next < lua_ntable) { + lua_pushstring(lua_table[next].varname->str); + luaI_pushobject(&s_object(next)); + } } -static Object *functofind; -static int checkfunc (Object *o) +static TObject *functofind; +static int checkfunc (TObject *o) { - if (o->tag == LUA_T_FUNCTION) + if (o->ttype == LUA_T_FUNCTION) return - ((functofind->tag == LUA_T_FUNCTION || functofind->tag == LUA_T_MARK) + ((functofind->ttype == LUA_T_FUNCTION || functofind->ttype == LUA_T_MARK) && (functofind->value.tf == o->value.tf)); - if (o->tag == LUA_T_CFUNCTION) + if (o->ttype == LUA_T_CFUNCTION) return - ((functofind->tag == LUA_T_CFUNCTION || functofind->tag == LUA_T_CMARK) - && (functofind->value.f == o->value.f)); + ((functofind->ttype == LUA_T_CFUNCTION || + functofind->ttype == LUA_T_CMARK) && + (functofind->value.f == o->value.f)); return 0; } @@ -270,7 +258,7 @@ char *lua_getobjname (lua_Object o, char **name) { /* try to find a name for given function */ functofind = luaI_Address(o); if ((*name = luaI_travfallbacks(checkfunc)) != NULL) - return "fallback"; + return "tag-method"; else if ((*name = lua_travsymbol(checkfunc)) != NULL) return "global"; else return ""; diff --git a/src/table.h b/src/table.h index d7003c96..5a628526 100644 --- a/src/table.h +++ b/src/table.h @@ -1,7 +1,7 @@ /* ** Module to control static tables ** TeCGraf - PUC-Rio -** $Id: table.h,v 2.21 1996/04/22 18:00:37 roberto Exp $ +** $Id: table.h,v 2.25 1997/05/26 14:42:36 roberto Exp $ */ #ifndef table_h @@ -12,7 +12,7 @@ typedef struct { - Object object; + TObject object; TaggedString *varname; } Symbol; @@ -28,10 +28,11 @@ Word luaI_findsymbolbyname (char *name); Word luaI_findsymbol (TaggedString *t); Word luaI_findconstant (TaggedString *t); Word luaI_findconstantbyname (char *name); +int luaI_globaldefined (char *name); +void luaI_nextvar (void); TaggedString *luaI_createfixedstring (char *str); -int lua_markobject (Object *o); -int luaI_ismarked (Object *o); -Long luaI_collectgarbage (void); +int lua_markobject (TObject *o); +int luaI_ismarked (TObject *o); void lua_pack (void); @@ -3,17 +3,18 @@ ** TecCGraf - PUC-Rio */ -char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp $"; +char *rcs_tree="$Id: tree.c,v 1.28 1997/06/11 14:24:40 roberto Exp $"; #include <string.h> -#include "mem.h" +#include "luamem.h" #include "lua.h" #include "tree.h" #include "lex.h" #include "hash.h" #include "table.h" +#include "fallback.h" #define NUM_HASHS 64 @@ -28,23 +29,43 @@ static int initialized = 0; static stringtable string_root[NUM_HASHS]; -static TaggedString EMPTY = {NOT_USED, NOT_USED, 0, 2, {0}}; +static TaggedString EMPTY = {LUA_T_STRING, NULL, {{NOT_USED, NOT_USED}}, + 0, 2, {0}}; -static unsigned long hash (char *str) +static unsigned long hash (char *s, int tag) { - unsigned long h = 0; - while (*str) - h = ((h<<5)-h)^(unsigned char)*(str++); + unsigned long h; + if (tag != LUA_T_STRING) + h = (unsigned long)s; + else { + h = 0; + while (*s) + h = ((h<<5)-h)^(unsigned char)*(s++); + } return h; } + +static void luaI_inittree (void) +{ + int i; + for (i=0; i<NUM_HASHS; i++) { + string_root[i].size = 0; + string_root[i].nuse = 0; + string_root[i].hash = NULL; + } +} + + static void initialize (void) { initialized = 1; + luaI_inittree(); luaI_addReserved(); luaI_initsymbol(); luaI_initconstant(); + luaI_initfallbacks(); } @@ -58,8 +79,7 @@ static void grow (stringtable *tb) /* rehash */ tb->nuse = 0; for (i=0; i<tb->size; i++) - if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) - { + if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { int h = tb->hash[i]->hash%newsize; while (newhash[h]) h = (h+1)%newsize; @@ -71,10 +91,30 @@ static void grow (stringtable *tb) tb->hash = newhash; } -static TaggedString *insert (char *str, stringtable *tb) + +static TaggedString *newone(char *buff, int tag, unsigned long h) +{ + TaggedString *ts; + if (tag == LUA_T_STRING) { + ts = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(buff)); + strcpy(ts->str, buff); + ts->u.s.varindex = ts->u.s.constindex = NOT_USED; + ts->tag = LUA_T_STRING; + } + else { + ts = (TaggedString *)luaI_malloc(sizeof(TaggedString)); + ts->u.v = buff; + ts->tag = tag == LUA_ANYTAG ? 0 : tag; + } + ts->marked = 0; + ts->hash = h; + return ts; +} + +static TaggedString *insert (char *buff, int tag, stringtable *tb) { TaggedString *ts; - unsigned long h = hash(str); + unsigned long h = hash(buff, tag); int i; int j = -1; if ((Long)tb->nuse*3 >= (Long)tb->size*2) @@ -84,12 +124,14 @@ static TaggedString *insert (char *str, stringtable *tb) grow(tb); } i = h%tb->size; - while (tb->hash[i]) + while ((ts = tb->hash[i]) != NULL) { - if (tb->hash[i] == &EMPTY) + if (ts == &EMPTY) j = i; - else if (strcmp(str, tb->hash[i]->str) == 0) - return tb->hash[i]; + else if ((ts->tag == LUA_T_STRING) ? + (tag == LUA_T_STRING && (strcmp(buff, ts->str) == 0)) : + ((tag == ts->tag || tag == LUA_ANYTAG) && buff == ts->u.v)) + return ts; i = (i+1)%tb->size; } /* not found */ @@ -98,27 +140,49 @@ static TaggedString *insert (char *str, stringtable *tb) i = j; else tb->nuse++; - ts = tb->hash[i] = (TaggedString *)luaI_malloc(sizeof(TaggedString)+strlen(str)); - strcpy(ts->str, str); - ts->marked = 0; - ts->hash = h; - ts->varindex = ts->constindex = NOT_USED; + ts = tb->hash[i] = newone(buff, tag, h); return ts; } -TaggedString *lua_createstring (char *str) +TaggedString *luaI_createudata (void *udata, int tag) { - return insert(str, &string_root[(unsigned)str[0]%NUM_HASHS]); + return insert(udata, tag, &string_root[(unsigned)udata%NUM_HASHS]); +} + +TaggedString *lua_createstring (char *str) +{ + return insert(str, LUA_T_STRING, &string_root[(unsigned)str[0]%NUM_HASHS]); +} + + +void luaI_strcallIM (TaggedString *l) +{ + TObject o; + ttype(&o) = LUA_T_USERDATA; + for (; l; l=l->next) { + tsvalue(&o) = l; + luaI_gcIM(&o); + } +} + + +void luaI_strfree (TaggedString *l) +{ + while (l) { + TaggedString *next = l->next; + luaI_free(l); + l = next; + } } /* ** Garbage collection function. -** This function traverse the string list freeing unindexed strings */ -Long lua_strcollector (void) +TaggedString *luaI_strcollector (long *acum) { Long counter = 0; + TaggedString *frees = NULL; int i; for (i=0; i<NUM_HASHS; i++) { @@ -133,13 +197,15 @@ Long lua_strcollector (void) t->marked = 0; else { - luaI_free(t); + t->next = frees; + frees = t; tb->hash[j] = &EMPTY; counter++; } } } } - return counter; + *acum += counter; + return frees; } @@ -1,7 +1,7 @@ /* ** tree.h ** TecCGraf - PUC-Rio -** $Id: tree.h,v 1.14 1996/02/26 17:07:49 roberto Exp $ +** $Id: tree.h,v 1.18 1997/06/09 17:28:14 roberto Exp $ */ #ifndef tree_h @@ -14,8 +14,15 @@ typedef struct TaggedString { - Word varindex; /* != NOT_USED if this is a symbol */ - Word constindex; /* != NOT_USED if this is a constant */ + int tag; /* if != LUA_T_STRING, this is a userdata */ + struct TaggedString *next; + union { + struct { + Word varindex; /* != NOT_USED if this is a symbol */ + Word constindex; /* != NOT_USED if this is a constant */ + } s; + void *v; /* if this is a userdata, here is its value */ + } u; unsigned long hash; /* 0 if not initialized */ int marked; /* for garbage collection; never collect (nor change) if > 1 */ char str[1]; /* \0 byte already reserved */ @@ -23,6 +30,9 @@ typedef struct TaggedString TaggedString *lua_createstring (char *str); -Long lua_strcollector (void); +TaggedString *luaI_createudata (void *udata, int tag); +TaggedString *luaI_strcollector (long *cont); +void luaI_strfree (TaggedString *l); +void luaI_strcallIM (TaggedString *l); #endif diff --git a/src/undump.c b/src/undump.c index 2e6ee07f..1a00ef7f 100644 --- a/src/undump.c +++ b/src/undump.c @@ -3,33 +3,28 @@ ** load bytecodes from files */ -char* rcs_undump="$Id: undump.c,v 1.21 1996/11/18 11:18:29 lhf Exp $"; +char* rcs_undump="$Id: undump.c,v 1.24 1997/06/17 18:19:17 roberto Exp $"; #include <stdio.h> #include <string.h> +#include "auxlib.h" #include "opcode.h" -#include "mem.h" +#include "luamem.h" #include "table.h" #include "undump.h" +#include "zio.h" static int swapword=0; static int swapfloat=0; static TFunc* Main=NULL; /* functions in a chunk */ static TFunc* lastF=NULL; -static void warn(char* s) /* TODO: remove */ -{ -#if 0 - fprintf(stderr,"undump: %s\n",s); -#endif -} - static void FixCode(Byte* code, Byte* end) /* swap words */ { Byte* p; for (p=code; p!=end;) { - OpCode op=(OpCode)*p; + int op=*p; switch (op) { case PUSHNIL: @@ -83,6 +78,8 @@ static void FixCode(Byte* code, Byte* end) /* swap words */ case STORELIST0: case ADJUST: case RETCODE: + case VARARGS: + case STOREMAP: p+=2; break; case STORELIST: @@ -132,7 +129,8 @@ static void FixCode(Byte* code, Byte* end) /* swap words */ break; } default: - lua_error("corrupt binary file"); + luaL_verror("corrupt binary file: bad opcode %d at %d\n", + op,(int)(p-code)); break; } } @@ -150,149 +148,152 @@ static void Unthread(Byte* code, int i, int v) } } -static int LoadWord(FILE* D) +static int LoadWord(ZIO* Z) { Word w; - fread(&w,sizeof(w),1,D); + zread(Z,&w,sizeof(w)); if (swapword) { - Byte* p=(Byte*)&w; /* TODO: need union? */ + Byte* p=(Byte*)&w; Byte t; t=p[0]; p[0]=p[1]; p[1]=t; } return w; } -static int LoadSize(FILE* D) +static int LoadSize(ZIO* Z) { - Word hi=LoadWord(D); - Word lo=LoadWord(D); + Word hi=LoadWord(Z); + Word lo=LoadWord(Z); int s=(hi<<16)|lo; if ((Word)s != s) lua_error("code too long"); return s; } -static void* LoadBlock(int size, FILE* D) +static void* LoadBlock(int size, ZIO* Z) { void* b=luaI_malloc(size); - fread(b,size,1,D); + zread(Z,b,size); return b; } -static char* LoadString(FILE* D) +static char* LoadString(ZIO* Z) { - int size=LoadWord(D); + int size=LoadWord(Z); char *b=luaI_buffer(size); - fread(b,size,1,D); + zread(Z,b,size); return b; } -static char* LoadNewString(FILE* D) +static char* LoadNewString(ZIO* Z) { - return LoadBlock(LoadWord(D),D); + return LoadBlock(LoadWord(Z),Z); } -static void LoadFunction(FILE* D) +static void LoadFunction(ZIO* Z) { TFunc* tf=new(TFunc); tf->next=NULL; tf->locvars=NULL; - tf->size=LoadSize(D); - tf->lineDefined=LoadWord(D); + tf->size=LoadSize(Z); + tf->lineDefined=LoadWord(Z); if (IsMain(tf)) /* new main */ { - tf->fileName=LoadNewString(D); + tf->fileName=LoadNewString(Z); Main=lastF=tf; } else /* fix PUSHFUNCTION */ { - tf->marked=LoadWord(D); + tf->marked=LoadWord(Z); tf->fileName=Main->fileName; memcpy(Main->code+tf->marked,&tf,sizeof(tf)); lastF=lastF->next=tf; } - tf->code=LoadBlock(tf->size,D); + tf->code=LoadBlock(tf->size,Z); if (swapword || swapfloat) FixCode(tf->code,tf->code+tf->size); while (1) /* unthread */ { - int c=getc(D); + int c=zgetc(Z); if (c==ID_VAR) /* global var */ { - int i=LoadWord(D); - char* s=LoadString(D); + int i=LoadWord(Z); + char* s=LoadString(Z); int v=luaI_findsymbolbyname(s); Unthread(tf->code,i,v); } else if (c==ID_STR) /* constant string */ { - int i=LoadWord(D); - char* s=LoadString(D); + int i=LoadWord(Z); + char* s=LoadString(Z); int v=luaI_findconstantbyname(s); Unthread(tf->code,i,v); } else { - ungetc(c,D); + zungetc(Z); break; } } } -static void LoadSignature(FILE* D) +static void LoadSignature(ZIO* Z) { char* s=SIGNATURE; - while (*s!=0 && getc(D)==*s) + while (*s!=0 && zgetc(Z)==*s) ++s; - if (*s!=0) lua_error("bad signature"); + if (*s!=0) lua_error("cannot load binary file: bad signature"); } -static void LoadHeader(FILE* D) /* TODO: error handling */ +static void LoadHeader(ZIO* Z) { Word w,tw=TEST_WORD; float f,tf=TEST_FLOAT; int version; - LoadSignature(D); - version=getc(D); + LoadSignature(Z); + version=zgetc(Z); if (version>0x23) /* after 2.5 */ { - int oldsizeofW=getc(D); - int oldsizeofF=getc(D); - int oldsizeofP=getc(D); + int oldsizeofW=zgetc(Z); + int oldsizeofF=zgetc(Z); + int oldsizeofP=zgetc(Z); if (oldsizeofW!=2) - lua_error("cannot load binary file created on machine with sizeof(Word)!=2"); + luaL_verror( + "cannot load binary file created on machine with sizeof(Word)=%d; " + "expected 2",oldsizeofW); if (oldsizeofF!=4) - lua_error("cannot load binary file created on machine with sizeof(float)!=4. not an IEEE machine?"); - if (oldsizeofP!=sizeof(TFunc*)) /* TODO: pack */ - lua_error("cannot load binary file: different pointer sizes"); + luaL_verror( + "cannot load binary file created on machine with sizeof(float)=%d; " + "expected 4\nnot an IEEE machine?",oldsizeofF); + if (oldsizeofP!=sizeof(TFunc*)) /* TODO: pack? */ + luaL_verror( + "cannot load binary file created on machine with sizeof(TFunc*)=%d; " + "expected %d",oldsizeofP,(int)sizeof(TFunc*)); } - fread(&w,sizeof(w),1,D); /* test word */ + zread(Z,&w,sizeof(w)); /* test word */ if (w!=tw) { swapword=1; - warn("different byte order"); } - fread(&f,sizeof(f),1,D); /* test float */ + zread(Z,&f,sizeof(f)); /* test float */ if (f!=tf) { - Byte* p=(Byte*)&f; /* TODO: need union? */ + Byte* p=(Byte*)&f; Byte t; swapfloat=1; t=p[0]; p[0]=p[3]; p[3]=t; t=p[1]; p[1]=p[2]; p[2]=t; if (f!=tf) /* TODO: try another perm? */ - lua_error("different float representation"); - else - warn("different byte order in floats"); + lua_error("cannot load binary file: unknown float representation"); } } -static void LoadChunk(FILE* D) +static void LoadChunk(ZIO* Z) { - LoadHeader(D); + LoadHeader(Z); while (1) { - int c=getc(D); - if (c==ID_FUN) LoadFunction(D); else { ungetc(c,D); break; } + int c=zgetc(Z); + if (c==ID_FUN) LoadFunction(Z); else { zungetc(Z); break; } } } @@ -300,30 +301,26 @@ static void LoadChunk(FILE* D) ** load one chunk from a file. ** return list of functions found, headed by main, or NULL at EOF. */ -TFunc* luaI_undump1(FILE* D) +TFunc* luaI_undump1(ZIO* Z) { - while (1) + int c=zgetc(Z); + if (c==ID_CHUNK) { - int c=getc(D); - if (c==ID_CHUNK) - { - LoadChunk(D); - return Main; - } - else if (c==EOF) - return NULL; - else - lua_error("not a lua binary file"); + LoadChunk(Z); + return Main; } + else if (c!=EOZ) + lua_error("not a lua binary file"); + return NULL; } /* ** load and run all chunks in a file */ -int luaI_undump(FILE* D) +int luaI_undump(ZIO* Z) { TFunc* m; - while ((m=luaI_undump1(D))) + while ((m=luaI_undump1(Z))) { int status=luaI_dorun(m); luaI_freefunc(m); diff --git a/src/undump.h b/src/undump.h index 8d757e36..39373583 100644 --- a/src/undump.h +++ b/src/undump.h @@ -1,10 +1,14 @@ /* ** undump.h ** definitions for lua decompiler -** $Id: undump.h,v 1.3 1996/11/14 11:44:34 lhf Exp $ +** $Id: undump.h,v 1.6 1997/06/17 18:19:17 roberto Exp $ */ +#ifndef undump_h +#define undump_h + #include "func.h" +#include "zio.h" #define IsMain(f) (f->lineDefined==0) @@ -15,9 +19,12 @@ #define ID_VAR 'V' #define ID_STR 'S' #define SIGNATURE "Lua" -#define VERSION 0x25 /* 2.5 */ +#define VERSION 0x25 /* last format change was in 2.5 */ #define TEST_WORD 0x1234 /* a word for testing byte ordering */ #define TEST_FLOAT 0.123456789e-23 /* a float for testing representation */ -TFunc* luaI_undump1(FILE* D); /* load one chunk */ -int luaI_undump(FILE* D); /* load all chunks */ + +TFunc* luaI_undump1(ZIO* Z); +int luaI_undump(ZIO* Z); /* load all chunks */ + +#endif diff --git a/src/zio.c b/src/zio.c new file mode 100644 index 00000000..2af49f42 --- /dev/null +++ b/src/zio.c @@ -0,0 +1,79 @@ +/* +* zio.c +* a generic input stream interface +* $Id: zio.c,v 1.2 1997/06/20 19:25:54 roberto Exp $ +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "zio.h" + + +/* ----------------------------------------------------- memory buffers --- */ + +static int zmfilbuf(ZIO* z) +{ + return EOZ; +} + +ZIO* zmopen(ZIO* z, char* b, int size) +{ + if (b==NULL) return NULL; + z->n=size; + z->p= (unsigned char *)b; + z->filbuf=zmfilbuf; + z->u=NULL; + return z; +} + +/* ------------------------------------------------------------ strings --- */ + +ZIO* zsopen(ZIO* z, char* s) +{ + if (s==NULL) return NULL; + return zmopen(z,s,strlen(s)); +} + +/* -------------------------------------------------------------- FILEs --- */ + +static int zffilbuf(ZIO* z) +{ + int n=fread(z->buffer,1,ZBSIZE,z->u); + if (n==0) return EOZ; + z->n=n-1; + z->p=z->buffer; + return *(z->p++); +} + + +ZIO* zFopen(ZIO* z, FILE* f) +{ + if (f==NULL) return NULL; + z->n=0; + z->p=z->buffer; + z->filbuf=zffilbuf; + z->u=f; + return z; +} + + +/* --------------------------------------------------------------- read --- */ +int zread(ZIO *z, void *b, int n) +{ + while (n) { + int m; + if (z->n == 0) { + if (z->filbuf(z) == EOZ) + return n; /* retorna quantos faltaram ler */ + zungetc(z); /* poe o resultado de filbuf no buffer */ + } + m = (n <= z->n) ? n : z->n; /* minimo de n e z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; +} diff --git a/src/zio.h b/src/zio.h new file mode 100644 index 00000000..f0f36404 --- /dev/null +++ b/src/zio.h @@ -0,0 +1,48 @@ +/* +* zio.h +* a generic input stream interface +* $Id: zio.h,v 1.5 1997/06/20 19:25:54 roberto Exp $ +*/ + +#ifndef zio_h +#define zio_h + +#include <stdio.h> + + + +/* For Lua only */ +#define zFopen luaZ_Fopen +#define zsopen luaZ_sopen +#define zmopen luaZ_mopen +#define zread luaZ_read + +#define EOZ (-1) /* end of stream */ + +typedef struct zio ZIO; + +ZIO* zFopen(ZIO* z, FILE* f); /* open FILEs */ +ZIO* zsopen(ZIO* z, char* s); /* string */ +ZIO* zmopen(ZIO* z, char* b, int size); /* memory */ + +int zread(ZIO* z, void* b, int n); /* read next n bytes */ + +#define zgetc(z) (--(z)->n>=0 ? ((int)*(z)->p++): (z)->filbuf(z)) +#define zungetc(z) (++(z)->n,--(z)->p) + + + +/* --------- Private Part ------------------ */ + +#define ZBSIZE 256 /* buffer size */ + +struct zio { + int n; /* bytes still unread */ + unsigned char* p; /* current position in buffer */ + int (*filbuf)(ZIO* z); + void* u; /* additional data */ + unsigned char buffer[ZBSIZE]; /* buffer */ +}; + + +#endif |