diff options
Diffstat (limited to 'opcode.c')
| -rw-r--r-- | opcode.c | 196 |
1 files changed, 126 insertions, 70 deletions
| @@ -3,7 +3,7 @@ | |||
| 3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | char *rcs_opcode="$Id: opcode.c,v 3.80 1997/02/11 11:35:05 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 3.81 1997/02/20 15:51:14 roberto Exp roberto $"; |
| 7 | 7 | ||
| 8 | #include <setjmp.h> | 8 | #include <setjmp.h> |
| 9 | #include <stdio.h> | 9 | #include <stdio.h> |
| @@ -261,15 +261,20 @@ static StkId callC (lua_CFunction func, StkId base) | |||
| 261 | return firstResult; | 261 | return firstResult; |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | static void callIM (Object *f, int nParams, int nResults) | ||
| 265 | { | ||
| 266 | open_stack(nParams); | ||
| 267 | *(top-nParams-1) = *f; | ||
| 268 | do_call((top-stack)-nParams, nResults); | ||
| 269 | } | ||
| 270 | |||
| 264 | /* | 271 | /* |
| 265 | ** Call the specified fallback, putting it on the stack below its arguments | 272 | ** Call the specified fallback, putting it on the stack below its arguments |
| 266 | */ | 273 | */ |
| 267 | static void callFB (int fb) | 274 | static void callFB (int fb) |
| 268 | { | 275 | { |
| 269 | int nParams = luaI_fallBacks[fb].nParams; | 276 | callIM(&luaI_fallBacks[fb].function, luaI_fallBacks[fb].nParams, |
| 270 | open_stack(nParams); | 277 | luaI_fallBacks[fb].nResults); |
| 271 | *(top-nParams-1) = luaI_fallBacks[fb].function; | ||
| 272 | do_call((top-stack)-nParams, luaI_fallBacks[fb].nResults); | ||
| 273 | } | 278 | } |
| 274 | 279 | ||
| 275 | 280 | ||
| @@ -320,35 +325,77 @@ static void do_call (StkId base, int nResults) | |||
| 320 | */ | 325 | */ |
| 321 | static void pushsubscript (void) | 326 | static void pushsubscript (void) |
| 322 | { | 327 | { |
| 328 | int tg = luaI_tag(top-2); | ||
| 329 | Object *im = luaI_getim(tg, FB_GETTABLE); | ||
| 330 | if (tag(top-2) == LUA_T_ARRAY && im == NULL) { | ||
| 331 | Object *h = lua_hashget(avalue(top-2), top-1); | ||
| 332 | if (h != NULL && tag(h) != LUA_T_NIL) { | ||
| 333 | --top; | ||
| 334 | *(top-1) = *h; | ||
| 335 | } | ||
| 336 | else if (tg == LUA_T_ARRAY && | ||
| 337 | (im=luaI_getim(0, FB_INDEX)) != NULL) | ||
| 338 | callIM(im, 2, 1); | ||
| 339 | else { | ||
| 340 | --top; | ||
| 341 | tag(top-1) = LUA_T_NIL; | ||
| 342 | } | ||
| 343 | } | ||
| 344 | else { /* object is not a table, and/or has a specific "gettable" method */ | ||
| 345 | if (im) | ||
| 346 | callIM(im, 2, 1); | ||
| 347 | else | ||
| 348 | lua_error("indexed expression not a table"); | ||
| 349 | } | ||
| 350 | } | ||
| 351 | |||
| 352 | |||
| 353 | lua_Object lua_basicindex (void) | ||
| 354 | { | ||
| 355 | adjustC(2); | ||
| 323 | if (tag(top-2) != LUA_T_ARRAY) | 356 | if (tag(top-2) != LUA_T_ARRAY) |
| 324 | callFB(FB_GETTABLE); | 357 | lua_error("indexed expression not a table in basic indexing"); |
| 325 | else | 358 | else { |
| 326 | { | ||
| 327 | Object *h = lua_hashget(avalue(top-2), top-1); | 359 | Object *h = lua_hashget(avalue(top-2), top-1); |
| 328 | if (h == NULL || tag(h) == LUA_T_NIL) | 360 | --top; |
| 329 | callFB(FB_INDEX); | 361 | if (h != NULL) |
| 330 | else | ||
| 331 | { | ||
| 332 | --top; | ||
| 333 | *(top-1) = *h; | 362 | *(top-1) = *h; |
| 334 | } | 363 | else |
| 364 | tag(top-1) = LUA_T_NIL; | ||
| 335 | } | 365 | } |
| 366 | CLS_current.base++; /* incorporate object in the stack */ | ||
| 367 | return (Ref(top-1)); | ||
| 336 | } | 368 | } |
| 337 | 369 | ||
| 338 | 370 | ||
| 339 | /* | 371 | /* |
| 340 | ** Function to store indexed based on values at the top | 372 | ** Function to store indexed based on values at the top |
| 373 | ** mode = 0: basic store (without internal methods) | ||
| 374 | ** mode = 1: normal store (with internal methods) | ||
| 375 | ** mode = 2: "deep stack" store (with internal methods) | ||
| 341 | */ | 376 | */ |
| 342 | static void storesubscript (void) | 377 | static void storesubscript (Object *t, int mode) |
| 343 | { | 378 | { |
| 344 | if (tag(top-3) != LUA_T_ARRAY) | 379 | Object *im = (mode == 0) ? NULL : luaI_getim(luaI_tag(t), FB_SETTABLE); |
| 345 | callFB(FB_SETTABLE); | 380 | if (tag(t) == LUA_T_ARRAY && im == NULL) { |
| 346 | else | 381 | Object *h = lua_hashdefine(avalue(t), t+1); |
| 347 | { | 382 | *h = *(top-1); |
| 348 | Object *h = lua_hashdefine (avalue(top-3), top-2); | 383 | top -= (mode == 2) ? 1 : 3; |
| 349 | *h = *(top-1); | 384 | } |
| 350 | top -= 3; | 385 | else { /* object is not a table, and/or has a specific "settable" method */ |
| 351 | } | 386 | if (im) { |
| 387 | if (mode == 2) { | ||
| 388 | lua_checkstack(top+2); | ||
| 389 | *(top+1) = *(top-1); | ||
| 390 | *(top) = *(t+1); | ||
| 391 | *(top-1) = *t; | ||
| 392 | top += 2; | ||
| 393 | } | ||
| 394 | callIM(im, 3, 0); | ||
| 395 | } | ||
| 396 | else | ||
| 397 | lua_error("indexed expression not a table"); | ||
| 398 | } | ||
| 352 | } | 399 | } |
| 353 | 400 | ||
| 354 | 401 | ||
| @@ -450,6 +497,26 @@ int lua_setlocal (lua_Function func, int local_number) | |||
| 450 | return 0; | 497 | return 0; |
| 451 | } | 498 | } |
| 452 | 499 | ||
| 500 | /* | ||
| 501 | ** Call the function at CLS_current.base, and incorporate results on | ||
| 502 | ** the Lua2C structure. | ||
| 503 | */ | ||
| 504 | static void do_callinc (int nResults) | ||
| 505 | { | ||
| 506 | do_call(CLS_current.base+1, nResults); | ||
| 507 | CLS_current.num = (top-stack) - CLS_current.base; /* number of results */ | ||
| 508 | CLS_current.base += CLS_current.num; /* incorporate results on the stack */ | ||
| 509 | } | ||
| 510 | |||
| 511 | static void do_unprotectedrun (lua_CFunction f, int nParams, int nResults) | ||
| 512 | { | ||
| 513 | adjustC(nParams); | ||
| 514 | open_stack((top-stack)-CLS_current.base); | ||
| 515 | stack[CLS_current.base].tag = LUA_T_CFUNCTION; | ||
| 516 | stack[CLS_current.base].value.f = f; | ||
| 517 | do_callinc(nResults); | ||
| 518 | } | ||
| 519 | |||
| 453 | 520 | ||
| 454 | /* | 521 | /* |
| 455 | ** Execute a protected call. Assumes that function is at CLS_current.base and | 522 | ** Execute a protected call. Assumes that function is at CLS_current.base and |
| @@ -462,15 +529,11 @@ static int do_protectedrun (int nResults) | |||
| 462 | struct C_Lua_Stack oldCLS = CLS_current; | 529 | struct C_Lua_Stack oldCLS = CLS_current; |
| 463 | jmp_buf *oldErr = errorJmp; | 530 | jmp_buf *oldErr = errorJmp; |
| 464 | errorJmp = &myErrorJmp; | 531 | errorJmp = &myErrorJmp; |
| 465 | if (setjmp(myErrorJmp) == 0) | 532 | if (setjmp(myErrorJmp) == 0) { |
| 466 | { | 533 | do_callinc(nResults); |
| 467 | do_call(CLS_current.base+1, nResults); | ||
| 468 | CLS_current.num = (top-stack) - CLS_current.base; /* number of results */ | ||
| 469 | CLS_current.base += CLS_current.num; /* incorporate results on the stack */ | ||
| 470 | status = 0; | 534 | status = 0; |
| 471 | } | 535 | } |
| 472 | else | 536 | else { /* an error occurred: restore CLS_current and top */ |
| 473 | { /* an error occurred: restore CLS_current and top */ | ||
| 474 | CLS_current = oldCLS; | 537 | CLS_current = oldCLS; |
| 475 | top = stack+CLS_current.base; | 538 | top = stack+CLS_current.base; |
| 476 | status = 1; | 539 | status = 1; |
| @@ -586,15 +649,18 @@ int lua_dostring (char *str) | |||
| 586 | */ | 649 | */ |
| 587 | lua_Object lua_setfallback (char *name, lua_CFunction fallback) | 650 | lua_Object lua_setfallback (char *name, lua_CFunction fallback) |
| 588 | { | 651 | { |
| 589 | adjustC(1); /* one slot for the pseudo-function */ | ||
| 590 | stack[CLS_current.base].tag = LUA_T_CFUNCTION; | ||
| 591 | stack[CLS_current.base].value.f = luaI_setfallback; | ||
| 592 | lua_pushstring(name); | 652 | lua_pushstring(name); |
| 593 | lua_pushcfunction(fallback); | 653 | lua_pushcfunction(fallback); |
| 594 | if (do_protectedrun(1) == 0) | 654 | do_unprotectedrun(luaI_setfallback, 2, 1); |
| 595 | return (Ref(top-1)); | 655 | return (Ref(top-1)); |
| 596 | else | 656 | } |
| 597 | return LUA_NOOBJECT; | 657 | |
| 658 | void lua_setintmethod (int tag, char *event, lua_CFunction method) | ||
| 659 | { | ||
| 660 | lua_pushnumber(tag); | ||
| 661 | lua_pushstring(event); | ||
| 662 | lua_pushcfunction (method); | ||
| 663 | do_unprotectedrun(luaI_setintmethod, 3, 0); | ||
| 598 | } | 664 | } |
| 599 | 665 | ||
| 600 | 666 | ||
| @@ -637,13 +703,25 @@ void lua_endblock (void) | |||
| 637 | adjustC(0); | 703 | adjustC(0); |
| 638 | } | 704 | } |
| 639 | 705 | ||
| 706 | void lua_settag (int tag) | ||
| 707 | { | ||
| 708 | adjustC(1); | ||
| 709 | luaI_settag(tag, --top); | ||
| 710 | } | ||
| 711 | |||
| 640 | /* | 712 | /* |
| 641 | ** API: receives on the stack the table, the index, and the new value. | 713 | ** API: receives on the stack the table, the index, and the new value. |
| 642 | */ | 714 | */ |
| 643 | void lua_storesubscript (void) | 715 | void lua_storesubscript (void) |
| 644 | { | 716 | { |
| 645 | adjustC(3); | 717 | adjustC(3); |
| 646 | storesubscript(); | 718 | storesubscript(top-3, 1); |
| 719 | } | ||
| 720 | |||
| 721 | void lua_basicstoreindex (void) | ||
| 722 | { | ||
| 723 | adjustC(3); | ||
| 724 | storesubscript(top-3, 0); | ||
| 647 | } | 725 | } |
| 648 | 726 | ||
| 649 | /* | 727 | /* |
| @@ -688,7 +766,7 @@ int lua_isuserdata (lua_Object o) | |||
| 688 | 766 | ||
| 689 | int lua_iscfunction (lua_Object o) | 767 | int lua_iscfunction (lua_Object o) |
| 690 | { | 768 | { |
| 691 | int t = lua_type(o); | 769 | int t = lua_tag(o); |
| 692 | return (t == LUA_T_CMARK) || (t == LUA_T_CFUNCTION); | 770 | return (t == LUA_T_CMARK) || (t == LUA_T_CFUNCTION); |
| 693 | } | 771 | } |
| 694 | 772 | ||
| @@ -699,13 +777,13 @@ int lua_isnumber (lua_Object o) | |||
| 699 | 777 | ||
| 700 | int lua_isstring (lua_Object o) | 778 | int lua_isstring (lua_Object o) |
| 701 | { | 779 | { |
| 702 | int t = lua_type(o); | 780 | int t = lua_tag(o); |
| 703 | return (t == LUA_T_STRING) || (t == LUA_T_NUMBER); | 781 | return (t == LUA_T_STRING) || (t == LUA_T_NUMBER); |
| 704 | } | 782 | } |
| 705 | 783 | ||
| 706 | int lua_isfunction (lua_Object o) | 784 | int lua_isfunction (lua_Object o) |
| 707 | { | 785 | { |
| 708 | int t = lua_type(o); | 786 | int t = lua_tag(o); |
| 709 | return (t == LUA_T_FUNCTION) || (t == LUA_T_CFUNCTION) || | 787 | return (t == LUA_T_FUNCTION) || (t == LUA_T_CFUNCTION) || |
| 710 | (t == LUA_T_MARK) || (t == LUA_T_CMARK); | 788 | (t == LUA_T_MARK) || (t == LUA_T_CMARK); |
| 711 | } | 789 | } |
| @@ -893,16 +971,9 @@ void lua_pushobject (lua_Object o) | |||
| 893 | incr_top; | 971 | incr_top; |
| 894 | } | 972 | } |
| 895 | 973 | ||
| 896 | int lua_type (lua_Object o) | 974 | int lua_tag (lua_Object o) |
| 897 | { | 975 | { |
| 898 | if (o == LUA_NOOBJECT) | 976 | return (o == LUA_NOOBJECT) ? LUA_T_NIL : luaI_tag(Address(o)); |
| 899 | return LUA_T_NIL; | ||
| 900 | else { | ||
| 901 | lua_Type t = tag(Address(o)); | ||
| 902 | if (t == LUA_T_USERDATA) | ||
| 903 | return (Address(o))->value.ts->tag; | ||
| 904 | else return t; | ||
| 905 | } | ||
| 906 | } | 977 | } |
| 907 | 978 | ||
| 908 | 979 | ||
| @@ -1085,29 +1156,14 @@ static StkId lua_execute (Byte *pc, StkId base) | |||
| 1085 | break; | 1156 | break; |
| 1086 | 1157 | ||
| 1087 | case STOREINDEXED0: | 1158 | case STOREINDEXED0: |
| 1088 | storesubscript(); | 1159 | storesubscript(top-3, 1); |
| 1089 | break; | 1160 | break; |
| 1090 | 1161 | ||
| 1091 | case STOREINDEXED: | 1162 | case STOREINDEXED: { |
| 1092 | { | 1163 | int n = *pc++; |
| 1093 | int n = *pc++; | 1164 | storesubscript(top-3-n, 2); |
| 1094 | if (tag(top-3-n) != LUA_T_ARRAY) | 1165 | break; |
| 1095 | { | ||
| 1096 | lua_checkstack(top+2); | ||
| 1097 | *(top+1) = *(top-1); | ||
| 1098 | *(top) = *(top-2-n); | ||
| 1099 | *(top-1) = *(top-3-n); | ||
| 1100 | top += 2; | ||
| 1101 | callFB(FB_SETTABLE); | ||
| 1102 | } | ||
| 1103 | else | ||
| 1104 | { | ||
| 1105 | Object *h = lua_hashdefine (avalue(top-3-n), top-2-n); | ||
| 1106 | *h = *(top-1); | ||
| 1107 | top--; | ||
| 1108 | } | ||
| 1109 | } | 1166 | } |
| 1110 | break; | ||
| 1111 | 1167 | ||
| 1112 | case STORELIST0: | 1168 | case STORELIST0: |
| 1113 | case STORELIST: | 1169 | case STORELIST: |
