aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-10-24 15:17:24 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-10-24 15:17:24 -0200
commite78cf96c971234ea25e35a9672ef00ea389d843f (patch)
tree57dc00fb747c26730acb13a087afb9bc7dcd3216
parent0cb38439560fc2b912d41d3116d2d74c030d13af (diff)
downloadlua-e78cf96c971234ea25e35a9672ef00ea389d843f.tar.gz
lua-e78cf96c971234ea25e35a9672ef00ea389d843f.tar.bz2
lua-e78cf96c971234ea25e35a9672ef00ea389d843f.zip
first version of Cclosures.
-rw-r--r--lapi.c115
-rw-r--r--lbuiltin.c12
-rw-r--r--ldo.c95
-rw-r--r--lfunc.c12
-rw-r--r--lfunc.h3
-rw-r--r--lgc.c6
-rw-r--r--lobject.c7
-rw-r--r--lobject.h12
-rw-r--r--lopcodes.h6
-rw-r--r--ltable.c5
-rw-r--r--ltm.c27
-rw-r--r--lua.h6
-rw-r--r--lua.stx4
-rw-r--r--lvm.c6
-rw-r--r--makefile10
15 files changed, 177 insertions, 149 deletions
diff --git a/lapi.c b/lapi.c
index d67ecd45..c3c4af08 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $ 2** $Id: lapi.c,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -94,6 +94,18 @@ lua_Object lua_lua2C (int number)
94} 94}
95 95
96 96
97lua_Object lua_upvalue (int n)
98{
99 TObject *f = luaD_stack.stack+luaD_Cstack.lua2C-1;
100 if (ttype(f) != LUA_T_MARK || n <= 0 || n > clvalue(f)->nelems)
101 return LUA_NOOBJECT;
102if (ttype(protovalue(f)) != LUA_T_CPROTO) lua_error("BAD!!");
103 *luaD_stack.top = clvalue(f)->consts[n];
104 incr_top;
105 return put_luaObjectonTop();
106}
107
108
97int lua_callfunction (lua_Object function) 109int lua_callfunction (lua_Object function)
98{ 110{
99 if (function == LUA_NOOBJECT) 111 if (function == LUA_NOOBJECT)
@@ -227,8 +239,7 @@ int lua_isuserdata (lua_Object o)
227 239
228int lua_iscfunction (lua_Object o) 240int lua_iscfunction (lua_Object o)
229{ 241{
230 int t = lua_tag(o); 242 return (o != LUA_NOOBJECT) && (lua_tag(o) == LUA_T_CPROTO);
231 return (t == LUA_T_CMARK) || (t == LUA_T_CFUNCTION);
232} 243}
233 244
234int lua_isnumber (lua_Object o) 245int lua_isnumber (lua_Object o)
@@ -244,9 +255,8 @@ int lua_isstring (lua_Object o)
244 255
245int lua_isfunction (lua_Object o) 256int lua_isfunction (lua_Object o)
246{ 257{
247 int t = lua_tag(o); 258 return (o != LUA_NOOBJECT) && ((ttype(Address(o)) == LUA_T_FUNCTION) ||
248 return (t == LUA_T_FUNCTION) || (t == LUA_T_CFUNCTION) || 259 (ttype(Address(o)) == LUA_T_MARK));
249 (t == LUA_T_MARK) || (t == LUA_T_CMARK);
250} 260}
251 261
252 262
@@ -273,10 +283,9 @@ void *lua_getuserdata (lua_Object object)
273 283
274lua_CFunction lua_getcfunction (lua_Object object) 284lua_CFunction lua_getcfunction (lua_Object object)
275{ 285{
276 if (object == LUA_NOOBJECT || ((ttype(Address(object)) != LUA_T_CFUNCTION) && 286 if (!lua_iscfunction(object))
277 (ttype(Address(object)) != LUA_T_CMARK))) 287 return NULL;
278 return NULL; 288 else return fvalue(protovalue(Address(object)));
279 else return (fvalue(Address(object)));
280} 289}
281 290
282 291
@@ -305,15 +314,19 @@ void lua_pushstring (char *s)
305 luaC_checkGC(); 314 luaC_checkGC();
306} 315}
307 316
308void lua_pushcfunction (lua_CFunction fn) 317void lua_pushCclosure (lua_CFunction fn, int n)
309{ 318{
310 if (fn == NULL) 319 if (fn == NULL) {
311 ttype(luaD_stack.top) = LUA_T_NIL; 320 ttype(luaD_stack.top) = LUA_T_NIL;
321 incr_top;
322 }
312 else { 323 else {
313 ttype(luaD_stack.top) = LUA_T_CFUNCTION; 324 checkCparams(n);
325 ttype(luaD_stack.top) = LUA_T_CPROTO;
314 fvalue(luaD_stack.top) = fn; 326 fvalue(luaD_stack.top) = fn;
327 incr_top;
328 luaV_closure(n);
315 } 329 }
316 incr_top;
317} 330}
318 331
319void lua_pushusertag (void *u, int tag) 332void lua_pushusertag (void *u, int tag)
@@ -339,8 +352,6 @@ void lua_pushobject (lua_Object o)
339 *luaD_stack.top = *Address(o); 352 *luaD_stack.top = *Address(o);
340 if (ttype(luaD_stack.top) == LUA_T_MARK) 353 if (ttype(luaD_stack.top) == LUA_T_MARK)
341 ttype(luaD_stack.top) = LUA_T_FUNCTION; 354 ttype(luaD_stack.top) = LUA_T_FUNCTION;
342 else if (ttype(luaD_stack.top) == LUA_T_CMARK)
343 ttype(luaD_stack.top) = LUA_T_CFUNCTION;
344 incr_top; 355 incr_top;
345} 356}
346 357
@@ -350,12 +361,11 @@ int lua_tag (lua_Object lo)
350 if (lo == LUA_NOOBJECT) return LUA_T_NIL; 361 if (lo == LUA_NOOBJECT) return LUA_T_NIL;
351 else { 362 else {
352 TObject *o = Address(lo); 363 TObject *o = Address(lo);
353 lua_Type t = ttype(o); 364 int t = luaT_efectivetag(o);
354 if (t == LUA_T_USERDATA) 365 if (t == LUA_T_USERDATA)
355 return o->value.ts->u.d.tag; 366 return o->value.ts->u.d.tag;
356 else if (t == LUA_T_ARRAY) 367 else
357 return o->value.a->htag; 368 return t;
358 else return t;
359 } 369 }
360} 370}
361 371
@@ -395,7 +405,7 @@ lua_Function lua_stackedfunction (int level)
395{ 405{
396 StkId i; 406 StkId i;
397 for (i = (luaD_stack.top-1)-luaD_stack.stack; i>=0; i--) 407 for (i = (luaD_stack.top-1)-luaD_stack.stack; i>=0; i--)
398 if (luaD_stack.stack[i].ttype == LUA_T_MARK || luaD_stack.stack[i].ttype == LUA_T_CMARK) 408 if (luaD_stack.stack[i].ttype == LUA_T_MARK)
399 if (level-- == 0) 409 if (level-- == 0)
400 return Ref(luaD_stack.stack+i); 410 return Ref(luaD_stack.stack+i);
401 return LUA_NOOBJECT; 411 return LUA_NOOBJECT;
@@ -413,24 +423,27 @@ lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
413{ 423{
414 TObject *f = luaA_Address(func); 424 TObject *f = luaA_Address(func);
415 /* check whether func is a Lua function */ 425 /* check whether func is a Lua function */
416 if (ttype(f) != LUA_T_MARK && ttype(f) != LUA_T_FUNCTION) 426 if (!(f->ttype == LUA_T_MARK || f->ttype == LUA_T_FUNCTION))
417 return LUA_NOOBJECT; 427 return LUA_NOOBJECT;
418 *name = luaF_getlocalname(f->value.tf, local_number, lua_currentline(func)); 428 else {
419 if (*name) { 429 TProtoFunc *fp = protovalue(f)->value.tf;
420 /* if "*name", there must be a LUA_T_LINE */ 430 *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
421 /* therefore, f+2 points to function base */ 431 if (*name) {
422 return Ref((f+2)+(local_number-1)); 432 /* if "*name", there must be a LUA_T_LINE */
433 /* therefore, f+2 points to function base */
434 return Ref((f+2)+(local_number-1));
435 }
436 else
437 return LUA_NOOBJECT;
423 } 438 }
424 else
425 return LUA_NOOBJECT;
426} 439}
427 440
428 441
429int lua_setlocal (lua_Function func, int local_number) 442int lua_setlocal (lua_Function func, int local_number)
430{ 443{
431 TObject *f = Address(func); 444 TObject *f = Address(func);
432 char *name = luaF_getlocalname(f->value.tf, local_number, 445 TProtoFunc *fp = protovalue(f)->value.tf;
433 lua_currentline(func)); 446 char *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
434 checkCparams(1); 447 checkCparams(1);
435 --luaD_stack.top; 448 --luaD_stack.top;
436 if (name) { 449 if (name) {
@@ -447,16 +460,18 @@ int lua_setlocal (lua_Function func, int local_number)
447void lua_funcinfo (lua_Object func, char **filename, int *linedefined) 460void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
448{ 461{
449 TObject *f = Address(func); 462 TObject *f = Address(func);
450 if (f->ttype == LUA_T_MARK || f->ttype == LUA_T_FUNCTION) 463 if (!(ttype(f) == LUA_T_MARK || ttype(f) == LUA_T_FUNCTION))
451 { 464 lua_error("API - `funcinfo' called with a non-function value");
452 TProtoFunc *fp = f->value.cl->consts[0].value.tf; 465 else {
453 *filename = fp->fileName->str; 466 f = protovalue(f);
454 *linedefined = fp->lineDefined; 467 if (ttype(f) == LUA_T_PROTO) {
455 } 468 *filename = tfvalue(f)->fileName->str;
456 else if (f->ttype == LUA_T_CMARK || f->ttype == LUA_T_CFUNCTION) 469 *linedefined = tfvalue(f)->lineDefined;
457 { 470 }
458 *filename = "(C)"; 471 else {
459 *linedefined = -1; 472 *filename = "(C)";
473 *linedefined = -1;
474 }
460 } 475 }
461} 476}
462 477
@@ -464,17 +479,10 @@ void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
464static TObject *functofind; 479static TObject *functofind;
465static int checkfunc (TObject *o) 480static int checkfunc (TObject *o)
466{ 481{
467 if (o->ttype == LUA_T_FUNCTION) 482 return (o->ttype == LUA_T_FUNCTION) &&
468 return 483 ((functofind->ttype == LUA_T_FUNCTION) ||
469 ((functofind->ttype == LUA_T_FUNCTION || 484 (functofind->ttype == LUA_T_MARK)) &&
470 functofind->ttype == LUA_T_MARK) && 485 (functofind->value.cl == o->value.cl);
471 (functofind->value.cl == o->value.cl));
472 else if (o->ttype == LUA_T_CFUNCTION)
473 return
474 ((functofind->ttype == LUA_T_CFUNCTION ||
475 functofind->ttype == LUA_T_CMARK) &&
476 (functofind->value.f == o->value.f));
477 else return 0;
478} 486}
479 487
480 488
@@ -548,8 +556,9 @@ static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults)
548{ 556{
549 StkId base = (luaD_stack.top-luaD_stack.stack)-nParams; 557 StkId base = (luaD_stack.top-luaD_stack.stack)-nParams;
550 luaD_openstack(nParams); 558 luaD_openstack(nParams);
551 luaD_stack.stack[base].ttype = LUA_T_CFUNCTION; 559 luaD_stack.stack[base].ttype = LUA_T_CPROTO;
552 luaD_stack.stack[base].value.f = f; 560 luaD_stack.stack[base].value.f = f;
561 luaF_simpleclosure(luaD_stack.stack+base);
553 luaD_call(base+1, nResults); 562 luaD_call(base+1, nResults);
554} 563}
555 564
diff --git a/lbuiltin.c b/lbuiltin.c
index 902fe124..6cfd3a37 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbuiltin.c,v 1.3 1997/10/18 16:33:36 roberto Exp roberto $ 2** $Id: lbuiltin.c,v 1.4 1997/10/23 16:28:48 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*/
@@ -12,6 +12,7 @@
12#include "lauxlib.h" 12#include "lauxlib.h"
13#include "lbuiltin.h" 13#include "lbuiltin.h"
14#include "ldo.h" 14#include "ldo.h"
15#include "lfunc.h"
15#include "lmem.h" 16#include "lmem.h"
16#include "lobject.h" 17#include "lobject.h"
17#include "lstring.h" 18#include "lstring.h"
@@ -164,10 +165,6 @@ static char *to_string (lua_Object obj)
164 sprintf(buff, "function: %p", o->value.cl); 165 sprintf(buff, "function: %p", o->value.cl);
165 return buff; 166 return buff;
166 } 167 }
167 case LUA_T_CFUNCTION: {
168 sprintf(buff, "cfunction: %p", o->value.f);
169 return buff;
170 }
171 case LUA_T_USERDATA: { 168 case LUA_T_USERDATA: {
172 sprintf(buff, "userdata: %p", o->value.ts->u.d.v); 169 sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
173 return buff; 170 return buff;
@@ -382,6 +379,7 @@ static void testC (void)
382 break; 379 break;
383 380
384 case 'c': reg[getnum(s)] = lua_createtable(); break; 381 case 'c': reg[getnum(s)] = lua_createtable(); break;
382 case 'C': lua_pushCclosure(testC, getnum(s)); break;
385 case 'P': reg[getnum(s)] = lua_pop(); break; 383 case 'P': reg[getnum(s)] = lua_pop(); break;
386 case 'g': { int n=getnum(s); reg[n]=lua_getglobal(getname(s)); break; } 384 case 'g': { int n=getnum(s); reg[n]=lua_getglobal(getname(s)); break; }
387 case 'G': { int n = getnum(s); 385 case 'G': { int n = getnum(s);
@@ -401,6 +399,7 @@ static void testC (void)
401 case 'I': reg[getnum(s)] = lua_rawgettable(); break; 399 case 'I': reg[getnum(s)] = lua_rawgettable(); break;
402 case 't': lua_settable(); break; 400 case 't': lua_settable(); break;
403 case 'T': lua_rawsettable(); break; 401 case 'T': lua_rawsettable(); break;
402 case 'U': { int n=getnum(s); reg[n]=lua_upvalue(getnum(s)); break; }
404 default: luaL_verror("unknown command in `testC': %c", *(s-1)); 403 default: luaL_verror("unknown command in `testC': %c", *(s-1));
405 } 404 }
406 if (*s == 0) return; 405 if (*s == 0) return;
@@ -462,10 +461,11 @@ void luaB_predefine (void)
462 /* pre-register mem error messages, to avoid loop when error arises */ 461 /* pre-register mem error messages, to avoid loop when error arises */
463 luaS_newfixedstring(tableEM); 462 luaS_newfixedstring(tableEM);
464 luaS_newfixedstring(memEM); 463 luaS_newfixedstring(memEM);
465 o.ttype = LUA_T_CFUNCTION;
466 for (i=0; i<INTFUNCSIZE; i++) { 464 for (i=0; i<INTFUNCSIZE; i++) {
467 ts = luaS_new(int_funcs[i].name); 465 ts = luaS_new(int_funcs[i].name);
468 fvalue(&o) = int_funcs[i].func; 466 fvalue(&o) = int_funcs[i].func;
467 ttype(&o) = LUA_T_CPROTO;
468 luaF_simpleclosure(&o);
469 luaS_rawsetglobal(ts, &o); 469 luaS_rawsetglobal(ts, &o);
470 } 470 }
471 ts = luaS_new("_VERSION"); 471 ts = luaS_new("_VERSION");
diff --git a/ldo.c b/ldo.c
index 8bf43215..e9ab366a 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $ 2** $Id: ldo.c,v 1.4 1997/10/23 16:26:37 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*/
@@ -11,6 +11,7 @@
11 11
12#include "lbuiltin.h" 12#include "lbuiltin.h"
13#include "ldo.h" 13#include "ldo.h"
14#include "lfunc.h"
14#include "lgc.h" 15#include "lgc.h"
15#include "lmem.h" 16#include "lmem.h"
16#include "lobject.h" 17#include "lobject.h"
@@ -31,7 +32,7 @@
31 32
32static TObject initial_stack; 33static TObject initial_stack;
33 34
34struct Stack luaD_stack = {&initial_stack+1, &initial_stack, &initial_stack}; 35struct Stack luaD_stack = {&initial_stack, &initial_stack, &initial_stack};
35 36
36 37
37struct C_Lua_Stack luaD_Cstack = {0, 0, 0}; 38struct C_Lua_Stack luaD_Cstack = {0, 0, 0};
@@ -40,6 +41,40 @@ static jmp_buf *errorJmp = NULL; /* current error recover point */
40 41
41 42
42 43
44/*
45** Error messages
46*/
47
48static void auxerrorim (char *form)
49{
50 lua_Object s = lua_getparam(1);
51 if (lua_isstring(s))
52 fprintf(stderr, form, lua_getstring(s));
53}
54
55
56static void femergencyerror (void)
57{
58 auxerrorim("THERE WAS AN ERROR INSIDE AN ERROR METHOD:\n%s\n");
59}
60
61
62static void stderrorim (void)
63{
64 auxerrorim("lua: %s\n");
65}
66
67
68TObject luaD_errorim;
69static TObject emergencyerror;
70
71
72static void initCfunc (TObject *o, lua_CFunction f)
73{
74 ttype(o) = LUA_T_CPROTO;
75 fvalue(o) = f;
76 luaF_simpleclosure(o);
77}
43 78
44 79
45#define STACK_EXTRA 32 80#define STACK_EXTRA 32
@@ -50,8 +85,10 @@ static void initstack (int n)
50 luaD_stack.stack = luaM_newvector(maxstack, TObject); 85 luaD_stack.stack = luaM_newvector(maxstack, TObject);
51 luaD_stack.last = luaD_stack.stack+(maxstack-1); 86 luaD_stack.last = luaD_stack.stack+(maxstack-1);
52 luaD_stack.top = luaD_stack.stack; 87 luaD_stack.top = luaD_stack.stack;
53 *(luaD_stack.top++) = initial_stack; 88 *luaD_stack.stack = initial_stack;
54 luaB_predefine(); 89 luaB_predefine();
90 initCfunc(&luaD_errorim, stderrorim);
91 initCfunc(&emergencyerror, femergencyerror);
55} 92}
56 93
57 94
@@ -79,7 +116,6 @@ void luaD_checkstack (int n)
79} 116}
80 117
81 118
82
83/* 119/*
84** Adjust stack. Set top to the given value, pushing NILs if needed. 120** Adjust stack. Set top to the given value, pushing NILs if needed.
85*/ 121*/
@@ -128,9 +164,9 @@ void luaD_callHook (StkId base, lua_Type type, int isreturn)
128 (*lua_callhook)(LUA_NOOBJECT, "(return)", 0); 164 (*lua_callhook)(LUA_NOOBJECT, "(return)", 0);
129 else { 165 else {
130 TObject *f = luaD_stack.stack+base-1; 166 TObject *f = luaD_stack.stack+base-1;
131 if (type == LUA_T_MARK) 167 if (type == LUA_T_PROTO)
132 (*lua_callhook)(Ref(f), f->value.tf->fileName->str, 168 (*lua_callhook)(Ref(f), tfvalue(protovalue(f))->fileName->str,
133 f->value.tf->lineDefined); 169 tfvalue(protovalue(f))->lineDefined);
134 else 170 else
135 (*lua_callhook)(Ref(f), "(C)", -1); 171 (*lua_callhook)(Ref(f), "(C)", -1);
136 } 172 }
@@ -153,10 +189,10 @@ static StkId callC (lua_CFunction func, StkId base)
153 luaD_Cstack.lua2C = base; 189 luaD_Cstack.lua2C = base;
154 luaD_Cstack.base = base+luaD_Cstack.num; /* == top-stack */ 190 luaD_Cstack.base = base+luaD_Cstack.num; /* == top-stack */
155 if (lua_callhook) 191 if (lua_callhook)
156 luaD_callHook(base, LUA_T_CMARK, 0); 192 luaD_callHook(base, LUA_T_CPROTO, 0);
157 (*func)(); 193 (*func)();
158 if (lua_callhook) /* func may have changed lua_callhook */ 194 if (lua_callhook) /* func may have changed lua_callhook */
159 luaD_callHook(base, LUA_T_CMARK, 1); 195 luaD_callHook(base, LUA_T_CPROTO, 1);
160 firstResult = luaD_Cstack.base; 196 firstResult = luaD_Cstack.base;
161 luaD_Cstack = oldCLS; 197 luaD_Cstack = oldCLS;
162 return firstResult; 198 return firstResult;
@@ -182,13 +218,11 @@ void luaD_call (StkId base, int nResults)
182 StkId firstResult; 218 StkId firstResult;
183 TObject *func = luaD_stack.stack+base-1; 219 TObject *func = luaD_stack.stack+base-1;
184 int i; 220 int i;
185 if (ttype(func) == LUA_T_CFUNCTION) { 221 if (ttype(func) == LUA_T_FUNCTION) {
186 ttype(func) = LUA_T_CMARK; 222 TObject *proto = protovalue(func);
187 firstResult = callC(fvalue(func), base);
188 }
189 else if (ttype(func) == LUA_T_FUNCTION) {
190 ttype(func) = LUA_T_MARK; 223 ttype(func) = LUA_T_MARK;
191 firstResult = luaV_execute(func->value.cl, base); 224 firstResult = (ttype(proto) == LUA_T_CPROTO) ? callC(fvalue(proto), base)
225 : luaV_execute(func->value.cl, base);
192 } 226 }
193 else { /* func is not a function */ 227 else { /* func is not a function */
194 /* Check the tag method for invalid functions */ 228 /* Check the tag method for invalid functions */
@@ -222,39 +256,12 @@ void luaD_travstack (int (*fn)(TObject *))
222} 256}
223 257
224 258
225/*
226** Error messages
227*/
228
229static void auxerrorim (char *form)
230{
231 lua_Object s = lua_getparam(1);
232 if (lua_isstring(s))
233 fprintf(stderr, form, lua_getstring(s));
234}
235
236
237static void emergencyerrorf (void)
238{
239 auxerrorim("THERE WAS AN ERROR INSIDE AN ERROR METHOD:\n%s\n");
240}
241
242
243static void stderrorim (void)
244{
245 auxerrorim("lua: %s\n");
246}
247
248
249TObject luaD_errorim = {LUA_T_CFUNCTION, {stderrorim}};
250
251 259
252static void message (char *s) 260static void message (char *s)
253{ 261{
254 TObject im = luaD_errorim; 262 TObject im = luaD_errorim;
255 if (ttype(&im) != LUA_T_NIL) { 263 if (ttype(&im) != LUA_T_NIL) {
256 luaD_errorim.ttype = LUA_T_CFUNCTION; 264 luaD_errorim = emergencyerror;
257 luaD_errorim.value.f = emergencyerrorf;
258 lua_pushstring(s); 265 lua_pushstring(s);
259 luaD_callTM(&im, 1, 0); 266 luaD_callTM(&im, 1, 0);
260 luaD_errorim = im; 267 luaD_errorim = im;
@@ -291,7 +298,7 @@ static void do_callinc (int nResults)
291 298
292/* 299/*
293** Execute a protected call. Assumes that function is at luaD_Cstack.base and 300** Execute a protected call. Assumes that function is at luaD_Cstack.base and
294** parameters are on luaD_stack.top of it. Leave nResults on the luaD_stack.stack. 301** parameters are on top of it. Leave nResults on the stack.
295*/ 302*/
296int luaD_protectedrun (int nResults) 303int luaD_protectedrun (int nResults)
297{ 304{
diff --git a/lfunc.c b/lfunc.c
index a29894e2..7270e980 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $ 2** $Id: lfunc.c,v 1.4 1997/10/23 16:26:37 roberto Exp roberto $
3** Lua Funcion auxiliar 3** Lua Funcion auxiliar
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -23,10 +23,20 @@ Closure *luaF_newclosure (int nelems)
23 Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject)); 23 Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject));
24 luaO_insertlist(&luaF_rootcl, (GCnode *)c); 24 luaO_insertlist(&luaF_rootcl, (GCnode *)c);
25 luaO_nblocks += gcsizeclosure(c); 25 luaO_nblocks += gcsizeclosure(c);
26 c->nelems = nelems;
26 return c; 27 return c;
27} 28}
28 29
29 30
31void luaF_simpleclosure (TObject *o)
32{
33 Closure *c = luaF_newclosure(0);
34 c->consts[0] = *o;
35 ttype(o) = LUA_T_FUNCTION;
36 clvalue(o) = c;
37}
38
39
30TProtoFunc *luaF_newproto (void) 40TProtoFunc *luaF_newproto (void)
31{ 41{
32 TProtoFunc *f = luaM_new(TProtoFunc); 42 TProtoFunc *f = luaM_new(TProtoFunc);
diff --git a/lfunc.h b/lfunc.h
index 4a7a6ac9..b6e14e26 100644
--- a/lfunc.h
+++ b/lfunc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $ 2** $Id: lfunc.h,v 1.2 1997/09/26 16:46:20 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*/
@@ -19,6 +19,7 @@ TProtoFunc *luaF_newproto (void);
19Closure *luaF_newclosure (int nelems); 19Closure *luaF_newclosure (int nelems);
20void luaF_freeproto (TProtoFunc *l); 20void luaF_freeproto (TProtoFunc *l);
21void luaF_freeclosure (Closure *l); 21void luaF_freeclosure (Closure *l);
22void luaF_simpleclosure (TObject *o);
22 23
23char *luaF_getlocalname (TProtoFunc *func, int local_number, int line); 24char *luaF_getlocalname (TProtoFunc *func, int local_number, int line);
24 25
diff --git a/lgc.c b/lgc.c
index 0ea948f6..aafc4cb8 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.4 1997/10/16 10:59:34 roberto Exp roberto $ 2** $Id: lgc.c,v 1.5 1997/10/23 16:26:37 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*/
@@ -97,7 +97,7 @@ static int ismarked (TObject *o)
97 return o->value.tf->head.marked; 97 return o->value.tf->head.marked;
98 case LUA_T_ARRAY: 98 case LUA_T_ARRAY:
99 return o->value.a->head.marked; 99 return o->value.a->head.marked;
100 default: /* nil, number or cfunction */ 100 default: /* nil, number or cproto */
101 return 1; 101 return 1;
102 } 102 }
103} 103}
@@ -234,7 +234,7 @@ static int markobject (TObject *o)
234 case LUA_T_PROTO: 234 case LUA_T_PROTO:
235 protomark(o->value.tf); 235 protomark(o->value.tf);
236 break; 236 break;
237 default: break; /* numbers, cfunctions, etc */ 237 default: break; /* numbers, cprotos, etc */
238 } 238 }
239 return 0; 239 return 0;
240} 240}
diff --git a/lobject.c b/lobject.c
index 71579156..8c3c11f7 100644
--- a/lobject.c
+++ b/lobject.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.c,v 1.3 1997/10/16 20:07:40 roberto Exp roberto $ 2** $Id: lobject.c,v 1.4 1997/10/23 16:26:37 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
14char *luaO_typenames[] = { /* ORDER LUA_T */ 14char *luaO_typenames[] = { /* ORDER LUA_T */
15 "userdata", "number", "string", "table", "function", "function", 15 "userdata", "number", "string", "table", "prototype", "cprototype",
16 "nil", "prototype", "mark", "cmark", "line", NULL 16 "nil", "function", "mark", "cmark", "line", NULL
17}; 17};
18 18
19 19
@@ -48,7 +48,6 @@ int luaO_equalObj (TObject *t1, TObject *t2)
48 case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2); 48 case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2);
49 case LUA_T_ARRAY: return avalue(t1) == avalue(t2); 49 case LUA_T_ARRAY: return avalue(t1) == avalue(t2);
50 case LUA_T_FUNCTION: return t1->value.cl == t2->value.cl; 50 case LUA_T_FUNCTION: return t1->value.cl == t2->value.cl;
51 case LUA_T_CFUNCTION: return fvalue(t1) == fvalue(t2);
52 default: 51 default:
53 lua_error("internal error in `lua_equalObj'"); 52 lua_error("internal error in `lua_equalObj'");
54 return 0; /* UNREACHEABLE */ 53 return 0; /* UNREACHEABLE */
diff --git a/lobject.h b/lobject.h
index ee97f8cd..7e9afd62 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.5 1997/10/16 20:07:40 roberto Exp roberto $ 2** $Id: lobject.h,v 1.6 1997/10/23 16:26:37 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*/
@@ -39,12 +39,11 @@ typedef enum {
39 LUA_T_NUMBER = -1, /* fixed tag for numbers */ 39 LUA_T_NUMBER = -1, /* fixed tag for numbers */
40 LUA_T_STRING = -2, /* fixed tag for strings */ 40 LUA_T_STRING = -2, /* fixed tag for strings */
41 LUA_T_ARRAY = -3, /* tag default for tables (or arrays) */ 41 LUA_T_ARRAY = -3, /* tag default for tables (or arrays) */
42 LUA_T_FUNCTION = -4, /* fixed tag for functions */ 42 LUA_T_PROTO = -4, /* fixed tag for functions */
43 LUA_T_CFUNCTION= -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_PROTO = -7, 45 LUA_T_FUNCTION = -7,
46 LUA_T_MARK = -8, 46 LUA_T_MARK = -8,
47 LUA_T_CMARK = -9,
48 LUA_T_LINE = -10 47 LUA_T_LINE = -10
49} lua_Type; 48} lua_Type;
50 49
@@ -53,7 +52,7 @@ typedef enum {
53 52
54 53
55typedef union { 54typedef union {
56 lua_CFunction f; /* LUA_T_CFUNCTION, LUA_T_CMARK */ 55 lua_CFunction f; /* LUA_T_CPROTO */
57 real n; /* LUA_T_NUMBER */ 56 real n; /* LUA_T_NUMBER */
58 struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */ 57 struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */
59 struct TProtoFunc *tf; /* LUA_T_PROTO */ 58 struct TProtoFunc *tf; /* LUA_T_PROTO */
@@ -132,6 +131,7 @@ typedef struct LocVar {
132#define fvalue(o) ((o)->value.f) 131#define fvalue(o) ((o)->value.f)
133#define tfvalue(o) ((o)->value.tf) 132#define tfvalue(o) ((o)->value.tf)
134 133
134#define protovalue(o) (&(o)->value.cl->consts[0])
135 135
136/* 136/*
137** Closures 137** Closures
diff --git a/lopcodes.h b/lopcodes.h
index 11a88152..ba73cec4 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.9 1997/10/16 10:59:34 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.10 1997/10/16 21:14:47 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -135,9 +135,9 @@ IFTUPJMPW,/* w x - (x!=nil)? PC-=w */
135IFFUPJMP,/* b x - (x==nil)? PC-=b */ 135IFFUPJMP,/* b x - (x==nil)? PC-=b */
136IFFUPJMPW,/* w x - (x==nil)? PC-=w */ 136IFFUPJMPW,/* w x - (x==nil)? PC-=w */
137 137
138CLOSURE,/* b v_b...v_1 proto c(proto) */ 138CLOSURE,/* b proto v_b...v_1 c(proto) */
139CLOSURE0,/* - proto c(proto) */ 139CLOSURE0,/* - proto c(proto) */
140CLOSURE1,/* - v_1 proto c(proto) */ 140CLOSURE1,/* - proto v_1 c(proto) */
141 141
142CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */ 142CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
143CALLFUNC0,/* b v_b...v_1 f - f(v1,...,v_b) */ 143CALLFUNC0,/* b v_b...v_1 f - f(v1,...,v_b) */
diff --git a/ltable.c b/ltable.c
index 71d49dcb..4ac0caab 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 1.3 1997/10/18 16:29:15 roberto Exp roberto $ 2** $Id: ltable.c,v 1.4 1997/10/23 16:26:37 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*/
@@ -41,9 +41,6 @@ static long int hashindex (TObject *ref)
41 case LUA_T_FUNCTION: 41 case LUA_T_FUNCTION:
42 h = (IntPoint)clvalue(ref); 42 h = (IntPoint)clvalue(ref);
43 break; 43 break;
44 case LUA_T_CFUNCTION:
45 h = (IntPoint)fvalue(ref);
46 break;
47 case LUA_T_ARRAY: 44 case LUA_T_ARRAY:
48 h = (IntPoint)avalue(ref); 45 h = (IntPoint)avalue(ref);
49 break; 46 break;
diff --git a/ltm.c b/ltm.c
index 913c4b7d..980fd4d6 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $ 2** $Id: ltm.c,v 1.3 1997/10/16 20:07:40 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*/
@@ -93,8 +93,8 @@ static char validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */
93{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */ 93{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */
94{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */ 94{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */
95{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */ 95{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */
96{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_FUNCTION */ 96{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_PROTO */
97{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CFUNCTION */ 97{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CPROTO */
98{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */ 98{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */
99}; 99};
100 100
@@ -145,14 +145,19 @@ void luaT_realtag (int tag)
145 145
146int luaT_efectivetag (TObject *o) 146int luaT_efectivetag (TObject *o)
147{ 147{
148 lua_Type t = ttype(o); 148 int t;
149 if (t == LUA_T_USERDATA) { 149 switch (t = ttype(o)) {
150 int tag = o->value.ts->u.d.tag; 150 case LUA_T_USERDATA: {
151 return (tag >= 0) ? LUA_T_USERDATA : tag; 151 int tag = o->value.ts->u.d.tag;
152 return (tag >= 0) ? LUA_T_USERDATA : tag;
153 }
154 case LUA_T_ARRAY:
155 return o->value.a->htag;
156 case LUA_T_FUNCTION: case LUA_T_MARK:
157 return o->value.cl->consts[0].ttype;
158 default:
159 return t;
152 } 160 }
153 else if (t == LUA_T_ARRAY)
154 return o->value.a->htag;
155 else return t;
156} 161}
157 162
158 163
@@ -163,7 +168,7 @@ TObject *luaT_gettagmethod (int t, char *event)
163 if (validevent(t, e)) 168 if (validevent(t, e))
164 return luaT_getim(t,e); 169 return luaT_getim(t,e);
165 else 170 else
166 return luaT_getim(LUA_T_CMARK, IM_GETTABLE); /* always nil */ 171 return luaT_getim(LUA_T_NUMBER, IM_ADD); /* always nil */
167} 172}
168 173
169 174
diff --git a/lua.h b/lua.h
index 1cce56c0..91d80c02 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: $ 2** $Id: lua.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
3** LUA - An Extensible Extension Language 3** LUA - An Extensible Extension Language
4** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil 4** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
5** e-mail: lua@tecgraf.puc-rio.br 5** e-mail: lua@tecgraf.puc-rio.br
@@ -72,6 +72,7 @@ void lua_endblock (void);
72lua_Object lua_lua2C (int number); 72lua_Object lua_lua2C (int number);
73#define lua_getparam(_) lua_lua2C(_) 73#define lua_getparam(_) lua_lua2C(_)
74#define lua_getresult(_) lua_lua2C(_) 74#define lua_getresult(_) lua_lua2C(_)
75lua_Object lua_upvalue (int n);
75 76
76int lua_isnil (lua_Object object); 77int lua_isnil (lua_Object object);
77int lua_istable (lua_Object object); 78int lua_istable (lua_Object object);
@@ -90,7 +91,7 @@ void *lua_getuserdata (lua_Object object);
90void lua_pushnil (void); 91void lua_pushnil (void);
91void lua_pushnumber (float n); 92void lua_pushnumber (float n);
92void lua_pushstring (char *s); 93void lua_pushstring (char *s);
93void lua_pushcfunction (lua_CFunction fn); 94void lua_pushCclosure (lua_CFunction fn, int n);
94void lua_pushusertag (void *u, int tag); 95void lua_pushusertag (void *u, int tag);
95void lua_pushobject (lua_Object object); 96void lua_pushobject (lua_Object object);
96 97
@@ -131,6 +132,7 @@ long lua_collectgarbage (long limit);
131 132
132#define lua_pushuserdata(u) lua_pushusertag(u, 0) 133#define lua_pushuserdata(u) lua_pushusertag(u, 0)
133 134
135#define lua_pushcfunction(f) lua_pushCclosure(f, 0)
134 136
135 137
136 138
diff --git a/lua.stx b/lua.stx
index 13549e31..559d224f 100644
--- a/lua.stx
+++ b/lua.stx
@@ -1,6 +1,6 @@
1%{ 1%{
2/* 2/*
3** $Id: lua.stx,v 1.11 1997/10/16 10:59:34 roberto Exp roberto $ 3** $Id: lua.stx,v 1.12 1997/10/18 16:46:39 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*/
@@ -520,9 +520,9 @@ static void func_onstack (TProtoFunc *f)
520 int c = next_constant(currState); 520 int c = next_constant(currState);
521 ttype(&currState->f->consts[c]) = LUA_T_PROTO; 521 ttype(&currState->f->consts[c]) = LUA_T_PROTO;
522 currState->f->consts[c].value.tf = (currState+1)->f; 522 currState->f->consts[c].value.tf = (currState+1)->f;
523 code_constant(c);
524 for (i=0; i<nupvalues; i++) 523 for (i=0; i<nupvalues; i++)
525 lua_pushvar((currState+1)->upvalues[i]); 524 lua_pushvar((currState+1)->upvalues[i]);
525 code_constant(c);
526 code_oparg(CLOSURE, 2, nupvalues, -nupvalues); 526 code_oparg(CLOSURE, 2, nupvalues, -nupvalues);
527} 527}
528 528
diff --git a/lvm.c b/lvm.c
index 4b77c3a6..2f8aaea1 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.9 1997/10/13 22:12:04 roberto Exp roberto $ 2** $Id: lvm.c,v 1.10 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*/
@@ -79,8 +79,8 @@ int luaV_tostring (TObject *obj)
79void luaV_closure (int nelems) 79void luaV_closure (int nelems)
80{ 80{
81 Closure *c = luaF_newclosure(nelems); 81 Closure *c = luaF_newclosure(nelems);
82 memcpy(c->consts, luaD_stack.top-(nelems+1), (nelems+1)*sizeof(TObject)); 82 c->consts[0] = *(luaD_stack.top-1);
83 c->nelems = nelems; 83 memcpy(&c->consts[1], luaD_stack.top-(nelems+1), nelems*sizeof(TObject));
84 luaD_stack.top -= nelems; 84 luaD_stack.top -= nelems;
85 ttype(luaD_stack.top-1) = LUA_T_FUNCTION; 85 ttype(luaD_stack.top-1) = LUA_T_FUNCTION;
86 (luaD_stack.top-1)->value.cl = c; 86 (luaD_stack.top-1)->value.cl = c;
diff --git a/makefile b/makefile
index d562fecf..c2b0b2cd 100644
--- a/makefile
+++ b/makefile
@@ -1,5 +1,5 @@
1# 1#
2## $Id: makefile,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $ 2## $Id: makefile,v 1.3 1997/10/13 22:10:45 roberto Exp roberto $
3## Makefile 3## Makefile
4## See Copyright Notice in lua.h 4## See Copyright Notice in lua.h
5# 5#
@@ -90,15 +90,13 @@ clear :
90%.c : RCS/%.c,v 90%.c : RCS/%.c,v
91 co $@ 91 co $@
92 92
93
94
95lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lfunc.h lgc.h \ 93lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lfunc.h lgc.h \
96 lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.h 94 lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.h
97lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h 95lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
98lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \ 96lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \
99 lmem.h lstring.h ltable.h ltm.h 97 ldo.h lfunc.h lmem.h lstring.h ltable.h ltm.h
100ldo.o: ldo.c lbuiltin.h ldo.h lobject.h lua.h lgc.h lmem.h lparser.h \ 98ldo.o: ldo.c lbuiltin.h ldo.h lobject.h lua.h lfunc.h lgc.h lmem.h \
101 lzio.h ltm.h luadebug.h lundump.h lvm.h 99 lparser.h lzio.h ltm.h luadebug.h lundump.h lvm.h
102lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h 100lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h
103lgc.o: lgc.c ldo.h lobject.h lua.h lfunc.h lgc.h lmem.h lstring.h \ 101lgc.o: lgc.c ldo.h lobject.h lua.h lfunc.h lgc.h lmem.h lstring.h \
104 ltable.h ltm.h 102 ltable.h ltm.h