commit 1444d28476af70bc51c4fdba71deb669f41c77a3
parent 2de803c250de373186afbbea0a5978f54c52850c
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 19 Mar 1997 16:40:50 -0300
first full implementation of internal methods
Diffstat:
M | fallback.c | | | 369 | ++++++++++++++++++++++++++++++++++++++++++++++++------------------------------- |
M | fallback.h | | | 37 | +++++++++++++++++++------------------ |
M | hash.c | | | 9 | ++++----- |
M | hash.h | | | 3 | ++- |
M | inout.c | | | 4 | +++- |
M | lua.h | | | 20 | +++++++------------- |
M | opcode.c | | | 161 | +++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------- |
M | opcode.h | | | 22 | ++++++++++++---------- |
M | table.c | | | 4 | +++- |
M | tree.c | | | 23 | ++++++++++++++++++++++- |
M | tree.h | | | 3 | ++- |
11 files changed, 404 insertions(+), 251 deletions(-)
diff --git a/fallback.c b/fallback.c
@@ -3,11 +3,12 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_fallback="$Id: fallback.c,v 1.26 1997/02/26 17:38:41 roberto Unstable roberto $";
+char *rcs_fallback="$Id: fallback.c,v 1.27 1997/03/11 18:44:28 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
+#include "auxlib.h"
#include "mem.h"
#include "fallback.h"
#include "opcode.h"
@@ -17,105 +18,6 @@ char *rcs_fallback="$Id: fallback.c,v 1.26 1997/02/26 17:38:41 roberto Unstable
#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[] = {
-{"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 */
-{"index", {LUA_T_CFUNCTION, {indexFB}}, 2, 1},
-{"error", {LUA_T_CFUNCTION, {errorFB}}, 1, 0}
-};
-
-#define N_FB (sizeof(luaI_fallBacks)/sizeof(struct FB))
-
-static int luaI_findevent (char *name)
-{
- int i;
- for (i=0; i<N_FB; i++)
- if (strcmp(luaI_fallBacks[i].kind, name) == 0)
- return i;
- /* name not found */
- lua_error("invalid event name");
- return 0; /* to avoid warnings */
-}
-
-
-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'");
- i = luaI_findevent(name);
- luaI_pushobject(&luaI_fallBacks[i].function);
- luaI_fallBacks[i].function = *luaI_Address(func);
-}
-
-
-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");
-}
/* -------------------------------------------
@@ -187,50 +89,127 @@ void luaI_invalidaterefs (void)
refArray[i].status = COLLECTED;
}
-char *luaI_travfallbacks (int (*fn)(Object *))
+
+/* -------------------------------------------
+* Internal Methods
+*/
+
+char *eventname[] = {
+ "gettable", /* IM_GETTABLE */
+ "arith", /* IM_ARITH */
+ "order", /* IM_ORDER */
+ "concat", /* IM_CONCAT */
+ "settable", /* IM_SETTABLE */
+ "gc", /* IM_GC */
+ "function", /* IM_FUNCTION */
+ "index", /* IM_INDEX */
+ NULL
+};
+
+
+char *geventname[] = {
+ "error", /* GIM_ERROR */
+ "getglobal", /* GIM_GETGLOBAL */
+ "setglobal", /* GIM_SETGLOBAL */
+ NULL
+};
+
+static int luaI_findevent (char *name, char *list[])
{
int i;
- for (i=0; i<N_FB; i++)
- if (fn(&luaI_fallBacks[i].function))
- return luaI_fallBacks[i].kind;
- return NULL;
+ for (i=0; list[i]; i++)
+ if (strcmp(list[i], name) == 0)
+ return i;
+ /* name not found */
+ return -1;
}
+static int luaI_checkevent (char *name, char *list[])
+{
+ int e = luaI_findevent(name, list);
+ if (e < 0)
+ lua_error("invalid event name");
+ return e;
+}
-/* -------------------------------------------
-* Internal Methods
-*/
-#define BASE_TAG 1000
static struct IM {
lua_Type tp;
- Object int_method[FB_N];
- } *luaI_IMtable = NULL;
+ Object int_method[IM_N];
+} *luaI_IMtable = NULL;
+
static int IMtable_size = 0;
-static int last_tag = BASE_TAG-1;
+static int last_tag = LUA_T_NIL;
+
+static struct {
+ lua_Type t;
+ int event;
+} exceptions[] = { /* list of events that cannot be modified */
+ {LUA_T_NUMBER, IM_ARITH},
+ {LUA_T_NUMBER, IM_ORDER},
+ {LUA_T_NUMBER, IM_GC},
+ {LUA_T_STRING, IM_ARITH},
+ {LUA_T_STRING, IM_ORDER},
+ {LUA_T_STRING, IM_CONCAT},
+ {LUA_T_STRING, IM_GC},
+ {LUA_T_ARRAY, IM_GETTABLE},
+ {LUA_T_ARRAY, IM_SETTABLE},
+ {LUA_T_FUNCTION, IM_FUNCTION},
+ {LUA_T_FUNCTION, IM_GC},
+ {LUA_T_CFUNCTION, IM_FUNCTION},
+ {LUA_T_CFUNCTION, IM_GC},
+ {LUA_T_NIL, 0} /* flag end of list */
+};
-int lua_newtag (char *t)
+
+static int validevent (int t, int event)
+{
+ int i;
+ if (t == LUA_T_NIL) /* cannot modify any event for nil */
+ return 0;
+ for (i=0; exceptions[i].t != LUA_T_NIL; i++)
+ if (exceptions[i].t == t && exceptions[i].event == event)
+ return 0;
+ return 1;
+}
+
+static void init_entry (int tag)
{
int i;
- ++last_tag;
- if ((last_tag-BASE_TAG) >= IMtable_size)
+ for (i=0; i<IM_N; i++)
+ luaI_IMtable[-tag].int_method[i].ttype = LUA_T_NIL;
+}
+
+void luaI_initfallbacks (void)
+{
+ int i;
+ IMtable_size = NUM_TYPES+10;
+ luaI_IMtable = newvector(IMtable_size, struct IM);
+ for (i=LUA_T_NIL; i<=LUA_T_USERDATA; i++) {
+ luaI_IMtable[-i].tp = (lua_Type)i;
+ init_entry(i);
+ }
+}
+
+int lua_newtag (char *t)
+{
+ --last_tag;
+ if ((-last_tag) >= IMtable_size)
IMtable_size = growvector(&luaI_IMtable, IMtable_size,
struct IM, memEM, MAX_INT);
if (strcmp(t, "table") == 0)
- luaI_IMtable[last_tag-BASE_TAG].tp = LUA_T_ARRAY;
+ luaI_IMtable[-last_tag].tp = LUA_T_ARRAY;
else if (strcmp(t, "userdata") == 0)
- luaI_IMtable[last_tag-BASE_TAG].tp = LUA_T_USERDATA;
+ luaI_IMtable[-last_tag].tp = LUA_T_USERDATA;
else
lua_error("invalid type for new tag");
- for (i=0; i<FB_N; i++)
- luaI_IMtable[last_tag-BASE_TAG].int_method[i].ttype = LUA_T_NIL;
+ init_entry(last_tag);
return last_tag;
}
-static int validtag (int tag)
-{
- return (BASE_TAG <= tag && tag <= last_tag);
-}
+
+#define validtag(tag) (last_tag <= (tag) && (tag) <= 0)
+
static void checktag (int tag)
{
@@ -238,10 +217,18 @@ static void checktag (int tag)
lua_error("invalid tag");
}
+lua_Type luaI_typetag (int tag)
+{
+ if (tag >= 0) return LUA_T_USERDATA;
+ else {
+ checktag(tag);
+ return luaI_IMtable[-tag].tp;
+ }
+}
+
void luaI_settag (int tag, Object *o)
{
- checktag(tag);
- if (ttype(o) != luaI_IMtable[tag-BASE_TAG].tp)
+ if (ttype(o) != luaI_typetag(tag))
lua_error("Tag is not compatible with this type");
if (o->ttype == LUA_T_ARRAY)
o->value.a->htag = tag;
@@ -261,29 +248,123 @@ int luaI_tag (Object *o)
Object *luaI_getim (int tag, int event)
{
- if (tag == 0)
- return &luaI_fallBacks[event].function;
- else if (validtag(tag)) {
- Object *func = &luaI_IMtable[tag-BASE_TAG].int_method[event];
- if (func->ttype == LUA_T_NIL)
- return NULL;
- else
- return func;
- }
- else return NULL;
+ if (tag > LUA_T_USERDATA)
+ tag = LUA_T_USERDATA; /* default for non-registered tags */
+ return &luaI_IMtable[-tag].int_method[event];
+}
+
+Object *luaI_getimbyObj (Object *o, int event)
+{
+ return luaI_getim(luaI_tag(o), event);
}
void luaI_setintmethod (void)
{
- lua_Object tag = lua_getparam(1);
- lua_Object event = lua_getparam(2);
+ int t = (int)luaL_check_number(1, "setintmethod");
+ int e = luaI_checkevent(luaL_check_string(2, "setintmethod"), eventname);
lua_Object func = lua_getparam(3);
- if (!(lua_isnumber(tag) && lua_isstring(event) && lua_isfunction(func)))
- lua_error("incorrect arguments to function `setintmethod'");
- else {
- int i = luaI_findevent(lua_getstring(event));
- int t = lua_getnumber(tag);
- checktag(t);
- luaI_IMtable[t-BASE_TAG].int_method[i] = *luaI_Address(func);
+ if (!validevent(t, e))
+ lua_error("cannot change this internal method");
+ luaL_arg_check(lua_isnil(func) || lua_isfunction(func), "setintmethod",
+ 3, "function expected");
+ checktag(t);
+ luaI_IMtable[-t].int_method[e] = *luaI_Address(func);
+}
+
+static Object gmethod[GIM_N] = {
+ {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}, {LUA_T_NIL, {NULL}}
+};
+
+Object *luaI_getgim (int event)
+{
+ return &gmethod[event];
+}
+
+void luaI_setglobalmethod (void)
+{
+ int e = luaI_checkevent(luaL_check_string(1, "setintmethod"), geventname);
+ lua_Object func = lua_getparam(2);
+ luaL_arg_check(lua_isnil(func) || lua_isfunction(func), "setintmethod",
+ 2, "function expected");
+ gmethod[e] = *luaI_Address(func);
+}
+
+char *luaI_travfallbacks (int (*fn)(Object *))
+{ /* ??????????
+ int i;
+ for (i=0; i<N_FB; i++)
+ if (fn(&luaI_fallBacks[i].function))
+ return luaI_fallBacks[i].kind; */
+ return NULL;
+}
+
+
+/*
+* ===================================================================
+* compatibility with old fallback system
+*/
+
+
+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");
+}
+
+
+void luaI_setfallback (void)
+{
+ int e;
+ char *name = luaL_check_string(1, "setfallback");
+ lua_Object func = lua_getparam(2);
+ luaL_arg_check(lua_isfunction(func), "setfallback", 2, "function expected");
+ e = luaI_findevent(name, geventname);
+ if (e >= 0) { /* global event */
+ switch (e) {
+ case GIM_ERROR:
+ gmethod[e] = *luaI_Address(func);
+ lua_pushcfunction(errorFB);
+ break;
+ case GIM_GETGLOBAL: /* goes through */
+ case GIM_SETGLOBAL:
+ gmethod[e] = *luaI_Address(func);
+ lua_pushcfunction(nilFB);
+ break;
+ default: lua_error("internal error");
+ }
+ }
+ else { /* tagged name? */
+ int t;
+ Object oldfunc;
+ e = luaI_checkevent(name, eventname);
+ oldfunc = luaI_IMtable[LUA_T_USERDATA].int_method[e];
+ for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++)
+ if (validevent(t, e))
+ luaI_IMtable[-t].int_method[e] = *luaI_Address(func);
+ if (oldfunc.ttype != LUA_T_NIL)
+ luaI_pushobject(&oldfunc);
+ else {
+ switch (e) {
+ case IM_GC: case IM_INDEX:
+ lua_pushcfunction(nilFB);
+ break;
+ default:
+ lua_pushcfunction(typeFB);
+ break;
+ }
+ }
}
}
+
diff --git a/fallback.h b/fallback.h
@@ -1,5 +1,5 @@
/*
-** $Id: fallback.h,v 1.13 1996/04/25 14:10:00 roberto Exp roberto $
+** $Id: fallback.h,v 1.14 1997/02/26 17:38:41 roberto Unstable roberto $
*/
#ifndef fallback_h
@@ -8,24 +8,20 @@
#include "lua.h"
#include "opcode.h"
-extern struct FB {
- char *kind;
- Object function;
- int nParams;
- int nResults;
-} luaI_fallBacks[];
+#define IM_GETTABLE 0
+#define IM_ARITH 1
+#define IM_ORDER 2
+#define IM_CONCAT 3
+#define IM_SETTABLE 4
+#define IM_GC 5
+#define IM_FUNCTION 6
+#define IM_INDEX 7
+#define IM_N 8
-#define FB_GETTABLE 0
-#define FB_ARITH 1
-#define FB_ORDER 2
-#define FB_CONCAT 3
-#define FB_SETTABLE 4
-#define FB_GC 5
-#define FB_FUNCTION 6
-#define FB_GETGLOBAL 7
-#define FB_INDEX 8
-#define FB_ERROR 9
-#define FB_N 10
+#define GIM_ERROR 0
+#define GIM_GETGLOBAL 1
+#define GIM_SETGLOBAL 2
+#define GIM_N 3
void luaI_setfallback (void);
int luaI_ref (Object *object, int lock);
@@ -35,9 +31,14 @@ void luaI_invalidaterefs (void);
char *luaI_travfallbacks (int (*fn)(Object *));
void luaI_settag (int tag, Object *o);
+lua_Type luaI_typetag (int tag);
Object *luaI_getim (int tag, int event);
+Object *luaI_getgim (int event);
+Object *luaI_getimbyObj (Object *o, int event);
int luaI_tag (Object *o);
void luaI_setintmethod (void);
+void luaI_setglobalmethod (void);
+void luaI_initfallbacks (void);
#endif
diff --git a/hash.c b/hash.c
@@ -3,7 +3,7 @@
** hash manager for lua
*/
-char *rcs_hash="$Id: hash.c,v 2.34 1997/02/26 17:38:41 roberto Unstable roberto $";
+char *rcs_hash="$Id: hash.c,v 2.35 1997/03/11 18:44:28 roberto Exp roberto $";
#include "mem.h"
@@ -159,7 +159,7 @@ void lua_hashmark (Hash *h)
}
-static void call_fallbacks (void)
+void luaI_hashcallIM (void)
{
Hash *curr_array;
Object t;
@@ -168,10 +168,10 @@ static void call_fallbacks (void)
if (markarray(curr_array) != 1)
{
avalue(&t) = curr_array;
- luaI_gcFB(&t);
+ luaI_gcIM(&t);
}
ttype(&t) = LUA_T_NIL;
- luaI_gcFB(&t); /* end of list */
+ luaI_gcIM(&t); /* end of list */
}
@@ -183,7 +183,6 @@ Long lua_hashcollector (void)
{
Hash *curr_array = listhead, *prev = NULL;
Long counter = 0;
- call_fallbacks();
while (curr_array != NULL)
{
Hash *next = curr_array->next;
diff --git a/hash.h b/hash.h
@@ -1,7 +1,7 @@
/*
** hash.h
** hash manager for lua
-** $Id: hash.h,v 2.12 1996/05/06 14:30:27 roberto Exp roberto $
+** $Id: hash.h,v 2.13 1997/02/26 17:38:41 roberto Unstable roberto $
*/
#ifndef hash_h
@@ -30,6 +30,7 @@ int luaI_redimension (int nhash);
Hash *lua_createarray (int nhash);
void lua_hashmark (Hash *h);
Long lua_hashcollector (void);
+void luaI_hashcallIM (void);
Object *lua_hashget (Hash *t, Object *ref);
Object *lua_hashdefine (Hash *t, Object *ref);
void lua_next (void);
diff --git a/inout.c b/inout.c
@@ -5,11 +5,12 @@
** Also provides some predefined lua functions.
*/
-char *rcs_inout="$Id: inout.c,v 2.45 1997/03/11 18:44:28 roberto Exp roberto $";
+char *rcs_inout="$Id: inout.c,v 2.46 1997/03/17 17:01:10 roberto Exp roberto $";
#include <stdio.h>
#include <string.h>
+#include "auxlib.h"
#include "lex.h"
#include "opcode.h"
#include "inout.h"
@@ -322,6 +323,7 @@ static struct {
{"print", luaI_print},
{"setfallback", luaI_setfallback},
{"setintmethod", luaI_setintmethod},
+ {"setglobalmethod", luaI_setglobalmethod},
{"setglobal", luaI_setglobal},
{"tonumber", lua_obj2number},
{"tostring", luaI_tostring},
diff --git a/lua.h b/lua.h
@@ -2,7 +2,7 @@
** LUA - Linguagem para Usuarios de Aplicacao
** Grupo de Tecnologia em Computacao Grafica
** TeCGraf - PUC-Rio
-** $Id: lua.h,v 3.35 1997/02/26 17:38:41 roberto Unstable roberto $
+** $Id: lua.h,v 3.36 1997/03/17 17:01:10 roberto Exp roberto $
*/
@@ -21,6 +21,7 @@ typedef unsigned int lua_Object;
lua_Object lua_setfallback (char *event, lua_CFunction fallback);
void lua_setintmethod (int tag, char *event, lua_CFunction method);
+void lua_setglobalmethod (char *event, lua_CFunction method);
int lua_newtag (char *t);
void lua_settag (int tag); /* In: object */
@@ -36,8 +37,9 @@ int lua_call (char *funcname);
void lua_beginblock (void);
void lua_endblock (void);
-lua_Object lua_getparam (int number);
-#define lua_getresult(_) lua_getparam(_)
+lua_Object lua_lua2C (int number);
+#define lua_getparam(_) lua_lua2C(_)
+#define lua_getresult(_) lua_lua2C(_)
int lua_isnil (lua_Object object);
int lua_istable (lua_Object object);
@@ -62,7 +64,9 @@ void lua_pushusertag (void *u, int tag);
void lua_pushobject (lua_Object object);
lua_Object lua_getglobal (char *name);
+lua_Object lua_basicgetglobal (char *name);
void lua_storeglobal (char *name); /* In: value */
+void lua_basicstoreglobal (char *name); /* In: value */
void lua_storesubscript (void); /* In: table, index, value */
void lua_basicstoreindex (void); /* In: table, index, value */
@@ -91,16 +95,6 @@ lua_Object lua_createtable (void);
/* =============================================================== */
-/* Auxiliar functions for libraries */
-
-void luaL_arg_check(int cond, char *funcname, int numarg, char *extramsg);
-char *luaL_check_string (int numArg, char *funcname);
-char *luaL_opt_string (int numArg, char *def, char *funcname);
-double luaL_check_number (int numArg, char *funcname);
-double luaL_opt_number (int numArg, double def, char *funcname);
-
-
-/* =============================================================== */
/* for compatibility with old versions. Avoid using these macros */
#define lua_type(o) (lua_tag(o))
diff --git a/opcode.c b/opcode.c
@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_opcode="$Id: opcode.c,v 3.83 1997/03/06 17:30:55 roberto Exp roberto $";
+char *rcs_opcode="$Id: opcode.c,v 3.84 1997/03/11 18:44:28 roberto Exp roberto $";
#include <setjmp.h>
#include <stdio.h>
@@ -268,15 +268,6 @@ static void callIM (Object *f, int nParams, int nResults)
do_call((top-stack)-nParams, nResults);
}
-/*
-** Call the specified fallback, putting it on the stack below its arguments
-*/
-static void callFB (int fb)
-{
- callIM(&luaI_fallBacks[fb].function, luaI_fallBacks[fb].nParams,
- luaI_fallBacks[fb].nResults);
-}
-
/*
** Call a function (C or Lua). The parameters must be on the stack,
@@ -289,21 +280,21 @@ static void do_call (StkId base, int nResults)
StkId firstResult;
Object *func = stack+base-1;
int i;
- if (ttype(func) == LUA_T_CFUNCTION)
- {
+ if (ttype(func) == LUA_T_CFUNCTION) {
ttype(func) = LUA_T_CMARK;
firstResult = callC(fvalue(func), base);
}
- else if (ttype(func) == LUA_T_FUNCTION)
- {
+ 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 fallback for invalid functions */
+ Object *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;
}
@@ -326,15 +317,14 @@ static void do_call (StkId base, int nResults)
static void pushsubscript (void)
{
int tg = luaI_tag(top-2);
- Object *im = luaI_getim(tg, FB_GETTABLE);
- if (ttype(top-2) == LUA_T_ARRAY && im == NULL) {
+ Object *im = luaI_getim(tg, IM_GETTABLE);
+ if (ttype(top-2) == LUA_T_ARRAY && ttype(im) == LUA_T_NIL) {
Object *h = lua_hashget(avalue(top-2), top-1);
if (h != NULL && ttype(h) != LUA_T_NIL) {
--top;
*(top-1) = *h;
}
- else if (tg == LUA_T_ARRAY &&
- (im=luaI_getim(0, FB_INDEX)) != NULL)
+ else if (ttype(im=luaI_getim(tg, IM_INDEX)) != LUA_T_NIL)
callIM(im, 2, 1);
else {
--top;
@@ -376,14 +366,14 @@ lua_Object lua_basicindex (void)
*/
static void storesubscript (Object *t, int mode)
{
- Object *im = (mode == 0) ? NULL : luaI_getim(luaI_tag(t), FB_SETTABLE);
- if (ttype(t) == LUA_T_ARRAY && im == NULL) {
+ Object *im = (mode == 0) ? NULL : luaI_getimbyObj(t, IM_SETTABLE);
+ if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) {
Object *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) {
+ if (im && ttype(im) != LUA_T_NIL) {
if (mode == 2) {
lua_checkstack(top+2);
*(top+1) = *(top-1);
@@ -403,11 +393,13 @@ static void getglobal (Word n)
{
*top = lua_table[n].object;
incr_top;
- if (ttype(top-1) == LUA_T_NIL)
- { /* must call getglobal fallback */
- ttype(top-1) = LUA_T_STRING;
- tsvalue(top-1) = lua_table[n].varname;
- callFB(FB_GETGLOBAL);
+ if (ttype(top-1) == LUA_T_NIL) { /* check i.m. */
+ Object *im = luaI_getgim(GIM_GETGLOBAL);
+ if (ttype(im) != LUA_T_NIL) {
+ ttype(top-1) = LUA_T_STRING;
+ tsvalue(top-1) = lua_table[n].varname;
+ callIM(im, 1, 1);
+ }
}
}
@@ -428,8 +420,13 @@ void lua_travstack (int (*fn)(Object *))
static void lua_message (char *s)
{
- lua_pushstring(s);
- callFB(FB_ERROR);
+ Object *im = luaI_getgim(GIM_ERROR);
+ if (ttype(im) == LUA_T_NIL)
+ fprintf(stderr, "lua: %s\n", s);
+ else {
+ lua_pushstring(s);
+ callIM(im, 1, 0);
+ }
}
/*
@@ -659,10 +656,20 @@ void lua_setintmethod (int tag, char *event, lua_CFunction method)
{
lua_pushnumber(tag);
lua_pushstring(event);
- lua_pushcfunction (method);
+ if (method)
+ lua_pushcfunction (method);
+ else
+ lua_pushnil();
do_unprotectedrun(luaI_setintmethod, 3, 0);
}
+void lua_setglobalmethod (char *event, lua_CFunction method)
+{
+ lua_pushstring(event);
+ lua_pushcfunction (method);
+ do_unprotectedrun(luaI_setglobalmethod, 3, 0);
+}
+
/*
** API: receives on the stack the table and the index.
@@ -741,7 +748,7 @@ lua_Object lua_createtable (void)
** 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.base-CLS_current.num+number-1)) ==
@@ -874,6 +881,17 @@ lua_Object lua_getglobal (char *name)
return Ref(top-1);
}
+
+lua_Object lua_basicgetglobal (char *name)
+{
+ adjustC(0);
+ *top = lua_table[luaI_findsymbolbyname(name)].object;
+ incr_top;
+ CLS_current.base++; /* incorporate object in the stack */
+ return Ref(top-1);
+}
+
+
/*
** Store top of the stack at a global variable array field.
*/
@@ -944,7 +962,7 @@ void lua_pushbinarydata (void *buff, int size, int tag)
*/
void lua_pushusertag (void *u, int tag)
{
- if (tag < LUA_T_USERDATA)
+ if (luaI_typetag(tag) != LUA_T_USERDATA)
lua_error("invalid tag in `lua_pushusertag'");
lua_pushbinarydata(&u, sizeof(void *), tag);
}
@@ -977,18 +995,47 @@ int lua_tag (lua_Object o)
}
-void luaI_gcFB (Object *o)
+void luaI_gcIM (Object *o)
{
- *top = *o;
- incr_top;
- callFB(FB_GC);
+ Object *im = luaI_getimbyObj(o, IM_GC);
+ if (ttype(im) != LUA_T_NIL) {
+ *top = *o;
+ incr_top;
+ callIM(im, 1, 0);
+ }
}
static void call_arith (char *op)
{
+ Object *im = luaI_getimbyObj(top-2, IM_ARITH); /* try first operand */
+ if (ttype(im) == LUA_T_NIL) {
+ im = luaI_getimbyObj(top-1, IM_ARITH); /* try second operand */
+ if (ttype(im) == LUA_T_NIL) {
+ im = luaI_getim(0, IM_ARITH); /* try a 'global' i.m. */
+ if (ttype(im) == LUA_T_NIL)
+ lua_error("unexpected type at conversion to number");
+ }
+ }
lua_pushstring(op);
- callFB(FB_ARITH);
+ callIM(im, 3, 1);
+}
+
+static void concim (Object *o)
+{
+ Object *im = luaI_getimbyObj(o, IM_CONCAT);
+ if (ttype(im) == LUA_T_NIL)
+ lua_error("unexpected type at conversion to string");
+ callIM(im, 2, 1);
+}
+
+static void ordim (Object *o, char *op)
+{
+ Object *im = luaI_getimbyObj(o, IM_ORDER);
+ if (ttype(im) == LUA_T_NIL)
+ lua_error("unexpected type at comparison");
+ lua_pushstring(op);
+ callIM(im, 3, 1);
}
static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
@@ -999,10 +1046,12 @@ static void comparison (lua_Type ttype_less, lua_Type ttype_equal,
int result;
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 (tostring(l)) {
+ ordim(l, op);
+ return;
+ }
+ else if (tostring(r)) {
+ ordim(r, op);
return;
}
else
@@ -1318,17 +1367,17 @@ static StkId lua_execute (Byte *pc, StkId base)
call_arith("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: {
+ Object *l = top-2;
+ Object *r = top-1;
+ if (tostring(l)) /* first argument is not a string */
+ concim(l);
+ else if (tostring(r)) /* second argument is not a string */
+ concim(r);
+ else {
+ tsvalue(l) = lua_createstring(lua_strconc(svalue(l),svalue(r)));
+ --top;
+ }
}
break;
@@ -1356,7 +1405,7 @@ static StkId lua_execute (Byte *pc, StkId base)
}
break;
- case ONFJMP:
+ case ONFJMP:
{
Word w;
get_word(w,pc);
diff --git a/opcode.h b/opcode.h
@@ -1,6 +1,6 @@
/*
** TeCGraf - PUC-Rio
-** $Id: opcode.h,v 3.27 1997/03/06 17:30:55 roberto Exp roberto $
+** $Id: opcode.h,v 3.28 1997/03/11 18:44:28 roberto Exp roberto $
*/
#ifndef opcode_h
@@ -16,18 +16,20 @@
typedef enum
{
- LUA_T_NIL = -1,
- LUA_T_NUMBER = -2,
- LUA_T_STRING = -3,
- LUA_T_ARRAY = -4, /* array==table */
+ 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= -6,
- LUA_T_MARK = -7,
- LUA_T_CMARK = -8,
- LUA_T_LINE = -9,
+ 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
+
typedef enum {
/* name parm before after side effect
@@ -156,7 +158,7 @@ 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 luaI_gcIM (Object *o);
int luaI_dorun (TFunc *tf);
#endif
diff --git a/table.c b/table.c
@@ -3,7 +3,7 @@
** Module to control static tables
*/
-char *rcs_table="$Id: table.c,v 2.59 1997/02/26 17:38:41 roberto Unstable roberto $";
+char *rcs_table="$Id: table.c,v 2.60 1997/03/11 18:44:28 roberto Exp roberto $";
#include "mem.h"
#include "opcode.h"
@@ -168,6 +168,8 @@ Long luaI_collectgarbage (void)
lua_travsymbol(lua_markobject); /* mark symbol table objects */
luaI_travlock(lua_markobject); /* mark locked objects */
luaI_travfallbacks(lua_markobject); /* mark fallbacks */
+ luaI_hashcallIM();
+ luaI_strcallIM();
luaI_invalidaterefs();
recovered += lua_strcollector();
recovered += lua_hashcollector();
diff --git a/tree.c b/tree.c
@@ -3,7 +3,7 @@
** TecCGraf - PUC-Rio
*/
-char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp roberto $";
+char *rcs_tree="$Id: tree.c,v 1.21 1997/02/11 11:35:05 roberto Exp roberto $";
#include <string.h>
@@ -14,6 +14,7 @@ char *rcs_tree="$Id: tree.c,v 1.20 1996/03/14 15:56:26 roberto Exp roberto $";
#include "lex.h"
#include "hash.h"
#include "table.h"
+#include "fallback.h"
#define NUM_HASHS 64
@@ -45,6 +46,7 @@ static void initialize (void)
luaI_addReserved();
luaI_initsymbol();
luaI_initconstant();
+ luaI_initfallbacks();
}
@@ -120,6 +122,25 @@ TaggedString *lua_createstring (char *str)
}
+void luaI_strcallIM (void)
+{
+ int i;
+ Object o;
+ ttype(&o) = LUA_T_USERDATA;
+ for (i=0; i<NUM_HASHS; i++) {
+ stringtable *tb = &string_root[i];
+ int j;
+ for (j=0; j<tb->size; j++) {
+ TaggedString *t = tb->hash[j];
+ if (t != NULL && t->tag != LUA_T_STRING && t->marked == 0) {
+ tsvalue(&o) = t;
+ luaI_gcIM(&o);
+ }
+ }
+ }
+}
+
+
/*
** Garbage collection function.
** This function traverse the string list freeing unindexed strings
diff --git a/tree.h b/tree.h
@@ -1,7 +1,7 @@
/*
** tree.h
** TecCGraf - PUC-Rio
-** $Id: tree.h,v 1.14 1996/02/26 17:07:49 roberto Exp roberto $
+** $Id: tree.h,v 1.15 1997/02/11 11:35:05 roberto Exp roberto $
*/
#ifndef tree_h
@@ -27,5 +27,6 @@ typedef struct TaggedString
TaggedString *lua_createstring (char *str);
TaggedString *luaI_createuserdata (char *buff, long size, int tag);
Long lua_strcollector (void);
+void luaI_strcallIM (void);
#endif