diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-02-26 14:38:41 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-02-26 14:38:41 -0300 |
commit | 131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa (patch) | |
tree | e912e35e04883c24e89917ee3d94b8fa574f6294 /opcode.c | |
parent | bbf1b3060a1aa4e5ec3235a560d3d054457e957d (diff) | |
download | lua-131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa.tar.gz lua-131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa.tar.bz2 lua-131d66efd2dc26b05bcb2bdaf67f5175f3eda1aa.zip |
first step in implementing internal methods.
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: |