diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-03-19 16:41:10 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-03-19 16:41:10 -0300 |
commit | 1444d28476af70bc51c4fdba71deb669f41c77a3 (patch) | |
tree | 6d19c5653702ea341f6650f3e917ed77456f757f /opcode.c | |
parent | 2de803c250de373186afbbea0a5978f54c52850c (diff) | |
download | lua-1444d28476af70bc51c4fdba71deb669f41c77a3.tar.gz lua-1444d28476af70bc51c4fdba71deb669f41c77a3.tar.bz2 lua-1444d28476af70bc51c4fdba71deb669f41c77a3.zip |
first full implementation of internal methods
Diffstat (limited to 'opcode.c')
-rw-r--r-- | opcode.c | 161 |
1 files changed, 105 insertions, 56 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.83 1997/03/06 17:30:55 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 3.84 1997/03/11 18:44:28 roberto Exp roberto $"; |
7 | 7 | ||
8 | #include <setjmp.h> | 8 | #include <setjmp.h> |
9 | #include <stdio.h> | 9 | #include <stdio.h> |
@@ -268,15 +268,6 @@ static void callIM (Object *f, int nParams, int nResults) | |||
268 | do_call((top-stack)-nParams, nResults); | 268 | do_call((top-stack)-nParams, nResults); |
269 | } | 269 | } |
270 | 270 | ||
271 | /* | ||
272 | ** Call the specified fallback, putting it on the stack below its arguments | ||
273 | */ | ||
274 | static void callFB (int fb) | ||
275 | { | ||
276 | callIM(&luaI_fallBacks[fb].function, luaI_fallBacks[fb].nParams, | ||
277 | luaI_fallBacks[fb].nResults); | ||
278 | } | ||
279 | |||
280 | 271 | ||
281 | /* | 272 | /* |
282 | ** Call a function (C or Lua). The parameters must be on the stack, | 273 | ** Call a function (C or Lua). The parameters must be on the stack, |
@@ -289,21 +280,21 @@ static void do_call (StkId base, int nResults) | |||
289 | StkId firstResult; | 280 | StkId firstResult; |
290 | Object *func = stack+base-1; | 281 | Object *func = stack+base-1; |
291 | int i; | 282 | int i; |
292 | if (ttype(func) == LUA_T_CFUNCTION) | 283 | if (ttype(func) == LUA_T_CFUNCTION) { |
293 | { | ||
294 | ttype(func) = LUA_T_CMARK; | 284 | ttype(func) = LUA_T_CMARK; |
295 | firstResult = callC(fvalue(func), base); | 285 | firstResult = callC(fvalue(func), base); |
296 | } | 286 | } |
297 | else if (ttype(func) == LUA_T_FUNCTION) | 287 | else if (ttype(func) == LUA_T_FUNCTION) { |
298 | { | ||
299 | ttype(func) = LUA_T_MARK; | 288 | ttype(func) = LUA_T_MARK; |
300 | firstResult = lua_execute(func->value.tf->code, base); | 289 | firstResult = lua_execute(func->value.tf->code, base); |
301 | } | 290 | } |
302 | else | 291 | else { /* func is not a function */ |
303 | { /* func is not a function */ | 292 | /* Check the fallback for invalid functions */ |
304 | /* Call the fallback for invalid functions */ | 293 | Object *im = luaI_getimbyObj(func, IM_FUNCTION); |
294 | if (ttype(im) == LUA_T_NIL) | ||
295 | lua_error("call expression not a function"); | ||
305 | open_stack((top-stack)-(base-1)); | 296 | open_stack((top-stack)-(base-1)); |
306 | stack[base-1] = luaI_fallBacks[FB_FUNCTION].function; | 297 | stack[base-1] = *im; |
307 | do_call(base, nResults); | 298 | do_call(base, nResults); |
308 | return; | 299 | return; |
309 | } | 300 | } |
@@ -326,15 +317,14 @@ static void do_call (StkId base, int nResults) | |||
326 | static void pushsubscript (void) | 317 | static void pushsubscript (void) |
327 | { | 318 | { |
328 | int tg = luaI_tag(top-2); | 319 | int tg = luaI_tag(top-2); |
329 | Object *im = luaI_getim(tg, FB_GETTABLE); | 320 | Object *im = luaI_getim(tg, IM_GETTABLE); |
330 | if (ttype(top-2) == LUA_T_ARRAY && im == NULL) { | 321 | if (ttype(top-2) == LUA_T_ARRAY && ttype(im) == LUA_T_NIL) { |
331 | Object *h = lua_hashget(avalue(top-2), top-1); | 322 | Object *h = lua_hashget(avalue(top-2), top-1); |
332 | if (h != NULL && ttype(h) != LUA_T_NIL) { | 323 | if (h != NULL && ttype(h) != LUA_T_NIL) { |
333 | --top; | 324 | --top; |
334 | *(top-1) = *h; | 325 | *(top-1) = *h; |
335 | } | 326 | } |
336 | else if (tg == LUA_T_ARRAY && | 327 | else if (ttype(im=luaI_getim(tg, IM_INDEX)) != LUA_T_NIL) |
337 | (im=luaI_getim(0, FB_INDEX)) != NULL) | ||
338 | callIM(im, 2, 1); | 328 | callIM(im, 2, 1); |
339 | else { | 329 | else { |
340 | --top; | 330 | --top; |
@@ -376,14 +366,14 @@ lua_Object lua_basicindex (void) | |||
376 | */ | 366 | */ |
377 | static void storesubscript (Object *t, int mode) | 367 | static void storesubscript (Object *t, int mode) |
378 | { | 368 | { |
379 | Object *im = (mode == 0) ? NULL : luaI_getim(luaI_tag(t), FB_SETTABLE); | 369 | Object *im = (mode == 0) ? NULL : luaI_getimbyObj(t, IM_SETTABLE); |
380 | if (ttype(t) == LUA_T_ARRAY && im == NULL) { | 370 | if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) { |
381 | Object *h = lua_hashdefine(avalue(t), t+1); | 371 | Object *h = lua_hashdefine(avalue(t), t+1); |
382 | *h = *(top-1); | 372 | *h = *(top-1); |
383 | top -= (mode == 2) ? 1 : 3; | 373 | top -= (mode == 2) ? 1 : 3; |
384 | } | 374 | } |
385 | else { /* object is not a table, and/or has a specific "settable" method */ | 375 | else { /* object is not a table, and/or has a specific "settable" method */ |
386 | if (im) { | 376 | if (im && ttype(im) != LUA_T_NIL) { |
387 | if (mode == 2) { | 377 | if (mode == 2) { |
388 | lua_checkstack(top+2); | 378 | lua_checkstack(top+2); |
389 | *(top+1) = *(top-1); | 379 | *(top+1) = *(top-1); |
@@ -403,11 +393,13 @@ static void getglobal (Word n) | |||
403 | { | 393 | { |
404 | *top = lua_table[n].object; | 394 | *top = lua_table[n].object; |
405 | incr_top; | 395 | incr_top; |
406 | if (ttype(top-1) == LUA_T_NIL) | 396 | if (ttype(top-1) == LUA_T_NIL) { /* check i.m. */ |
407 | { /* must call getglobal fallback */ | 397 | Object *im = luaI_getgim(GIM_GETGLOBAL); |
408 | ttype(top-1) = LUA_T_STRING; | 398 | if (ttype(im) != LUA_T_NIL) { |
409 | tsvalue(top-1) = lua_table[n].varname; | 399 | ttype(top-1) = LUA_T_STRING; |
410 | callFB(FB_GETGLOBAL); | 400 | tsvalue(top-1) = lua_table[n].varname; |
401 | callIM(im, 1, 1); | ||
402 | } | ||
411 | } | 403 | } |
412 | } | 404 | } |
413 | 405 | ||
@@ -428,8 +420,13 @@ void lua_travstack (int (*fn)(Object *)) | |||
428 | 420 | ||
429 | static void lua_message (char *s) | 421 | static void lua_message (char *s) |
430 | { | 422 | { |
431 | lua_pushstring(s); | 423 | Object *im = luaI_getgim(GIM_ERROR); |
432 | callFB(FB_ERROR); | 424 | if (ttype(im) == LUA_T_NIL) |
425 | fprintf(stderr, "lua: %s\n", s); | ||
426 | else { | ||
427 | lua_pushstring(s); | ||
428 | callIM(im, 1, 0); | ||
429 | } | ||
433 | } | 430 | } |
434 | 431 | ||
435 | /* | 432 | /* |
@@ -659,10 +656,20 @@ void lua_setintmethod (int tag, char *event, lua_CFunction method) | |||
659 | { | 656 | { |
660 | lua_pushnumber(tag); | 657 | lua_pushnumber(tag); |
661 | lua_pushstring(event); | 658 | lua_pushstring(event); |
662 | lua_pushcfunction (method); | 659 | if (method) |
660 | lua_pushcfunction (method); | ||
661 | else | ||
662 | lua_pushnil(); | ||
663 | do_unprotectedrun(luaI_setintmethod, 3, 0); | 663 | do_unprotectedrun(luaI_setintmethod, 3, 0); |
664 | } | 664 | } |
665 | 665 | ||
666 | void lua_setglobalmethod (char *event, lua_CFunction method) | ||
667 | { | ||
668 | lua_pushstring(event); | ||
669 | lua_pushcfunction (method); | ||
670 | do_unprotectedrun(luaI_setglobalmethod, 3, 0); | ||
671 | } | ||
672 | |||
666 | 673 | ||
667 | /* | 674 | /* |
668 | ** API: receives on the stack the table and the index. | 675 | ** API: receives on the stack the table and the index. |
@@ -741,7 +748,7 @@ lua_Object lua_createtable (void) | |||
741 | ** Get a parameter, returning the object handle or LUA_NOOBJECT on error. | 748 | ** Get a parameter, returning the object handle or LUA_NOOBJECT on error. |
742 | ** 'number' must be 1 to get the first parameter. | 749 | ** 'number' must be 1 to get the first parameter. |
743 | */ | 750 | */ |
744 | lua_Object lua_getparam (int number) | 751 | lua_Object lua_lua2C (int number) |
745 | { | 752 | { |
746 | if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT; | 753 | if (number <= 0 || number > CLS_current.num) return LUA_NOOBJECT; |
747 | /* Ref(stack+(CLS_current.base-CLS_current.num+number-1)) == | 754 | /* Ref(stack+(CLS_current.base-CLS_current.num+number-1)) == |
@@ -874,6 +881,17 @@ lua_Object lua_getglobal (char *name) | |||
874 | return Ref(top-1); | 881 | return Ref(top-1); |
875 | } | 882 | } |
876 | 883 | ||
884 | |||
885 | lua_Object lua_basicgetglobal (char *name) | ||
886 | { | ||
887 | adjustC(0); | ||
888 | *top = lua_table[luaI_findsymbolbyname(name)].object; | ||
889 | incr_top; | ||
890 | CLS_current.base++; /* incorporate object in the stack */ | ||
891 | return Ref(top-1); | ||
892 | } | ||
893 | |||
894 | |||
877 | /* | 895 | /* |
878 | ** Store top of the stack at a global variable array field. | 896 | ** Store top of the stack at a global variable array field. |
879 | */ | 897 | */ |
@@ -944,7 +962,7 @@ void lua_pushbinarydata (void *buff, int size, int tag) | |||
944 | */ | 962 | */ |
945 | void lua_pushusertag (void *u, int tag) | 963 | void lua_pushusertag (void *u, int tag) |
946 | { | 964 | { |
947 | if (tag < LUA_T_USERDATA) | 965 | if (luaI_typetag(tag) != LUA_T_USERDATA) |
948 | lua_error("invalid tag in `lua_pushusertag'"); | 966 | lua_error("invalid tag in `lua_pushusertag'"); |
949 | lua_pushbinarydata(&u, sizeof(void *), tag); | 967 | lua_pushbinarydata(&u, sizeof(void *), tag); |
950 | } | 968 | } |
@@ -977,18 +995,47 @@ int lua_tag (lua_Object o) | |||
977 | } | 995 | } |
978 | 996 | ||
979 | 997 | ||
980 | void luaI_gcFB (Object *o) | 998 | void luaI_gcIM (Object *o) |
981 | { | 999 | { |
982 | *top = *o; | 1000 | Object *im = luaI_getimbyObj(o, IM_GC); |
983 | incr_top; | 1001 | if (ttype(im) != LUA_T_NIL) { |
984 | callFB(FB_GC); | 1002 | *top = *o; |
1003 | incr_top; | ||
1004 | callIM(im, 1, 0); | ||
1005 | } | ||
985 | } | 1006 | } |
986 | 1007 | ||
987 | 1008 | ||
988 | static void call_arith (char *op) | 1009 | static void call_arith (char *op) |
989 | { | 1010 | { |
1011 | Object *im = luaI_getimbyObj(top-2, IM_ARITH); /* try first operand */ | ||
1012 | if (ttype(im) == LUA_T_NIL) { | ||
1013 | im = luaI_getimbyObj(top-1, IM_ARITH); /* try second operand */ | ||
1014 | if (ttype(im) == LUA_T_NIL) { | ||
1015 | im = luaI_getim(0, IM_ARITH); /* try a 'global' i.m. */ | ||
1016 | if (ttype(im) == LUA_T_NIL) | ||
1017 | lua_error("unexpected type at conversion to number"); | ||
1018 | } | ||
1019 | } | ||
990 | lua_pushstring(op); | 1020 | lua_pushstring(op); |
991 | callFB(FB_ARITH); | 1021 | callIM(im, 3, 1); |
1022 | } | ||
1023 | |||
1024 | static void concim (Object *o) | ||
1025 | { | ||
1026 | Object *im = luaI_getimbyObj(o, IM_CONCAT); | ||
1027 | if (ttype(im) == LUA_T_NIL) | ||
1028 | lua_error("unexpected type at conversion to string"); | ||
1029 | callIM(im, 2, 1); | ||
1030 | } | ||
1031 | |||
1032 | static void ordim (Object *o, char *op) | ||
1033 | { | ||
1034 | Object *im = luaI_getimbyObj(o, IM_ORDER); | ||
1035 | if (ttype(im) == LUA_T_NIL) | ||
1036 | lua_error("unexpected type at comparison"); | ||
1037 | lua_pushstring(op); | ||
1038 | callIM(im, 3, 1); | ||
992 | } | 1039 | } |
993 | 1040 | ||
994 | static void comparison (lua_Type ttype_less, lua_Type ttype_equal, | 1041 | static void comparison (lua_Type ttype_less, lua_Type ttype_equal, |
@@ -999,10 +1046,12 @@ static void comparison (lua_Type ttype_less, lua_Type ttype_equal, | |||
999 | int result; | 1046 | int result; |
1000 | if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) | 1047 | if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) |
1001 | result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; | 1048 | result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; |
1002 | else if (tostring(l) || tostring(r)) | 1049 | else if (tostring(l)) { |
1003 | { | 1050 | ordim(l, op); |
1004 | lua_pushstring(op); | 1051 | return; |
1005 | callFB(FB_ORDER); | 1052 | } |
1053 | else if (tostring(r)) { | ||
1054 | ordim(r, op); | ||
1006 | return; | 1055 | return; |
1007 | } | 1056 | } |
1008 | else | 1057 | else |
@@ -1318,17 +1367,17 @@ static StkId lua_execute (Byte *pc, StkId base) | |||
1318 | call_arith("pow"); | 1367 | call_arith("pow"); |
1319 | break; | 1368 | break; |
1320 | 1369 | ||
1321 | case CONCOP: | 1370 | case CONCOP: { |
1322 | { | 1371 | Object *l = top-2; |
1323 | Object *l = top-2; | 1372 | Object *r = top-1; |
1324 | Object *r = top-1; | 1373 | if (tostring(l)) /* first argument is not a string */ |
1325 | if (tostring(r) || tostring(l)) | 1374 | concim(l); |
1326 | callFB(FB_CONCAT); | 1375 | else if (tostring(r)) /* second argument is not a string */ |
1327 | else | 1376 | concim(r); |
1328 | { | 1377 | else { |
1329 | tsvalue(l) = lua_createstring (lua_strconc(svalue(l),svalue(r))); | 1378 | tsvalue(l) = lua_createstring(lua_strconc(svalue(l),svalue(r))); |
1330 | --top; | 1379 | --top; |
1331 | } | 1380 | } |
1332 | } | 1381 | } |
1333 | break; | 1382 | break; |
1334 | 1383 | ||
@@ -1356,7 +1405,7 @@ static StkId lua_execute (Byte *pc, StkId base) | |||
1356 | } | 1405 | } |
1357 | break; | 1406 | break; |
1358 | 1407 | ||
1359 | case ONFJMP: | 1408 | case ONFJMP: |
1360 | { | 1409 | { |
1361 | Word w; | 1410 | Word w; |
1362 | get_word(w,pc); | 1411 | get_word(w,pc); |