diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-12-15 14:17:20 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-12-15 14:17:20 -0200 |
| commit | 45e533599f08d849951b49bcab0be4fd735a966d (patch) | |
| tree | b8e3b175989f694391dd3da4191894f5df1e7d75 | |
| parent | 94144a7821c0fa412d5d228ab5197a8ebaaa3c25 (diff) | |
| download | lua-45e533599f08d849951b49bcab0be4fd735a966d.tar.gz lua-45e533599f08d849951b49bcab0be4fd735a966d.tar.bz2 lua-45e533599f08d849951b49bcab0be4fd735a966d.zip | |
optimization: closures without upvalues don't need to be closures
| -rw-r--r-- | lbuiltin.c | 27 | ||||
| -rw-r--r-- | ldo.c | 68 | ||||
| -rw-r--r-- | ldo.h | 4 | ||||
| -rw-r--r-- | lfunc.c | 11 | ||||
| -rw-r--r-- | lfunc.h | 3 | ||||
| -rw-r--r-- | lgc.c | 18 | ||||
| -rw-r--r-- | lobject.c | 10 | ||||
| -rw-r--r-- | lobject.h | 17 | ||||
| -rw-r--r-- | ltable.c | 10 | ||||
| -rw-r--r-- | ltm.c | 11 | ||||
| -rw-r--r-- | lua.stx | 14 | ||||
| -rw-r--r-- | lvm.c | 28 | ||||
| -rw-r--r-- | lvm.h | 4 |
13 files changed, 132 insertions, 93 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbuiltin.c,v 1.15 1997/12/09 13:35:19 roberto Exp roberto $ | 2 | ** $Id: lbuiltin.c,v 1.16 1997/12/11 17:21:11 roberto Exp roberto $ |
| 3 | ** Built-in functions | 3 | ** Built-in functions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -140,10 +140,18 @@ static char *to_string (lua_Object obj) | |||
| 140 | sprintf(buff, "table: %p", (void *)o->value.a); | 140 | sprintf(buff, "table: %p", (void *)o->value.a); |
| 141 | return buff; | 141 | return buff; |
| 142 | } | 142 | } |
| 143 | case LUA_T_FUNCTION: { | 143 | case LUA_T_CLOSURE: { |
| 144 | sprintf(buff, "function: %p", (void *)o->value.cl); | 144 | sprintf(buff, "function: %p", (void *)o->value.cl); |
| 145 | return buff; | 145 | return buff; |
| 146 | } | 146 | } |
| 147 | case LUA_T_PROTO: { | ||
| 148 | sprintf(buff, "function: %p", (void *)o->value.tf); | ||
| 149 | return buff; | ||
| 150 | } | ||
| 151 | case LUA_T_CPROTO: { | ||
| 152 | sprintf(buff, "function: %p", (void *)o->value.f); | ||
| 153 | return buff; | ||
| 154 | } | ||
| 147 | case LUA_T_USERDATA: { | 155 | case LUA_T_USERDATA: { |
| 148 | sprintf(buff, "userdata: %p", o->value.ts->u.d.v); | 156 | sprintf(buff, "userdata: %p", o->value.ts->u.d.v); |
| 149 | return buff; | 157 | return buff; |
| @@ -372,6 +380,20 @@ static void mem_query (void) | |||
| 372 | } | 380 | } |
| 373 | 381 | ||
| 374 | 382 | ||
| 383 | static void countlist (void) | ||
| 384 | { | ||
| 385 | char *s = luaL_check_string(1); | ||
| 386 | GCnode *l = (s[0]=='t') ? L->roottable.next : (s[0]=='c') ? L->rootcl.next : | ||
| 387 | (s[0]=='p') ? L->rootproto.next : L->rootglobal.next; | ||
| 388 | int i=0; | ||
| 389 | while (l) { | ||
| 390 | i++; | ||
| 391 | l = l->next; | ||
| 392 | } | ||
| 393 | lua_pushnumber(i); | ||
| 394 | } | ||
| 395 | |||
| 396 | |||
| 375 | static void testC (void) | 397 | static void testC (void) |
| 376 | { | 398 | { |
| 377 | #define getnum(s) ((*s++) - '0') | 399 | #define getnum(s) ((*s++) - '0') |
| @@ -433,6 +455,7 @@ static struct luaL_reg int_funcs[] = { | |||
| 433 | #ifdef DEBUG | 455 | #ifdef DEBUG |
| 434 | {"testC", testC}, | 456 | {"testC", testC}, |
| 435 | {"totalmem", mem_query}, | 457 | {"totalmem", mem_query}, |
| 458 | {"count", countlist}, | ||
| 436 | #endif | 459 | #endif |
| 437 | {"assert", luaI_assert}, | 460 | {"assert", luaI_assert}, |
| 438 | {"call", luaI_call}, | 461 | {"call", luaI_call}, |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.c,v 1.13 1997/11/27 18:25:14 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.14 1997/12/09 13:35:19 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -44,13 +44,6 @@ static void stderrorim (void) | |||
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | static void initCfunc (TObject *o, lua_CFunction f) | ||
| 48 | { | ||
| 49 | ttype(o) = LUA_T_CPROTO; | ||
| 50 | fvalue(o) = f; | ||
| 51 | luaF_simpleclosure(o); | ||
| 52 | } | ||
| 53 | |||
| 54 | 47 | ||
| 55 | #define STACK_UNIT 128 | 48 | #define STACK_UNIT 128 |
| 56 | 49 | ||
| @@ -60,7 +53,8 @@ void luaD_init (void) | |||
| 60 | L->stack.stack = luaM_newvector(STACK_UNIT, TObject); | 53 | L->stack.stack = luaM_newvector(STACK_UNIT, TObject); |
| 61 | L->stack.top = L->stack.stack; | 54 | L->stack.top = L->stack.stack; |
| 62 | L->stack.last = L->stack.stack+(STACK_UNIT-1); | 55 | L->stack.last = L->stack.stack+(STACK_UNIT-1); |
| 63 | initCfunc(&L->errorim, stderrorim); | 56 | ttype(&L->errorim) = LUA_T_CPROTO; |
| 57 | fvalue(&L->errorim) = stderrorim; | ||
| 64 | } | 58 | } |
| 65 | 59 | ||
| 66 | 60 | ||
| @@ -122,7 +116,7 @@ void luaD_lineHook (int line) | |||
| 122 | } | 116 | } |
| 123 | 117 | ||
| 124 | 118 | ||
| 125 | void luaD_callHook (StkId base, lua_Type type, int isreturn) | 119 | void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn) |
| 126 | { | 120 | { |
| 127 | struct C_Lua_Stack oldCLS = L->Cstack; | 121 | struct C_Lua_Stack oldCLS = L->Cstack; |
| 128 | StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; | 122 | StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; |
| @@ -131,9 +125,8 @@ void luaD_callHook (StkId base, lua_Type type, int isreturn) | |||
| 131 | (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); | 125 | (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); |
| 132 | else { | 126 | else { |
| 133 | TObject *f = L->stack.stack+base-1; | 127 | TObject *f = L->stack.stack+base-1; |
| 134 | if (type == LUA_T_PROTO) | 128 | if (tf) |
| 135 | (*lua_callhook)(Ref(f), tfvalue(protovalue(f))->fileName->str, | 129 | (*lua_callhook)(Ref(f), tf->fileName->str, tf->lineDefined); |
| 136 | tfvalue(protovalue(f))->lineDefined); | ||
| 137 | else | 130 | else |
| 138 | (*lua_callhook)(Ref(f), "(C)", -1); | 131 | (*lua_callhook)(Ref(f), "(C)", -1); |
| 139 | } | 132 | } |
| @@ -147,13 +140,13 @@ void luaD_callHook (StkId base, lua_Type type, int isreturn) | |||
| 147 | ** Cstack.num is the number of arguments; Cstack.lua2C points to the | 140 | ** Cstack.num is the number of arguments; Cstack.lua2C points to the |
| 148 | ** first argument. Returns an index to the first result from C. | 141 | ** first argument. Returns an index to the first result from C. |
| 149 | */ | 142 | */ |
| 150 | static StkId callC (struct Closure *cl, StkId base) | 143 | static StkId callC (struct Closure *cl, lua_CFunction f, StkId base) |
| 151 | { | 144 | { |
| 152 | struct C_Lua_Stack *CS = &L->Cstack; | 145 | struct C_Lua_Stack *CS = &L->Cstack; |
| 153 | struct C_Lua_Stack oldCLS = *CS; | 146 | struct C_Lua_Stack oldCLS = *CS; |
| 154 | StkId firstResult; | 147 | StkId firstResult; |
| 155 | int numarg = (L->stack.top-L->stack.stack) - base; | 148 | int numarg = (L->stack.top-L->stack.stack) - base; |
| 156 | if (cl->nelems > 0) { /* are there upvalues? */ | 149 | if (cl) { /* are there upvalues? */ |
| 157 | int i; | 150 | int i; |
| 158 | luaD_checkstack(cl->nelems); | 151 | luaD_checkstack(cl->nelems); |
| 159 | for (i=1; i<=numarg; i++) /* open space */ | 152 | for (i=1; i<=numarg; i++) /* open space */ |
| @@ -167,10 +160,10 @@ static StkId callC (struct Closure *cl, StkId base) | |||
| 167 | CS->lua2C = base; | 160 | CS->lua2C = base; |
| 168 | CS->base = base+numarg; /* == top-stack */ | 161 | CS->base = base+numarg; /* == top-stack */ |
| 169 | if (lua_callhook) | 162 | if (lua_callhook) |
| 170 | luaD_callHook(base, LUA_T_CPROTO, 0); | 163 | luaD_callHook(base, NULL, 0); |
| 171 | (*(fvalue(cl->consts)))(); /* do the actual call */ | 164 | (*f)(); /* do the actual call */ |
| 172 | if (lua_callhook) /* func may have changed lua_callhook */ | 165 | if (lua_callhook) /* func may have changed lua_callhook */ |
| 173 | luaD_callHook(base, LUA_T_CPROTO, 1); | 166 | luaD_callHook(base, NULL, 1); |
| 174 | firstResult = CS->base; | 167 | firstResult = CS->base; |
| 175 | *CS = oldCLS; | 168 | *CS = oldCLS; |
| 176 | return firstResult; | 169 | return firstResult; |
| @@ -196,19 +189,32 @@ void luaD_call (StkId base, int nResults) | |||
| 196 | StkId firstResult; | 189 | StkId firstResult; |
| 197 | TObject *func = L->stack.stack+base-1; | 190 | TObject *func = L->stack.stack+base-1; |
| 198 | int i; | 191 | int i; |
| 199 | if (ttype(func) == LUA_T_FUNCTION) { | 192 | switch (ttype(func)) { |
| 200 | TObject *proto = protovalue(func); | 193 | case LUA_T_CPROTO: |
| 201 | ttype(func) = LUA_T_MARK; | 194 | ttype(func) = LUA_T_CMARK; |
| 202 | firstResult = (ttype(proto) == LUA_T_CPROTO) ? callC(clvalue(func), base) | 195 | firstResult = callC(NULL, fvalue(func), base); |
| 203 | : luaV_execute(func->value.cl, base); | 196 | break; |
| 204 | } | 197 | case LUA_T_PROTO: |
| 205 | else { /* func is not a function */ | 198 | ttype(func) = LUA_T_PMARK; |
| 206 | /* Check the tag method for invalid functions */ | 199 | firstResult = luaV_execute(NULL, tfvalue(func), base); |
| 207 | TObject *im = luaT_getimbyObj(func, IM_FUNCTION); | 200 | break; |
| 208 | if (ttype(im) == LUA_T_NIL) | 201 | case LUA_T_CLOSURE: { |
| 209 | lua_error("call expression not a function"); | 202 | Closure *c = clvalue(func); |
| 210 | luaD_callTM(im, (L->stack.top-L->stack.stack)-(base-1), nResults); | 203 | TObject *proto = &(c->consts[0]); |
| 211 | return; | 204 | ttype(func) = LUA_T_CLMARK; |
| 205 | firstResult = (ttype(proto) == LUA_T_CPROTO) ? | ||
| 206 | callC(c, fvalue(proto), base) : | ||
| 207 | luaV_execute(c, tfvalue(proto), base); | ||
| 208 | break; | ||
| 209 | } | ||
| 210 | default: { /* func is not a function */ | ||
| 211 | /* Check the tag method for invalid functions */ | ||
| 212 | TObject *im = luaT_getimbyObj(func, IM_FUNCTION); | ||
| 213 | if (ttype(im) == LUA_T_NIL) | ||
| 214 | lua_error("call expression not a function"); | ||
| 215 | luaD_callTM(im, (L->stack.top-L->stack.stack)-(base-1), nResults); | ||
| 216 | return; | ||
| 217 | } | ||
| 212 | } | 218 | } |
| 213 | /* adjust the number of results */ | 219 | /* adjust the number of results */ |
| 214 | if (nResults != MULT_RET) | 220 | if (nResults != MULT_RET) |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldo.h,v 1.2 1997/11/04 15:27:53 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 1.3 1997/11/19 17:29:23 roberto Exp roberto $ |
| 3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -34,7 +34,7 @@ void luaD_init (void); | |||
| 34 | void luaD_adjusttop (StkId newtop); | 34 | void luaD_adjusttop (StkId newtop); |
| 35 | void luaD_openstack (int nelems); | 35 | void luaD_openstack (int nelems); |
| 36 | void luaD_lineHook (int line); | 36 | void luaD_lineHook (int line); |
| 37 | void luaD_callHook (StkId base, lua_Type type, int isreturn); | 37 | void luaD_callHook (StkId base, TProtoFunc *tf, int isreturn); |
| 38 | void luaD_call (StkId base, int nResults); | 38 | void luaD_call (StkId base, int nResults); |
| 39 | void luaD_callTM (TObject *f, int nParams, int nResults); | 39 | void luaD_callTM (TObject *f, int nParams, int nResults); |
| 40 | int luaD_protectedrun (int nResults); | 40 | int luaD_protectedrun (int nResults); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 1.6 1997/11/19 17:29:23 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.7 1997/12/09 13:35:19 roberto Exp roberto $ |
| 3 | ** Auxiliar functions to manipulate prototypes and closures | 3 | ** Auxiliar functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -26,15 +26,6 @@ Closure *luaF_newclosure (int nelems) | |||
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | void luaF_simpleclosure (TObject *o) | ||
| 30 | { | ||
| 31 | Closure *c = luaF_newclosure(0); | ||
| 32 | c->consts[0] = *o; | ||
| 33 | ttype(o) = LUA_T_FUNCTION; | ||
| 34 | clvalue(o) = c; | ||
| 35 | } | ||
| 36 | |||
| 37 | |||
| 38 | TProtoFunc *luaF_newproto (void) | 29 | TProtoFunc *luaF_newproto (void) |
| 39 | { | 30 | { |
| 40 | TProtoFunc *f = luaM_new(TProtoFunc); | 31 | TProtoFunc *f = luaM_new(TProtoFunc); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.h,v 1.3 1997/10/24 17:17:24 roberto Exp roberto $ | 2 | ** $Id: lfunc.h,v 1.4 1997/11/19 17:29:23 roberto Exp roberto $ |
| 3 | ** Lua Function structures | 3 | ** Lua Function structures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -16,7 +16,6 @@ TProtoFunc *luaF_newproto (void); | |||
| 16 | Closure *luaF_newclosure (int nelems); | 16 | Closure *luaF_newclosure (int nelems); |
| 17 | void luaF_freeproto (TProtoFunc *l); | 17 | void luaF_freeproto (TProtoFunc *l); |
| 18 | void luaF_freeclosure (Closure *l); | 18 | void luaF_freeclosure (Closure *l); |
| 19 | void luaF_simpleclosure (TObject *o); | ||
| 20 | 19 | ||
| 21 | char *luaF_getlocalname (TProtoFunc *func, int local_number, int line); | 20 | char *luaF_getlocalname (TProtoFunc *func, int local_number, int line); |
| 22 | 21 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.11 1997/12/09 13:35:19 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.12 1997/12/11 14:48:46 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -87,13 +87,15 @@ static int ismarked (TObject *o) | |||
| 87 | switch (o->ttype) { | 87 | switch (o->ttype) { |
| 88 | case LUA_T_STRING: case LUA_T_USERDATA: | 88 | case LUA_T_STRING: case LUA_T_USERDATA: |
| 89 | return o->value.ts->head.marked; | 89 | return o->value.ts->head.marked; |
| 90 | case LUA_T_FUNCTION: | 90 | case LUA_T_CLOSURE: |
| 91 | return o->value.cl->head.marked; | 91 | return o->value.cl->head.marked; |
| 92 | case LUA_T_PROTO: | ||
| 93 | return o->value.tf->head.marked; | ||
| 92 | case LUA_T_ARRAY: | 94 | case LUA_T_ARRAY: |
| 93 | return o->value.a->head.marked; | 95 | return o->value.a->head.marked; |
| 94 | #ifdef DEBUG | 96 | #ifdef DEBUG |
| 95 | case LUA_T_LINE: case LUA_T_MARK: | 97 | case LUA_T_LINE: case LUA_T_CLMARK: |
| 96 | case LUA_T_PROTO: case LUA_T_CPROTO: | 98 | case LUA_T_CMARK: case LUA_T_PMARK: |
| 97 | lua_error("internal error"); | 99 | lua_error("internal error"); |
| 98 | #endif | 100 | #endif |
| 99 | default: /* nil, number or cproto */ | 101 | default: /* nil, number or cproto */ |
| @@ -180,7 +182,7 @@ static void protomark (TProtoFunc *f) | |||
| 180 | } | 182 | } |
| 181 | 183 | ||
| 182 | 184 | ||
| 183 | static void funcmark (Closure *f) | 185 | static void closuremark (Closure *f) |
| 184 | { | 186 | { |
| 185 | if (!f->head.marked) { | 187 | if (!f->head.marked) { |
| 186 | int i; | 188 | int i; |
| @@ -227,10 +229,10 @@ static int markobject (TObject *o) | |||
| 227 | case LUA_T_ARRAY: | 229 | case LUA_T_ARRAY: |
| 228 | hashmark(avalue(o)); | 230 | hashmark(avalue(o)); |
| 229 | break; | 231 | break; |
| 230 | case LUA_T_FUNCTION: case LUA_T_MARK: | 232 | case LUA_T_CLOSURE: case LUA_T_CLMARK: |
| 231 | funcmark(o->value.cl); | 233 | closuremark(o->value.cl); |
| 232 | break; | 234 | break; |
| 233 | case LUA_T_PROTO: | 235 | case LUA_T_PROTO: case LUA_T_PMARK: |
| 234 | protomark(o->value.tf); | 236 | protomark(o->value.tf); |
| 235 | break; | 237 | break; |
| 236 | default: break; /* numbers, cprotos, etc */ | 238 | default: break; /* numbers, cprotos, etc */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.c,v 1.6 1997/11/03 20:45:23 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 1.7 1997/11/19 17:29:23 roberto Exp roberto $ |
| 3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -12,8 +12,8 @@ | |||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | char *luaO_typenames[] = { /* ORDER LUA_T */ | 14 | char *luaO_typenames[] = { /* ORDER LUA_T */ |
| 15 | "userdata", "number", "string", "table", "prototype", "cprototype", | 15 | "userdata", "number", "string", "table", "function", "function", |
| 16 | "nil", "function", "mark", "cmark", "line", NULL | 16 | "nil", "function", "mark", "mark", "mark", "line", NULL |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | 19 | ||
| @@ -48,7 +48,9 @@ int luaO_equalObj (TObject *t1, TObject *t2) | |||
| 48 | case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); | 48 | case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); |
| 49 | case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2); | 49 | case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2); |
| 50 | case LUA_T_ARRAY: return avalue(t1) == avalue(t2); | 50 | case LUA_T_ARRAY: return avalue(t1) == avalue(t2); |
| 51 | case LUA_T_FUNCTION: return t1->value.cl == t2->value.cl; | 51 | case LUA_T_CLOSURE: return t1->value.cl == t2->value.cl; |
| 52 | case LUA_T_PROTO: return tfvalue(t1) == tfvalue(t2); | ||
| 53 | case LUA_T_CPROTO: return fvalue(t1) == fvalue(t2); | ||
| 52 | default: | 54 | default: |
| 53 | lua_error("internal error in `lua_equalObj'"); | 55 | lua_error("internal error in `lua_equalObj'"); |
| 54 | return 0; /* UNREACHEABLE */ | 56 | return 0; /* UNREACHEABLE */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 1.9 1997/11/19 17:29:23 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.10 1997/11/27 18:25:06 roberto Exp roberto $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -42,9 +42,11 @@ typedef enum { | |||
| 42 | LUA_T_PROTO = -4, /* fixed tag for functions */ | 42 | LUA_T_PROTO = -4, /* fixed tag for functions */ |
| 43 | LUA_T_CPROTO = -5, /* fixed tag for Cfunctions */ | 43 | LUA_T_CPROTO = -5, /* fixed tag for Cfunctions */ |
| 44 | LUA_T_NIL = -6, /* last "pre-defined" tag */ | 44 | LUA_T_NIL = -6, /* last "pre-defined" tag */ |
| 45 | LUA_T_FUNCTION = -7, | 45 | LUA_T_CLOSURE = -7, |
| 46 | LUA_T_MARK = -8, | 46 | LUA_T_CLMARK = -8, /* mark for closures */ |
| 47 | LUA_T_LINE = -10 | 47 | LUA_T_PMARK = -9, /* mark for Lua prototypes */ |
| 48 | LUA_T_CMARK = -10, /* mark for C prototypes */ | ||
| 49 | LUA_T_LINE = -11 | ||
| 48 | } lua_Type; | 50 | } lua_Type; |
| 49 | 51 | ||
| 50 | #define NUM_TYPES 11 | 52 | #define NUM_TYPES 11 |
| @@ -52,11 +54,11 @@ typedef enum { | |||
| 52 | 54 | ||
| 53 | 55 | ||
| 54 | typedef union { | 56 | typedef union { |
| 55 | lua_CFunction f; /* LUA_T_CPROTO */ | 57 | lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */ |
| 56 | real n; /* LUA_T_NUMBER */ | 58 | real n; /* LUA_T_NUMBER */ |
| 57 | struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */ | 59 | struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */ |
| 58 | struct TProtoFunc *tf; /* LUA_T_PROTO */ | 60 | struct TProtoFunc *tf; /* LUA_T_PROTO, LUA_T_PMARK */ |
| 59 | struct Closure *cl; /* LUA_T_FUNCTION, LUA_T_MARK */ | 61 | struct Closure *cl; /* LUA_T_CLOSURE, LUA_T_CLMARK */ |
| 60 | struct Hash *a; /* LUA_T_ARRAY */ | 62 | struct Hash *a; /* LUA_T_ARRAY */ |
| 61 | int i; /* LUA_T_LINE */ | 63 | int i; /* LUA_T_LINE */ |
| 62 | } Value; | 64 | } Value; |
| @@ -133,6 +135,7 @@ typedef struct LocVar { | |||
| 133 | 135 | ||
| 134 | #define protovalue(o) ((o)->value.cl->consts) | 136 | #define protovalue(o) ((o)->value.cl->consts) |
| 135 | 137 | ||
| 138 | |||
| 136 | /* | 139 | /* |
| 137 | ** Closures | 140 | ** Closures |
| 138 | */ | 141 | */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 1.7 1997/11/21 19:00:46 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.8 1997/12/09 13:35:19 roberto Exp roberto $ |
| 3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -36,9 +36,15 @@ static long int hashindex (TObject *ref) | |||
| 36 | case LUA_T_STRING: case LUA_T_USERDATA: | 36 | case LUA_T_STRING: case LUA_T_USERDATA: |
| 37 | h = (IntPoint)tsvalue(ref); | 37 | h = (IntPoint)tsvalue(ref); |
| 38 | break; | 38 | break; |
| 39 | case LUA_T_FUNCTION: | 39 | case LUA_T_CLOSURE: |
| 40 | h = (IntPoint)clvalue(ref); | 40 | h = (IntPoint)clvalue(ref); |
| 41 | break; | 41 | break; |
| 42 | case LUA_T_PROTO: | ||
| 43 | h = (IntPoint)tfvalue(ref); | ||
| 44 | break; | ||
| 45 | case LUA_T_CPROTO: | ||
| 46 | h = (IntPoint)fvalue(ref); | ||
| 47 | break; | ||
| 42 | case LUA_T_ARRAY: | 48 | case LUA_T_ARRAY: |
| 43 | h = (IntPoint)avalue(ref); | 49 | h = (IntPoint)avalue(ref); |
| 44 | break; | 50 | break; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 1.10 1997/12/11 14:48:46 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 1.11 1997/12/11 17:21:11 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -112,16 +112,17 @@ int luaT_efectivetag (TObject *o) | |||
| 112 | { | 112 | { |
| 113 | int t; | 113 | int t; |
| 114 | switch (t = ttype(o)) { | 114 | switch (t = ttype(o)) { |
| 115 | case LUA_T_ARRAY: | ||
| 116 | return o->value.a->htag; | ||
| 115 | case LUA_T_USERDATA: { | 117 | case LUA_T_USERDATA: { |
| 116 | int tag = o->value.ts->u.d.tag; | 118 | int tag = o->value.ts->u.d.tag; |
| 117 | return (tag >= 0) ? LUA_T_USERDATA : tag; | 119 | return (tag >= 0) ? LUA_T_USERDATA : tag; |
| 118 | } | 120 | } |
| 119 | case LUA_T_ARRAY: | 121 | case LUA_T_CLOSURE: |
| 120 | return o->value.a->htag; | ||
| 121 | case LUA_T_FUNCTION: case LUA_T_MARK: | ||
| 122 | return o->value.cl->consts[0].ttype; | 122 | return o->value.cl->consts[0].ttype; |
| 123 | #ifdef DEBUG | 123 | #ifdef DEBUG |
| 124 | case LUA_T_LINE: case LUA_T_PROTO: case LUA_T_CPROTO: | 124 | case LUA_T_PMARK: case LUA_T_CMARK: |
| 125 | case LUA_T_CLMARK: case LUA_T_LINE: | ||
| 125 | lua_error("internal error"); | 126 | lua_error("internal error"); |
| 126 | #endif | 127 | #endif |
| 127 | default: | 128 | default: |
| @@ -1,6 +1,6 @@ | |||
| 1 | %{ | 1 | %{ |
| 2 | /* | 2 | /* |
| 3 | ** $Id: lua.stx,v 1.21 1997/12/09 13:35:19 roberto Exp roberto $ | 3 | ** $Id: lua.stx,v 1.22 1997/12/09 16:01:08 roberto Exp roberto $ |
| 4 | ** Syntax analizer and code generator | 4 | ** Syntax analizer and code generator |
| 5 | ** See Copyright Notice in lua.h | 5 | ** See Copyright Notice in lua.h |
| 6 | */ | 6 | */ |
| @@ -555,10 +555,14 @@ static void func_onstack (TProtoFunc *f) | |||
| 555 | int c = next_constant(L->currState); | 555 | int c = next_constant(L->currState); |
| 556 | ttype(&L->currState->f->consts[c]) = LUA_T_PROTO; | 556 | ttype(&L->currState->f->consts[c]) = LUA_T_PROTO; |
| 557 | L->currState->f->consts[c].value.tf = (L->currState+1)->f; | 557 | L->currState->f->consts[c].value.tf = (L->currState+1)->f; |
| 558 | for (i=0; i<nupvalues; i++) | 558 | if (nupvalues == 0) |
| 559 | lua_pushvar((L->currState+1)->upvalues[i]); | 559 | code_constant(c); |
| 560 | code_constant(c); | 560 | else { |
| 561 | code_oparg(CLOSURE, 2, nupvalues, -nupvalues); | 561 | for (i=0; i<nupvalues; i++) |
| 562 | lua_pushvar((L->currState+1)->upvalues[i]); | ||
| 563 | code_constant(c); | ||
| 564 | code_oparg(CLOSURE, 2, nupvalues, -nupvalues); | ||
| 565 | } | ||
| 562 | } | 566 | } |
| 563 | 567 | ||
| 564 | 568 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.15 1997/11/21 19:00:46 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.16 1997/12/09 13:35:19 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -79,13 +79,15 @@ int luaV_tostring (TObject *obj) | |||
| 79 | 79 | ||
| 80 | void luaV_closure (int nelems) | 80 | void luaV_closure (int nelems) |
| 81 | { | 81 | { |
| 82 | struct Stack *S = &L->stack; | 82 | if (nelems > 0) { |
| 83 | Closure *c = luaF_newclosure(nelems); | 83 | struct Stack *S = &L->stack; |
| 84 | c->consts[0] = *(S->top-1); | 84 | Closure *c = luaF_newclosure(nelems); |
| 85 | memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject)); | 85 | c->consts[0] = *(S->top-1); |
| 86 | S->top -= nelems; | 86 | memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject)); |
| 87 | ttype(S->top-1) = LUA_T_FUNCTION; | 87 | S->top -= nelems; |
| 88 | (S->top-1)->value.cl = c; | 88 | ttype(S->top-1) = LUA_T_CLOSURE; |
| 89 | (S->top-1)->value.cl = c; | ||
| 90 | } | ||
| 89 | } | 91 | } |
| 90 | 92 | ||
| 91 | 93 | ||
| @@ -279,13 +281,13 @@ static void adjust_varargs (StkId first_extra_arg) | |||
| 279 | ** [stack+base,top). Returns n such that the the results are between | 281 | ** [stack+base,top). Returns n such that the the results are between |
| 280 | ** [stack+n,top). | 282 | ** [stack+n,top). |
| 281 | */ | 283 | */ |
| 282 | StkId luaV_execute (Closure *cl, StkId base) | 284 | StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) |
| 283 | { | 285 | { |
| 284 | struct Stack *S = &L->stack; /* to optimize */ | 286 | struct Stack *S = &L->stack; /* to optimize */ |
| 285 | Byte *pc = cl->consts[0].value.tf->code; | 287 | Byte *pc = tf->code; |
| 286 | TObject *consts = cl->consts[0].value.tf->consts; | 288 | TObject *consts = tf->consts; |
| 287 | if (lua_callhook) | 289 | if (lua_callhook) |
| 288 | luaD_callHook(base, LUA_T_PROTO, 0); | 290 | luaD_callHook(base, tf, 0); |
| 289 | luaD_checkstack((*pc++)+EXTRA_STACK); | 291 | luaD_checkstack((*pc++)+EXTRA_STACK); |
| 290 | while (1) { | 292 | while (1) { |
| 291 | int aux; | 293 | int aux; |
| @@ -679,7 +681,7 @@ StkId luaV_execute (Closure *cl, StkId base) | |||
| 679 | /* goes through */ | 681 | /* goes through */ |
| 680 | case RETCODE: | 682 | case RETCODE: |
| 681 | if (lua_callhook) | 683 | if (lua_callhook) |
| 682 | luaD_callHook(base, LUA_T_PROTO, 1); | 684 | luaD_callHook(base, NULL, 1); |
| 683 | return (base + ((aux==RETCODE) ? *pc : 0)); | 685 | return (base + ((aux==RETCODE) ? *pc : 0)); |
| 684 | 686 | ||
| 685 | case SETLINEW: | 687 | case SETLINEW: |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.h,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $ | 2 | ** $Id: lvm.h,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -23,7 +23,7 @@ void luaV_gettable (void); | |||
| 23 | void luaV_settable (TObject *t, int mode); | 23 | void luaV_settable (TObject *t, int mode); |
| 24 | void luaV_getglobal (TaggedString *ts); | 24 | void luaV_getglobal (TaggedString *ts); |
| 25 | void luaV_setglobal (TaggedString *ts); | 25 | void luaV_setglobal (TaggedString *ts); |
| 26 | StkId luaV_execute (Closure *func, StkId base); | 26 | StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base); |
| 27 | void luaV_closure (int nelems); | 27 | void luaV_closure (int nelems); |
| 28 | 28 | ||
| 29 | #endif | 29 | #endif |
