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 | 94144a7821c0fa412d5d228ab5197a8ebaaa3c25 (patch) | |
tree | 99e21c8935f07c556eb16bed7414211d83234cbd /lapi.c | |
parent | 4daae2165d617e57ad1460471f8d902d38abac6e (diff) | |
download | lua-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.c | 99 |
1 files changed, 66 insertions, 33 deletions
@@ -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 | ||
61 | static TObject *luaA_protovalue (TObject *o) | ||
62 | { | ||
63 | return (ttype(o) == LUA_T_CLOSURE) ? protovalue(o) : o; | ||
64 | } | ||
65 | |||
66 | |||
57 | void luaA_packresults (void) | 67 | void 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 | ||
248 | int lua_iscfunction (lua_Object o) | 258 | int 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 | ||
253 | int lua_isnumber (lua_Object o) | 263 | int lua_isnumber (lua_Object o) |
@@ -263,7 +273,8 @@ int lua_isstring (lua_Object o) | |||
263 | 273 | ||
264 | int lua_isfunction (lua_Object o) | 274 | int 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 | ||
362 | int lua_tag (lua_Object lo) | 373 | int 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; | |||
407 | lua_Function lua_stackedfunction (int level) | 433 | lua_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) | |||
418 | int lua_currentline (lua_Function func) | 446 | int 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 | ||
425 | lua_Object lua_getlocal (lua_Function func, int local_number, char **name) | 454 | lua_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 | ||
445 | int lua_setlocal (lua_Function func, int local_number) | 474 | int 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 | ||