aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-12-15 14:17:20 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-12-15 14:17:20 -0200
commit94144a7821c0fa412d5d228ab5197a8ebaaa3c25 (patch)
tree99e21c8935f07c556eb16bed7414211d83234cbd /lapi.c
parent4daae2165d617e57ad1460471f8d902d38abac6e (diff)
downloadlua-94144a7821c0fa412d5d228ab5197a8ebaaa3c25.tar.gz
lua-94144a7821c0fa412d5d228ab5197a8ebaaa3c25.tar.bz2
lua-94144a7821c0fa412d5d228ab5197a8ebaaa3c25.zip
otimization: closures without upvalues don't need to be closures
Diffstat (limited to 'lapi.c')
-rw-r--r--lapi.c99
1 files changed, 66 insertions, 33 deletions
diff --git a/lapi.c b/lapi.c
index 51b6159b..3899bb86 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.12 1997/12/09 13:35:19 roberto Exp roberto $ 2** $Id: lapi.c,v 1.13 1997/12/11 14:48:46 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*/
@@ -39,8 +39,12 @@ static int normalized_type (TObject *o)
39{ 39{
40 int t = ttype(o); 40 int t = ttype(o);
41 switch (t) { 41 switch (t) {
42 case LUA_T_MARK: 42 case LUA_T_CLMARK:
43 return LUA_T_FUNCTION; 43 return LUA_T_CLOSURE;
44 case LUA_T_PMARK:
45 return LUA_T_PROTO;
46 case LUA_T_CMARK:
47 return LUA_T_CPROTO;
44 default: 48 default:
45 return t; 49 return t;
46 } 50 }
@@ -54,6 +58,12 @@ static void set_normalized (TObject *d, TObject *s)
54} 58}
55 59
56 60
61static TObject *luaA_protovalue (TObject *o)
62{
63 return (ttype(o) == LUA_T_CLOSURE) ? protovalue(o) : o;
64}
65
66
57void luaA_packresults (void) 67void luaA_packresults (void)
58{ 68{
59 luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top); 69 luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top);
@@ -247,7 +257,7 @@ int lua_isuserdata (lua_Object o)
247 257
248int lua_iscfunction (lua_Object o) 258int lua_iscfunction (lua_Object o)
249{ 259{
250 return (o != LUA_NOOBJECT) && (lua_tag(o) == LUA_T_CPROTO); 260 return (lua_tag(o) == LUA_T_CPROTO);
251} 261}
252 262
253int lua_isnumber (lua_Object o) 263int lua_isnumber (lua_Object o)
@@ -263,7 +273,8 @@ int lua_isstring (lua_Object o)
263 273
264int lua_isfunction (lua_Object o) 274int lua_isfunction (lua_Object o)
265{ 275{
266 return (o != LUA_NOOBJECT) && (normalized_type(Address(o)) == LUA_T_FUNCTION); 276 int t = lua_tag(o);
277 return (t == LUA_T_PROTO) || (t == LUA_T_CPROTO);
267} 278}
268 279
269 280
@@ -292,7 +303,7 @@ lua_CFunction lua_getcfunction (lua_Object object)
292{ 303{
293 if (!lua_iscfunction(object)) 304 if (!lua_iscfunction(object))
294 return NULL; 305 return NULL;
295 else return fvalue(protovalue(Address(object))); 306 else return fvalue(luaA_protovalue(Address(object)));
296} 307}
297 308
298 309
@@ -361,14 +372,29 @@ void lua_pushobject (lua_Object o)
361 372
362int lua_tag (lua_Object lo) 373int lua_tag (lua_Object lo)
363{ 374{
364 if (lo == LUA_NOOBJECT) return LUA_T_NIL; 375 if (lo == LUA_NOOBJECT)
376 return LUA_T_NIL;
365 else { 377 else {
366 TObject *o = Address(lo); 378 TObject *o = Address(lo);
367 int t = luaT_efectivetag(o); 379 int t;
368 if (t == LUA_T_USERDATA) 380 switch (t = ttype(o)) {
369 return o->value.ts->u.d.tag; 381 case LUA_T_USERDATA:
370 else 382 return o->value.ts->u.d.tag;
371 return t; 383 case LUA_T_ARRAY:
384 return o->value.a->htag;
385 case LUA_T_CLOSURE: case LUA_T_CLMARK:
386 return o->value.cl->consts[0].ttype;
387 case LUA_T_PMARK:
388 return LUA_T_PROTO;
389 case LUA_T_CMARK:
390 return LUA_T_CPROTO;
391#ifdef DEBUG
392 case LUA_T_LINE:
393 lua_error("internal error");
394#endif
395 default:
396 return t;
397 }
372 } 398 }
373} 399}
374 400
@@ -407,10 +433,12 @@ lua_LHFunction lua_linehook = NULL;
407lua_Function lua_stackedfunction (int level) 433lua_Function lua_stackedfunction (int level)
408{ 434{
409 StkId i; 435 StkId i;
410 for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) 436 for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) {
411 if (L->stack.stack[i].ttype == LUA_T_MARK) 437 int t = L->stack.stack[i].ttype;
438 if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
412 if (level-- == 0) 439 if (level-- == 0)
413 return Ref(L->stack.stack+i); 440 return Ref(L->stack.stack+i);
441 }
414 return LUA_NOOBJECT; 442 return LUA_NOOBJECT;
415} 443}
416 444
@@ -418,18 +446,19 @@ lua_Function lua_stackedfunction (int level)
418int lua_currentline (lua_Function func) 446int lua_currentline (lua_Function func)
419{ 447{
420 TObject *f = Address(func); 448 TObject *f = Address(func);
421 return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1; 449 return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ?
450 (f+1)->value.i : -1;
422} 451}
423 452
424 453
425lua_Object lua_getlocal (lua_Function func, int local_number, char **name) 454lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
426{ 455{
427 /* check whether func is a function */ 456 /* check whether func is a Lua function */
428 if (!lua_isfunction(func)) 457 if (lua_tag(func) != LUA_T_PROTO)
429 return LUA_NOOBJECT; 458 return LUA_NOOBJECT;
430 else { 459 else {
431 TObject *f = luaA_Address(func); 460 TObject *f = Address(func);
432 TProtoFunc *fp = protovalue(f)->value.tf; 461 TProtoFunc *fp = luaA_protovalue(f)->value.tf;
433 *name = luaF_getlocalname(fp, local_number, lua_currentline(func)); 462 *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
434 if (*name) { 463 if (*name) {
435 /* if "*name", there must be a LUA_T_LINE */ 464 /* if "*name", there must be a LUA_T_LINE */
@@ -444,19 +473,24 @@ lua_Object lua_getlocal (lua_Function func, int local_number, char **name)
444 473
445int lua_setlocal (lua_Function func, int local_number) 474int lua_setlocal (lua_Function func, int local_number)
446{ 475{
447 TObject *f = Address(func); 476 /* check whether func is a Lua function */
448 TProtoFunc *fp = protovalue(f)->value.tf; 477 if (lua_tag(func) != LUA_T_PROTO)
449 char *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
450 checkCparams(1);
451 --L->stack.top;
452 if (name) {
453 /* if "name", there must be a LUA_T_LINE */
454 /* therefore, f+2 points to function base */
455 *((f+2)+(local_number-1)) = *L->stack.top;
456 return 1;
457 }
458 else
459 return 0; 478 return 0;
479 else {
480 TObject *f = Address(func);
481 TProtoFunc *fp = luaA_protovalue(f)->value.tf;
482 char *name = luaF_getlocalname(fp, local_number, lua_currentline(func));
483 checkCparams(1);
484 --L->stack.top;
485 if (name) {
486 /* if "name", there must be a LUA_T_LINE */
487 /* therefore, f+2 points to function base */
488 *((f+2)+(local_number-1)) = *L->stack.top;
489 return 1;
490 }
491 else
492 return 0;
493 }
460} 494}
461 495
462 496
@@ -465,7 +499,7 @@ void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
465 if (!lua_isfunction(func)) 499 if (!lua_isfunction(func))
466 lua_error("API - `funcinfo' called with a non-function value"); 500 lua_error("API - `funcinfo' called with a non-function value");
467 else { 501 else {
468 TObject *f = protovalue(Address(func)); 502 TObject *f = luaA_protovalue(Address(func));
469 if (ttype(f) == LUA_T_PROTO) { 503 if (ttype(f) == LUA_T_PROTO) {
470 *filename = tfvalue(f)->fileName->str; 504 *filename = tfvalue(f)->fileName->str;
471 *linedefined = tfvalue(f)->lineDefined; 505 *linedefined = tfvalue(f)->lineDefined;
@@ -548,7 +582,6 @@ static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults)
548 luaD_openstack(nParams); 582 luaD_openstack(nParams);
549 L->stack.stack[base].ttype = LUA_T_CPROTO; 583 L->stack.stack[base].ttype = LUA_T_CPROTO;
550 L->stack.stack[base].value.f = f; 584 L->stack.stack[base].value.f = f;
551 luaF_simpleclosure(L->stack.stack+base);
552 luaD_call(base+1, nResults); 585 luaD_call(base+1, nResults);
553} 586}
554 587