aboutsummaryrefslogtreecommitdiff
path: root/opcode.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-03-19 16:41:10 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-03-19 16:41:10 -0300
commit1444d28476af70bc51c4fdba71deb669f41c77a3 (patch)
tree6d19c5653702ea341f6650f3e917ed77456f757f /opcode.c
parent2de803c250de373186afbbea0a5978f54c52850c (diff)
downloadlua-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.c161
1 files changed, 105 insertions, 56 deletions
diff --git a/opcode.c b/opcode.c
index 86fca402..b20901d9 100644
--- a/opcode.c
+++ b/opcode.c
@@ -3,7 +3,7 @@
3** TecCGraf - PUC-Rio 3** TecCGraf - PUC-Rio
4*/ 4*/
5 5
6char *rcs_opcode="$Id: opcode.c,v 3.83 1997/03/06 17:30:55 roberto Exp roberto $"; 6char *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*/
274static 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)
326static void pushsubscript (void) 317static 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*/
377static void storesubscript (Object *t, int mode) 367static 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
429static void lua_message (char *s) 421static 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
666void 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*/
744lua_Object lua_getparam (int number) 751lua_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
885lua_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*/
945void lua_pushusertag (void *u, int tag) 963void 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
980void luaI_gcFB (Object *o) 998void 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
988static void call_arith (char *op) 1009static 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
1024static 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
1032static 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
994static void comparison (lua_Type ttype_less, lua_Type ttype_equal, 1041static 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);