aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lbaselib.c20
-rw-r--r--lcode.c63
-rw-r--r--lcode.h4
-rw-r--r--ljumptab.h2
-rw-r--r--llex.c4
-rw-r--r--llex.h4
-rw-r--r--lopcodes.c6
-rw-r--r--lopcodes.h5
-rw-r--r--lparser.c29
-rw-r--r--lparser.h5
-rw-r--r--lvm.c14
11 files changed, 113 insertions, 43 deletions
diff --git a/lbaselib.c b/lbaselib.c
index 477d44d2..12a9e888 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.321 2018/02/27 17:48:28 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.322 2018/02/27 18:47:32 roberto Exp roberto $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -170,22 +170,6 @@ static int luaB_rawset (lua_State *L) {
170} 170}
171 171
172 172
173static int luaB_keyin (lua_State *L) {
174 luaL_checkany(L, 2); /* ensures a first argument too */
175 lua_settop(L, 2);
176 lua_pushboolean(L, lua_keyin(L, 1));
177 return 1;
178}
179
180
181static int luaB_removekey (lua_State *L) {
182 luaL_checkany(L, 2); /* ensures a first argument too */
183 lua_settop(L, 2);
184 lua_removekey(L, 1);
185 return 0;
186}
187
188
189static int pushmode (lua_State *L, int oldmode) { 173static int pushmode (lua_State *L, int oldmode) {
190 lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" : "generational"); 174 lua_pushstring(L, (oldmode == LUA_GCINC) ? "incremental" : "generational");
191 return 1; 175 return 1;
@@ -503,8 +487,6 @@ static const luaL_Reg base_funcs[] = {
503 {"rawlen", luaB_rawlen}, 487 {"rawlen", luaB_rawlen},
504 {"rawget", luaB_rawget}, 488 {"rawget", luaB_rawget},
505 {"rawset", luaB_rawset}, 489 {"rawset", luaB_rawset},
506 {"keyin", luaB_keyin},
507 {"removekey", luaB_removekey},
508 {"select", luaB_select}, 490 {"select", luaB_select},
509 {"setmetatable", luaB_setmetatable}, 491 {"setmetatable", luaB_setmetatable},
510 {"tonumber", luaB_tonumber}, 492 {"tonumber", luaB_tonumber},
diff --git a/lcode.c b/lcode.c
index 8f3c68c0..95e87f31 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.157 2018/02/21 15:49:32 roberto Exp roberto $ 2** $Id: lcode.c,v 2.158 2018/02/26 14:16:05 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -40,6 +40,14 @@
40static int codesJ (FuncState *fs, OpCode o, int sj, int k); 40static int codesJ (FuncState *fs, OpCode o, int sj, int k);
41 41
42 42
43
44/* semantic error */
45l_noret luaK_semerror (LexState *ls, const char *msg) {
46 ls->t.token = 0; /* remove "near <token>" from final message */
47 luaX_syntaxerror(ls, msg);
48}
49
50
43/* 51/*
44** If expression is a numeric constant, fills 'v' with its value 52** If expression is a numeric constant, fills 'v' with its value
45** and returns 1. Otherwise, returns 0. 53** and returns 1. Otherwise, returns 0.
@@ -670,6 +678,10 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
670 e->k = VNONRELOC; /* becomes a non-relocatable value */ 678 e->k = VNONRELOC; /* becomes a non-relocatable value */
671 break; 679 break;
672 } 680 }
681 case VUNDEF: { /* not a real expression */
682 luaK_semerror(fs->ls, "'undef' is not a value!!");
683 break;
684 }
673 case VUPVAL: { /* move value to some (pending) register */ 685 case VUPVAL: { /* move value to some (pending) register */
674 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); 686 e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
675 e->k = VRELOC; 687 e->k = VRELOC;
@@ -1398,6 +1410,48 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1398} 1410}
1399 1411
1400 1412
1413static void normalizeindexed (FuncState *fs, expdesc *v) {
1414 if (v->k != VINDEXED) { /* not in proper form? */
1415 int key = fs->freereg; /* register with key value */
1416 luaK_reserveregs(fs, 1);
1417 switch (v->k) {
1418 case VINDEXI:
1419 luaK_int(fs, key, v->u.ind.idx);
1420 break;
1421 case VINDEXSTR:
1422 luaK_codek(fs, key, v->u.ind.idx);
1423 break;
1424 case VINDEXUP:
1425 luaK_codek(fs, key, v->u.ind.idx);
1426 luaK_codeABC(fs, OP_GETUPVAL, fs->freereg, v->u.ind.t, 0);
1427 v->u.ind.t = fs->freereg;
1428 luaK_reserveregs(fs, 1); /* one more register for the upvalue */
1429 break;
1430 default:
1431 luaK_semerror(fs->ls, "'undef' is not a value!!");
1432 break;
1433 }
1434 v->u.ind.idx = key;
1435 v->k = VINDEXED;
1436 }
1437 freeregs(fs, v->u.ind.t, v->u.ind.idx);
1438}
1439
1440
1441static void codeisdef (FuncState *fs, int eq, expdesc *v) {
1442 normalizeindexed(fs, v);
1443 v->u.info = luaK_codeABCk(fs, OP_ISDEF, 0, v->u.ind.t, v->u.ind.idx, eq);
1444 v->k = VRELOC;
1445}
1446
1447
1448void luaK_codeundef (FuncState *fs, expdesc *v) {
1449 normalizeindexed(fs, v);
1450 v->u.info = luaK_codeABC(fs, OP_UNDEF, v->u.ind.t, v->u.ind.idx, 0);
1451 v->k = VRELOC;
1452}
1453
1454
1401/* 1455/*
1402** Apply prefix operation 'op' to expression 'e'. 1456** Apply prefix operation 'op' to expression 'e'.
1403*/ 1457*/
@@ -1446,7 +1500,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1446 break; 1500 break;
1447 } 1501 }
1448 case OPR_EQ: case OPR_NE: { 1502 case OPR_EQ: case OPR_NE: {
1449 if (!tonumeral(v, NULL)) 1503 if (!tonumeral(v, NULL) && fs->ls->t.token != TK_UNDEF)
1450 luaK_exp2RK(fs, v); 1504 luaK_exp2RK(fs, v);
1451 /* else keep numeral, which may be an immediate operand */ 1505 /* else keep numeral, which may be an immediate operand */
1452 break; 1506 break;
@@ -1543,7 +1597,10 @@ void luaK_posfix (FuncState *fs, BinOpr opr,
1543 break; 1597 break;
1544 } 1598 }
1545 case OPR_EQ: case OPR_NE: { 1599 case OPR_EQ: case OPR_NE: {
1546 codeeq(fs, opr, e1, e2); 1600 if (e2->k == VUNDEF)
1601 codeisdef(fs, opr == OPR_NE, e1);
1602 else
1603 codeeq(fs, opr, e1, e2);
1547 break; 1604 break;
1548 } 1605 }
1549 case OPR_LT: case OPR_LE: { 1606 case OPR_LT: case OPR_LE: {
diff --git a/lcode.h b/lcode.h
index beeba54f..e7c294d4 100644
--- a/lcode.h
+++ b/lcode.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.h,v 1.69 2017/11/30 13:29:18 roberto Exp roberto $ 2** $Id: lcode.h,v 1.70 2017/12/18 15:44:44 roberto Exp roberto $
3** Code generator for Lua 3** Code generator for Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -89,6 +89,8 @@ LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
89 expdesc *v2, int line); 89 expdesc *v2, int line);
90LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 90LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
91LUAI_FUNC void luaK_finish (FuncState *fs); 91LUAI_FUNC void luaK_finish (FuncState *fs);
92LUAI_FUNC void luaK_codeundef (FuncState *fs, expdesc *e);
93LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg);
92 94
93 95
94#endif 96#endif
diff --git a/ljumptab.h b/ljumptab.h
index ac6a0357..f9783ffb 100644
--- a/ljumptab.h
+++ b/ljumptab.h
@@ -78,6 +78,8 @@ static void *disptab[] = {
78&&L_OP_GEI, 78&&L_OP_GEI,
79&&L_OP_TEST, 79&&L_OP_TEST,
80&&L_OP_TESTSET, 80&&L_OP_TESTSET,
81&&L_OP_UNDEF,
82&&L_OP_ISDEF,
81&&L_OP_CALL, 83&&L_OP_CALL,
82&&L_OP_TAILCALL, 84&&L_OP_TAILCALL,
83&&L_OP_RETURN, 85&&L_OP_RETURN,
diff --git a/llex.c b/llex.c
index 5d5efb07..7e59eb49 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.c,v 2.99 2018/01/28 15:13:26 roberto Exp roberto $ 2** $Id: llex.c,v 2.100 2018/02/23 13:13:31 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -41,7 +41,7 @@ static const char *const luaX_tokens [] = {
41 "and", "break", "do", "else", "elseif", 41 "and", "break", "do", "else", "elseif",
42 "end", "false", "for", "function", "goto", "if", 42 "end", "false", "for", "function", "goto", "if",
43 "in", "local", "nil", "not", "or", "repeat", 43 "in", "local", "nil", "not", "or", "repeat",
44 "return", "then", "true", "until", "while", 44 "return", "then", "true", "undef", "until", "while",
45 "//", "..", "...", "==", ">=", "<=", "~=", 45 "//", "..", "...", "==", ">=", "<=", "~=",
46 "<<", ">>", "::", "<eof>", 46 "<<", ">>", "::", "<eof>",
47 "<number>", "<integer>", "<name>", "<string>" 47 "<number>", "<integer>", "<name>", "<string>"
diff --git a/llex.h b/llex.h
index 9f23bd89..fb33c33f 100644
--- a/llex.h
+++ b/llex.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: llex.h,v 1.79 2016/05/02 14:02:12 roberto Exp roberto $ 2** $Id: llex.h,v 1.80 2018/01/28 15:13:26 roberto Exp roberto $
3** Lexical Analyzer 3** Lexical Analyzer
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -28,7 +28,7 @@ enum RESERVED {
28 TK_AND = FIRST_RESERVED, TK_BREAK, 28 TK_AND = FIRST_RESERVED, TK_BREAK,
29 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 29 TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
30 TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 30 TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
31 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 31 TK_RETURN, TK_THEN, TK_TRUE, TK_UNDEF, TK_UNTIL, TK_WHILE,
32 /* other terminal symbols */ 32 /* other terminal symbols */
33 TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 33 TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
34 TK_SHL, TK_SHR, 34 TK_SHL, TK_SHR,
diff --git a/lopcodes.c b/lopcodes.c
index 79d77cc1..ac59537b 100644
--- a/lopcodes.c
+++ b/lopcodes.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.c,v 1.78 2018/02/15 15:34:29 roberto Exp roberto $ 2** $Id: lopcodes.c,v 1.79 2018/02/21 15:49:32 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -79,6 +79,8 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
79 "GEI", 79 "GEI",
80 "TEST", 80 "TEST",
81 "TESTSET", 81 "TESTSET",
82 "UNDEF",
83 "ISDEF",
82 "CALL", 84 "CALL",
83 "TAILCALL", 85 "TAILCALL",
84 "RETURN", 86 "RETURN",
@@ -162,6 +164,8 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
162 ,opmode(0, 0, 1, 0, iABC) /* OP_GEI */ 164 ,opmode(0, 0, 1, 0, iABC) /* OP_GEI */
163 ,opmode(0, 0, 1, 0, iABC) /* OP_TEST */ 165 ,opmode(0, 0, 1, 0, iABC) /* OP_TEST */
164 ,opmode(0, 0, 1, 1, iABC) /* OP_TESTSET */ 166 ,opmode(0, 0, 1, 1, iABC) /* OP_TESTSET */
167 ,opmode(0, 0, 0, 0, iABC) /* OP_UNDEF */
168 ,opmode(0, 0, 0, 1, iABC) /* OP_ISDEF */
165 ,opmode(1, 1, 0, 1, iABC) /* OP_CALL */ 169 ,opmode(1, 1, 0, 1, iABC) /* OP_CALL */
166 ,opmode(1, 1, 0, 1, iABC) /* OP_TAILCALL */ 170 ,opmode(1, 1, 0, 1, iABC) /* OP_TAILCALL */
167 ,opmode(0, 1, 0, 0, iABC) /* OP_RETURN */ 171 ,opmode(0, 1, 0, 0, iABC) /* OP_RETURN */
diff --git a/lopcodes.h b/lopcodes.h
index be7359e9..ddbaf8da 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.188 2018/02/15 15:34:29 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.189 2018/02/21 15:49:32 roberto Exp roberto $
3** Opcodes for Lua virtual machine 3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -266,6 +266,9 @@ OP_GEI,/* A sB if ((R(A) >= sB) ~= k) then pc++ */
266OP_TEST,/* A if (not R(A) == k) then pc++ */ 266OP_TEST,/* A if (not R(A) == k) then pc++ */
267OP_TESTSET,/* A B if (not R(B) == k) then R(A) := R(B) else pc++ */ 267OP_TESTSET,/* A B if (not R(B) == k) then R(A) := R(B) else pc++ */
268 268
269OP_UNDEF,/* A B R(A)[R(B)] = undef */
270OP_ISDEF,/* A B C R(A) = (R(B)[R(C)] == undef */
271
269OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ 272OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
270OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ 273OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
271 274
diff --git a/lparser.c b/lparser.c
index da27c472..9bf5485e 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 2.177 2018/02/09 15:16:06 roberto Exp roberto $ 2** $Id: lparser.c,v 2.178 2018/02/17 19:20:00 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -65,13 +65,6 @@ static void statement (LexState *ls);
65static void expr (LexState *ls, expdesc *v); 65static void expr (LexState *ls, expdesc *v);
66 66
67 67
68/* semantic error */
69static l_noret semerror (LexState *ls, const char *msg) {
70 ls->t.token = 0; /* remove "near <token>" from final message */
71 luaX_syntaxerror(ls, msg);
72}
73
74
75static l_noret error_expected (LexState *ls, int token) { 68static l_noret error_expected (LexState *ls, int token) {
76 luaX_syntaxerror(ls, 69 luaX_syntaxerror(ls,
77 luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); 70 luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
@@ -347,7 +340,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) {
347 const char *msg = luaO_pushfstring(ls->L, 340 const char *msg = luaO_pushfstring(ls->L,
348 "<goto %s> at line %d jumps into the scope of local '%s'", 341 "<goto %s> at line %d jumps into the scope of local '%s'",
349 getstr(gt->name), gt->line, getstr(vname)); 342 getstr(gt->name), gt->line, getstr(vname));
350 semerror(ls, msg); 343 luaK_semerror(ls, msg);
351 } 344 }
352 luaK_patchgoto(fs, gt->pc, label->pc, 1); 345 luaK_patchgoto(fs, gt->pc, label->pc, 1);
353 /* remove goto from pending list */ 346 /* remove goto from pending list */
@@ -477,7 +470,7 @@ static void fixbreaks (FuncState *fs, BlockCnt *bl) {
477static l_noret undefgoto (LexState *ls, Labeldesc *gt) { 470static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
478 const char *msg = "no visible label '%s' for <goto> at line %d"; 471 const char *msg = "no visible label '%s' for <goto> at line %d";
479 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); 472 msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
480 semerror(ls, msg); 473 luaK_semerror(ls, msg);
481} 474}
482 475
483 476
@@ -900,6 +893,11 @@ static void primaryexp (LexState *ls, expdesc *v) {
900 singlevar(ls, v); 893 singlevar(ls, v);
901 return; 894 return;
902 } 895 }
896 case TK_UNDEF: {
897 luaX_next(ls);
898 init_exp(v, VUNDEF, 0);
899 return;
900 }
903 default: { 901 default: {
904 luaX_syntaxerror(ls, "unexpected symbol"); 902 luaX_syntaxerror(ls, "unexpected symbol");
905 } 903 }
@@ -1185,6 +1183,10 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
1185 else { /* assignment -> '=' explist */ 1183 else { /* assignment -> '=' explist */
1186 int nexps; 1184 int nexps;
1187 checknext(ls, '='); 1185 checknext(ls, '=');
1186 if (nvars == 1 && testnext(ls, TK_UNDEF)) {
1187 luaK_codeundef(ls->fs, &lh->v);
1188 return;
1189 }
1188 nexps = explist(ls, &e); 1190 nexps = explist(ls, &e);
1189 if (nexps != nvars) 1191 if (nexps != nvars)
1190 adjust_assign(ls, nvars, nexps, &e); 1192 adjust_assign(ls, nvars, nexps, &e);
@@ -1237,7 +1239,7 @@ static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
1237 const char *msg = luaO_pushfstring(fs->ls->L, 1239 const char *msg = luaO_pushfstring(fs->ls->L,
1238 "label '%s' already defined on line %d", 1240 "label '%s' already defined on line %d",
1239 getstr(label), ll->arr[i].line); 1241 getstr(label), ll->arr[i].line);
1240 semerror(fs->ls, msg); 1242 luaK_semerror(fs->ls, msg);
1241 } 1243 }
1242 } 1244 }
1243} 1245}
@@ -1650,6 +1652,11 @@ static void statement (LexState *ls) {
1650 luaX_next(ls); /* skip LOCAL */ 1652 luaX_next(ls); /* skip LOCAL */
1651 if (testnext(ls, TK_FUNCTION)) /* local function? */ 1653 if (testnext(ls, TK_FUNCTION)) /* local function? */
1652 localfunc(ls); 1654 localfunc(ls);
1655 else if (testnext(ls, TK_UNDEF))
1656 (void)0; /* ignore */
1657 /* old versions may need to declare 'local undef'
1658 when using 'undef' with no environment; so this
1659 version accepts (and ignores) these declarations */
1653 else 1660 else
1654 localstat(ls); 1661 localstat(ls);
1655 break; 1662 break;
diff --git a/lparser.h b/lparser.h
index 6007d618..b8705e84 100644
--- a/lparser.h
+++ b/lparser.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.h,v 1.79 2017/11/30 13:29:18 roberto Exp roberto $ 2** $Id: lparser.h,v 1.80 2017/12/14 14:24:02 roberto Exp roberto $
3** Lua Parser 3** Lua Parser
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -52,7 +52,8 @@ typedef enum {
52 VRELOC, /* expression can put result in any register; 52 VRELOC, /* expression can put result in any register;
53 info = instruction pc */ 53 info = instruction pc */
54 VCALL, /* expression is a function call; info = instruction pc */ 54 VCALL, /* expression is a function call; info = instruction pc */
55 VVARARG /* vararg expression; info = instruction pc */ 55 VVARARG, /* vararg expression; info = instruction pc */
56 VUNDEF /* the 'undef' "expression" */
56} expkind; 57} expkind;
57 58
58 59
diff --git a/lvm.c b/lvm.c
index 891e7d8d..b3abbf13 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.348 2018/02/26 14:16:05 roberto Exp roberto $ 2** $Id: lvm.c,v 2.349 2018/03/02 18:59:19 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -1552,6 +1552,18 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1552 } 1552 }
1553 vmbreak; 1553 vmbreak;
1554 } 1554 }
1555 vmcase(OP_UNDEF) {
1556 TValue *rb = vRB(i);
1557 luaT_keydef(L, vra, rb, 1);
1558 vmbreak;
1559 }
1560 vmcase(OP_ISDEF) {
1561 TValue *rb = vRB(i);
1562 TValue *rc = vRC(i);
1563 int res = luaT_keydef(L, rb, rc, 0);
1564 setbvalue(vra, res == GETARG_k(i));
1565 vmbreak;
1566 }
1555 vmcase(OP_CALL) { 1567 vmcase(OP_CALL) {
1556 int b = GETARG_B(i); 1568 int b = GETARG_B(i);
1557 int nresults = GETARG_C(i) - 1; 1569 int nresults = GETARG_C(i) - 1;