diff options
Diffstat (limited to '')
-rw-r--r-- | lapi.c | 4 | ||||
-rw-r--r-- | lcode.c | 29 | ||||
-rw-r--r-- | lcode.h | 3 | ||||
-rw-r--r-- | ldebug.c | 177 | ||||
-rw-r--r-- | ldebug.h | 1 | ||||
-rw-r--r-- | ldo.c | 6 | ||||
-rw-r--r-- | ldo.h | 1 | ||||
-rw-r--r-- | lgc.c | 20 | ||||
-rw-r--r-- | lmathlib.c | 31 | ||||
-rw-r--r-- | loadlib.c | 9 | ||||
-rw-r--r-- | lobject.c | 2 | ||||
-rw-r--r-- | lobject.h | 18 | ||||
-rw-r--r-- | lopcodes.h | 8 | ||||
-rw-r--r-- | lparser.c | 12 | ||||
-rw-r--r-- | lstate.c | 6 | ||||
-rw-r--r-- | lstate.h | 3 | ||||
-rw-r--r-- | lstring.c | 11 | ||||
-rw-r--r-- | ltable.c | 5 | ||||
-rw-r--r-- | ltable.h | 2 | ||||
-rw-r--r-- | ltm.h | 5 | ||||
-rw-r--r-- | lua.c | 12 | ||||
-rw-r--r-- | lua.h | 32 | ||||
-rw-r--r-- | luaconf.h | 9 | ||||
-rw-r--r-- | lundump.c | 4 | ||||
-rw-r--r-- | lundump.h | 3 | ||||
-rw-r--r-- | lvm.c | 76 | ||||
-rw-r--r-- | manual/manual.of | 4 | ||||
-rw-r--r-- | testes/calls.lua | 14 | ||||
-rw-r--r-- | testes/db.lua | 8 | ||||
-rw-r--r-- | testes/errors.lua | 11 | ||||
-rw-r--r-- | testes/files.lua | 8 | ||||
-rw-r--r-- | testes/main.lua | 50 | ||||
-rw-r--r-- | testes/pm.lua | 56 | ||||
-rw-r--r-- | testes/sort.lua | 2 | ||||
-rw-r--r-- | testes/strings.lua | 3 | ||||
-rw-r--r-- | testes/utf8.lua | 2 |
36 files changed, 369 insertions, 278 deletions
@@ -417,9 +417,9 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { | |||
417 | o = index2value(L, idx); /* previous call may reallocate the stack */ | 417 | o = index2value(L, idx); /* previous call may reallocate the stack */ |
418 | } | 418 | } |
419 | if (len != NULL) | 419 | if (len != NULL) |
420 | *len = vslen(o); | 420 | *len = tsslen(tsvalue(o)); |
421 | lua_unlock(L); | 421 | lua_unlock(L); |
422 | return svalue(o); | 422 | return getstr(tsvalue(o)); |
423 | } | 423 | } |
424 | 424 | ||
425 | 425 | ||
@@ -415,7 +415,7 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { | |||
415 | /* | 415 | /* |
416 | ** Format and emit an 'iAsBx' instruction. | 416 | ** Format and emit an 'iAsBx' instruction. |
417 | */ | 417 | */ |
418 | int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) { | 418 | static int codeAsBx (FuncState *fs, OpCode o, int a, int bc) { |
419 | unsigned int b = bc + OFFSET_sBx; | 419 | unsigned int b = bc + OFFSET_sBx; |
420 | lua_assert(getOpMode(o) == iAsBx); | 420 | lua_assert(getOpMode(o) == iAsBx); |
421 | lua_assert(a <= MAXARG_A && b <= MAXARG_Bx); | 421 | lua_assert(a <= MAXARG_A && b <= MAXARG_Bx); |
@@ -671,7 +671,7 @@ static int fitsBx (lua_Integer i) { | |||
671 | 671 | ||
672 | void luaK_int (FuncState *fs, int reg, lua_Integer i) { | 672 | void luaK_int (FuncState *fs, int reg, lua_Integer i) { |
673 | if (fitsBx(i)) | 673 | if (fitsBx(i)) |
674 | luaK_codeAsBx(fs, OP_LOADI, reg, cast_int(i)); | 674 | codeAsBx(fs, OP_LOADI, reg, cast_int(i)); |
675 | else | 675 | else |
676 | luaK_codek(fs, reg, luaK_intK(fs, i)); | 676 | luaK_codek(fs, reg, luaK_intK(fs, i)); |
677 | } | 677 | } |
@@ -680,7 +680,7 @@ void luaK_int (FuncState *fs, int reg, lua_Integer i) { | |||
680 | static void luaK_float (FuncState *fs, int reg, lua_Number f) { | 680 | static void luaK_float (FuncState *fs, int reg, lua_Number f) { |
681 | lua_Integer fi; | 681 | lua_Integer fi; |
682 | if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi)) | 682 | if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi)) |
683 | luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); | 683 | codeAsBx(fs, OP_LOADF, reg, cast_int(fi)); |
684 | else | 684 | else |
685 | luaK_codek(fs, reg, luaK_numberK(fs, f)); | 685 | luaK_codek(fs, reg, luaK_numberK(fs, f)); |
686 | } | 686 | } |
@@ -1025,7 +1025,7 @@ static int luaK_exp2K (FuncState *fs, expdesc *e) { | |||
1025 | ** in the range of R/K indices). | 1025 | ** in the range of R/K indices). |
1026 | ** Returns 1 iff expression is K. | 1026 | ** Returns 1 iff expression is K. |
1027 | */ | 1027 | */ |
1028 | int luaK_exp2RK (FuncState *fs, expdesc *e) { | 1028 | static int exp2RK (FuncState *fs, expdesc *e) { |
1029 | if (luaK_exp2K(fs, e)) | 1029 | if (luaK_exp2K(fs, e)) |
1030 | return 1; | 1030 | return 1; |
1031 | else { /* not a constant in the right range: put it in a register */ | 1031 | else { /* not a constant in the right range: put it in a register */ |
@@ -1037,7 +1037,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) { | |||
1037 | 1037 | ||
1038 | static void codeABRK (FuncState *fs, OpCode o, int a, int b, | 1038 | static void codeABRK (FuncState *fs, OpCode o, int a, int b, |
1039 | expdesc *ec) { | 1039 | expdesc *ec) { |
1040 | int k = luaK_exp2RK(fs, ec); | 1040 | int k = exp2RK(fs, ec); |
1041 | luaK_codeABCk(fs, o, a, b, ec->u.info, k); | 1041 | luaK_codeABCk(fs, o, a, b, ec->u.info, k); |
1042 | } | 1042 | } |
1043 | 1043 | ||
@@ -1215,7 +1215,7 @@ static void codenot (FuncState *fs, expdesc *e) { | |||
1215 | 1215 | ||
1216 | 1216 | ||
1217 | /* | 1217 | /* |
1218 | ** Check whether expression 'e' is a small literal string | 1218 | ** Check whether expression 'e' is a short literal string |
1219 | */ | 1219 | */ |
1220 | static int isKstr (FuncState *fs, expdesc *e) { | 1220 | static int isKstr (FuncState *fs, expdesc *e) { |
1221 | return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B && | 1221 | return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B && |
@@ -1225,7 +1225,7 @@ static int isKstr (FuncState *fs, expdesc *e) { | |||
1225 | /* | 1225 | /* |
1226 | ** Check whether expression 'e' is a literal integer. | 1226 | ** Check whether expression 'e' is a literal integer. |
1227 | */ | 1227 | */ |
1228 | int luaK_isKint (expdesc *e) { | 1228 | static int isKint (expdesc *e) { |
1229 | return (e->k == VKINT && !hasjumps(e)); | 1229 | return (e->k == VKINT && !hasjumps(e)); |
1230 | } | 1230 | } |
1231 | 1231 | ||
@@ -1235,7 +1235,7 @@ int luaK_isKint (expdesc *e) { | |||
1235 | ** proper range to fit in register C | 1235 | ** proper range to fit in register C |
1236 | */ | 1236 | */ |
1237 | static int isCint (expdesc *e) { | 1237 | static int isCint (expdesc *e) { |
1238 | return luaK_isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C)); | 1238 | return isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C)); |
1239 | } | 1239 | } |
1240 | 1240 | ||
1241 | 1241 | ||
@@ -1244,7 +1244,7 @@ static int isCint (expdesc *e) { | |||
1244 | ** proper range to fit in register sC | 1244 | ** proper range to fit in register sC |
1245 | */ | 1245 | */ |
1246 | static int isSCint (expdesc *e) { | 1246 | static int isSCint (expdesc *e) { |
1247 | return luaK_isKint(e) && fitsC(e->u.ival); | 1247 | return isKint(e) && fitsC(e->u.ival); |
1248 | } | 1248 | } |
1249 | 1249 | ||
1250 | 1250 | ||
@@ -1283,15 +1283,16 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | |||
1283 | if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ | 1283 | if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */ |
1284 | luaK_exp2anyreg(fs, t); /* put it in a register */ | 1284 | luaK_exp2anyreg(fs, t); /* put it in a register */ |
1285 | if (t->k == VUPVAL) { | 1285 | if (t->k == VUPVAL) { |
1286 | lua_assert(isKstr(fs, k)); | ||
1286 | t->u.ind.t = t->u.info; /* upvalue index */ | 1287 | t->u.ind.t = t->u.info; /* upvalue index */ |
1287 | t->u.ind.idx = k->u.info; /* literal string */ | 1288 | t->u.ind.idx = k->u.info; /* literal short string */ |
1288 | t->k = VINDEXUP; | 1289 | t->k = VINDEXUP; |
1289 | } | 1290 | } |
1290 | else { | 1291 | else { |
1291 | /* register index of the table */ | 1292 | /* register index of the table */ |
1292 | t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info; | 1293 | t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info; |
1293 | if (isKstr(fs, k)) { | 1294 | if (isKstr(fs, k)) { |
1294 | t->u.ind.idx = k->u.info; /* literal string */ | 1295 | t->u.ind.idx = k->u.info; /* literal short string */ |
1295 | t->k = VINDEXSTR; | 1296 | t->k = VINDEXSTR; |
1296 | } | 1297 | } |
1297 | else if (isCint(k)) { | 1298 | else if (isCint(k)) { |
@@ -1459,7 +1460,7 @@ static void codebinK (FuncState *fs, BinOpr opr, | |||
1459 | */ | 1460 | */ |
1460 | static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, | 1461 | static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, |
1461 | OpCode op, int line, TMS event) { | 1462 | OpCode op, int line, TMS event) { |
1462 | if (!luaK_isKint(e2)) | 1463 | if (!isKint(e2)) |
1463 | return 0; /* not an integer constant */ | 1464 | return 0; /* not an integer constant */ |
1464 | else { | 1465 | else { |
1465 | lua_Integer i2 = e2->u.ival; | 1466 | lua_Integer i2 = e2->u.ival; |
@@ -1592,7 +1593,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) { | |||
1592 | op = OP_EQI; | 1593 | op = OP_EQI; |
1593 | r2 = im; /* immediate operand */ | 1594 | r2 = im; /* immediate operand */ |
1594 | } | 1595 | } |
1595 | else if (luaK_exp2RK(fs, e2)) { /* 2nd expression is constant? */ | 1596 | else if (exp2RK(fs, e2)) { /* 2nd expression is constant? */ |
1596 | op = OP_EQK; | 1597 | op = OP_EQK; |
1597 | r2 = e2->u.info; /* constant index */ | 1598 | r2 = e2->u.info; /* constant index */ |
1598 | } | 1599 | } |
@@ -1658,7 +1659,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { | |||
1658 | } | 1659 | } |
1659 | case OPR_EQ: case OPR_NE: { | 1660 | case OPR_EQ: case OPR_NE: { |
1660 | if (!tonumeral(v, NULL)) | 1661 | if (!tonumeral(v, NULL)) |
1661 | luaK_exp2RK(fs, v); | 1662 | exp2RK(fs, v); |
1662 | /* else keep numeral, which may be an immediate operand */ | 1663 | /* else keep numeral, which may be an immediate operand */ |
1663 | break; | 1664 | break; |
1664 | } | 1665 | } |
@@ -61,10 +61,8 @@ typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; | |||
61 | 61 | ||
62 | LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); | 62 | LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); |
63 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); | 63 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); |
64 | LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx); | ||
65 | LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, | 64 | LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, |
66 | int B, int C, int k); | 65 | int B, int C, int k); |
67 | LUAI_FUNC int luaK_isKint (expdesc *e); | ||
68 | LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); | 66 | LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); |
69 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); | 67 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); |
70 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); | 68 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); |
@@ -76,7 +74,6 @@ LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); | |||
76 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); | 74 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); |
77 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); | 75 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); |
78 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); | 76 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); |
79 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); | ||
80 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); | 77 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); |
81 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); | 78 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); |
82 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); | 79 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); |
@@ -417,40 +417,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
417 | ** ======================================================= | 417 | ** ======================================================= |
418 | */ | 418 | */ |
419 | 419 | ||
420 | static const char *getobjname (const Proto *p, int lastpc, int reg, | ||
421 | const char **name); | ||
422 | |||
423 | |||
424 | /* | ||
425 | ** Find a "name" for the constant 'c'. | ||
426 | */ | ||
427 | static void kname (const Proto *p, int c, const char **name) { | ||
428 | TValue *kvalue = &p->k[c]; | ||
429 | *name = (ttisstring(kvalue)) ? svalue(kvalue) : "?"; | ||
430 | } | ||
431 | |||
432 | |||
433 | /* | ||
434 | ** Find a "name" for the register 'c'. | ||
435 | */ | ||
436 | static void rname (const Proto *p, int pc, int c, const char **name) { | ||
437 | const char *what = getobjname(p, pc, c, name); /* search for 'c' */ | ||
438 | if (!(what && *what == 'c')) /* did not find a constant name? */ | ||
439 | *name = "?"; | ||
440 | } | ||
441 | |||
442 | |||
443 | /* | ||
444 | ** Find a "name" for a 'C' value in an RK instruction. | ||
445 | */ | ||
446 | static void rkname (const Proto *p, int pc, Instruction i, const char **name) { | ||
447 | int c = GETARG_C(i); /* key index */ | ||
448 | if (GETARG_k(i)) /* is 'c' a constant? */ | ||
449 | kname(p, c, name); | ||
450 | else /* 'c' is a register */ | ||
451 | rname(p, pc, c, name); | ||
452 | } | ||
453 | |||
454 | 420 | ||
455 | static int filterpc (int pc, int jmptarget) { | 421 | static int filterpc (int pc, int jmptarget) { |
456 | if (pc < jmptarget) /* is code conditional (inside a jump)? */ | 422 | if (pc < jmptarget) /* is code conditional (inside a jump)? */ |
@@ -509,28 +475,29 @@ static int findsetreg (const Proto *p, int lastpc, int reg) { | |||
509 | 475 | ||
510 | 476 | ||
511 | /* | 477 | /* |
512 | ** Check whether table being indexed by instruction 'i' is the | 478 | ** Find a "name" for the constant 'c'. |
513 | ** environment '_ENV' | ||
514 | */ | 479 | */ |
515 | static const char *gxf (const Proto *p, int pc, Instruction i, int isup) { | 480 | static const char *kname (const Proto *p, int index, const char **name) { |
516 | int t = GETARG_B(i); /* table index */ | 481 | TValue *kvalue = &p->k[index]; |
517 | const char *name; /* name of indexed variable */ | 482 | if (ttisstring(kvalue)) { |
518 | if (isup) /* is an upvalue? */ | 483 | *name = getstr(tsvalue(kvalue)); |
519 | name = upvalname(p, t); | 484 | return "constant"; |
520 | else | 485 | } |
521 | getobjname(p, pc, t, &name); | 486 | else { |
522 | return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; | 487 | *name = "?"; |
488 | return NULL; | ||
489 | } | ||
523 | } | 490 | } |
524 | 491 | ||
525 | 492 | ||
526 | static const char *getobjname (const Proto *p, int lastpc, int reg, | 493 | static const char *basicgetobjname (const Proto *p, int *ppc, int reg, |
527 | const char **name) { | 494 | const char **name) { |
528 | int pc; | 495 | int pc = *ppc; |
529 | *name = luaF_getlocalname(p, reg + 1, lastpc); | 496 | *name = luaF_getlocalname(p, reg + 1, pc); |
530 | if (*name) /* is a local? */ | 497 | if (*name) /* is a local? */ |
531 | return "local"; | 498 | return "local"; |
532 | /* else try symbolic execution */ | 499 | /* else try symbolic execution */ |
533 | pc = findsetreg(p, lastpc, reg); | 500 | *ppc = pc = findsetreg(p, pc, reg); |
534 | if (pc != -1) { /* could find instruction? */ | 501 | if (pc != -1) { /* could find instruction? */ |
535 | Instruction i = p->code[pc]; | 502 | Instruction i = p->code[pc]; |
536 | OpCode op = GET_OPCODE(i); | 503 | OpCode op = GET_OPCODE(i); |
@@ -538,18 +505,80 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, | |||
538 | case OP_MOVE: { | 505 | case OP_MOVE: { |
539 | int b = GETARG_B(i); /* move from 'b' to 'a' */ | 506 | int b = GETARG_B(i); /* move from 'b' to 'a' */ |
540 | if (b < GETARG_A(i)) | 507 | if (b < GETARG_A(i)) |
541 | return getobjname(p, pc, b, name); /* get name for 'b' */ | 508 | return basicgetobjname(p, ppc, b, name); /* get name for 'b' */ |
542 | break; | 509 | break; |
543 | } | 510 | } |
511 | case OP_GETUPVAL: { | ||
512 | *name = upvalname(p, GETARG_B(i)); | ||
513 | return "upvalue"; | ||
514 | } | ||
515 | case OP_LOADK: return kname(p, GETARG_Bx(i), name); | ||
516 | case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); | ||
517 | default: break; | ||
518 | } | ||
519 | } | ||
520 | return NULL; /* could not find reasonable name */ | ||
521 | } | ||
522 | |||
523 | |||
524 | /* | ||
525 | ** Find a "name" for the register 'c'. | ||
526 | */ | ||
527 | static void rname (const Proto *p, int pc, int c, const char **name) { | ||
528 | const char *what = basicgetobjname(p, &pc, c, name); /* search for 'c' */ | ||
529 | if (!(what && *what == 'c')) /* did not find a constant name? */ | ||
530 | *name = "?"; | ||
531 | } | ||
532 | |||
533 | |||
534 | /* | ||
535 | ** Find a "name" for a 'C' value in an RK instruction. | ||
536 | */ | ||
537 | static void rkname (const Proto *p, int pc, Instruction i, const char **name) { | ||
538 | int c = GETARG_C(i); /* key index */ | ||
539 | if (GETARG_k(i)) /* is 'c' a constant? */ | ||
540 | kname(p, c, name); | ||
541 | else /* 'c' is a register */ | ||
542 | rname(p, pc, c, name); | ||
543 | } | ||
544 | |||
545 | |||
546 | /* | ||
547 | ** Check whether table being indexed by instruction 'i' is the | ||
548 | ** environment '_ENV' | ||
549 | */ | ||
550 | static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { | ||
551 | int t = GETARG_B(i); /* table index */ | ||
552 | const char *name; /* name of indexed variable */ | ||
553 | if (isup) /* is 't' an upvalue? */ | ||
554 | name = upvalname(p, t); | ||
555 | else /* 't' is a register */ | ||
556 | basicgetobjname(p, &pc, t, &name); | ||
557 | return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; | ||
558 | } | ||
559 | |||
560 | |||
561 | /* | ||
562 | ** Extend 'basicgetobjname' to handle table accesses | ||
563 | */ | ||
564 | static const char *getobjname (const Proto *p, int lastpc, int reg, | ||
565 | const char **name) { | ||
566 | const char *kind = basicgetobjname(p, &lastpc, reg, name); | ||
567 | if (kind != NULL) | ||
568 | return kind; | ||
569 | else if (lastpc != -1) { /* could find instruction? */ | ||
570 | Instruction i = p->code[lastpc]; | ||
571 | OpCode op = GET_OPCODE(i); | ||
572 | switch (op) { | ||
544 | case OP_GETTABUP: { | 573 | case OP_GETTABUP: { |
545 | int k = GETARG_C(i); /* key index */ | 574 | int k = GETARG_C(i); /* key index */ |
546 | kname(p, k, name); | 575 | kname(p, k, name); |
547 | return gxf(p, pc, i, 1); | 576 | return isEnv(p, lastpc, i, 1); |
548 | } | 577 | } |
549 | case OP_GETTABLE: { | 578 | case OP_GETTABLE: { |
550 | int k = GETARG_C(i); /* key index */ | 579 | int k = GETARG_C(i); /* key index */ |
551 | rname(p, pc, k, name); | 580 | rname(p, lastpc, k, name); |
552 | return gxf(p, pc, i, 0); | 581 | return isEnv(p, lastpc, i, 0); |
553 | } | 582 | } |
554 | case OP_GETI: { | 583 | case OP_GETI: { |
555 | *name = "integer index"; | 584 | *name = "integer index"; |
@@ -558,24 +587,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, | |||
558 | case OP_GETFIELD: { | 587 | case OP_GETFIELD: { |
559 | int k = GETARG_C(i); /* key index */ | 588 | int k = GETARG_C(i); /* key index */ |
560 | kname(p, k, name); | 589 | kname(p, k, name); |
561 | return gxf(p, pc, i, 0); | 590 | return isEnv(p, lastpc, i, 0); |
562 | } | ||
563 | case OP_GETUPVAL: { | ||
564 | *name = upvalname(p, GETARG_B(i)); | ||
565 | return "upvalue"; | ||
566 | } | ||
567 | case OP_LOADK: | ||
568 | case OP_LOADKX: { | ||
569 | int b = (op == OP_LOADK) ? GETARG_Bx(i) | ||
570 | : GETARG_Ax(p->code[pc + 1]); | ||
571 | if (ttisstring(&p->k[b])) { | ||
572 | *name = svalue(&p->k[b]); | ||
573 | return "constant"; | ||
574 | } | ||
575 | break; | ||
576 | } | 591 | } |
577 | case OP_SELF: { | 592 | case OP_SELF: { |
578 | rkname(p, pc, i, name); | 593 | rkname(p, lastpc, i, name); |
579 | return "method"; | 594 | return "method"; |
580 | } | 595 | } |
581 | default: break; /* go through to return NULL */ | 596 | default: break; /* go through to return NULL */ |
@@ -627,7 +642,7 @@ static const char *funcnamefromcode (lua_State *L, const Proto *p, | |||
627 | default: | 642 | default: |
628 | return NULL; /* cannot find a reasonable name */ | 643 | return NULL; /* cannot find a reasonable name */ |
629 | } | 644 | } |
630 | *name = getstr(G(L)->tmname[tm]) + 2; | 645 | *name = getshrstr(G(L)->tmname[tm]) + 2; |
631 | return "metamethod"; | 646 | return "metamethod"; |
632 | } | 647 | } |
633 | 648 | ||
@@ -866,6 +881,28 @@ static int changedline (const Proto *p, int oldpc, int newpc) { | |||
866 | 881 | ||
867 | 882 | ||
868 | /* | 883 | /* |
884 | ** Traces Lua calls. If code is running the first instruction of a function, | ||
885 | ** and function is not vararg, and it is not coming from an yield, | ||
886 | ** calls 'luaD_hookcall'. (Vararg functions will call 'luaD_hookcall' | ||
887 | ** after adjusting its variable arguments; otherwise, they could call | ||
888 | ** a line/count hook before the call hook. Functions coming from | ||
889 | ** an yield already called 'luaD_hookcall' before yielding.) | ||
890 | */ | ||
891 | int luaG_tracecall (lua_State *L) { | ||
892 | CallInfo *ci = L->ci; | ||
893 | Proto *p = ci_func(ci)->p; | ||
894 | ci->u.l.trap = 1; /* ensure hooks will be checked */ | ||
895 | if (ci->u.l.savedpc == p->code) { /* first instruction (not resuming)? */ | ||
896 | if (p->is_vararg) | ||
897 | return 0; /* hooks will start at VARARGPREP instruction */ | ||
898 | else if (!(ci->callstatus & CIST_HOOKYIELD)) /* not yieded? */ | ||
899 | luaD_hookcall(L, ci); /* check 'call' hook */ | ||
900 | } | ||
901 | return 1; /* keep 'trap' on */ | ||
902 | } | ||
903 | |||
904 | |||
905 | /* | ||
869 | ** Traces the execution of a Lua function. Called before the execution | 906 | ** Traces the execution of a Lua function. Called before the execution |
870 | ** of each opcode, when debug is on. 'L->oldpc' stores the last | 907 | ** of each opcode, when debug is on. 'L->oldpc' stores the last |
871 | ** instruction traced, to detect line changes. When entering a new | 908 | ** instruction traced, to detect line changes. When entering a new |
@@ -58,6 +58,7 @@ LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, | |||
58 | TString *src, int line); | 58 | TString *src, int line); |
59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); | 59 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); |
60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); | 60 | LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); |
61 | LUAI_FUNC int luaG_tracecall (lua_State *L); | ||
61 | 62 | ||
62 | 63 | ||
63 | #endif | 64 | #endif |
@@ -409,7 +409,7 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) { | |||
409 | ** stack, below original 'func', so that 'luaD_precall' can call it. Raise | 409 | ** stack, below original 'func', so that 'luaD_precall' can call it. Raise |
410 | ** an error if there is no '__call' metafield. | 410 | ** an error if there is no '__call' metafield. |
411 | */ | 411 | */ |
412 | StkId luaD_tryfuncTM (lua_State *L, StkId func) { | 412 | static StkId tryfuncTM (lua_State *L, StkId func) { |
413 | const TValue *tm; | 413 | const TValue *tm; |
414 | StkId p; | 414 | StkId p; |
415 | checkstackGCp(L, 1, func); /* space for metamethod */ | 415 | checkstackGCp(L, 1, func); /* space for metamethod */ |
@@ -568,7 +568,7 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, | |||
568 | return -1; | 568 | return -1; |
569 | } | 569 | } |
570 | default: { /* not a function */ | 570 | default: { /* not a function */ |
571 | func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ | 571 | func = tryfuncTM(L, func); /* try to get '__call' metamethod */ |
572 | /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */ | 572 | /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */ |
573 | narg1++; | 573 | narg1++; |
574 | goto retry; /* try again */ | 574 | goto retry; /* try again */ |
@@ -609,7 +609,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { | |||
609 | return ci; | 609 | return ci; |
610 | } | 610 | } |
611 | default: { /* not a function */ | 611 | default: { /* not a function */ |
612 | func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ | 612 | func = tryfuncTM(L, func); /* try to get '__call' metamethod */ |
613 | /* return luaD_precall(L, func, nresults); */ | 613 | /* return luaD_precall(L, func, nresults); */ |
614 | goto retry; /* try again with metamethod */ | 614 | goto retry; /* try again with metamethod */ |
615 | } | 615 | } |
@@ -71,7 +71,6 @@ LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, | |||
71 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); | 71 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); |
72 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); | 72 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); |
73 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); | 73 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); |
74 | LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func); | ||
75 | LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); | 74 | LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); |
76 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, | 75 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, |
77 | ptrdiff_t oldtop, ptrdiff_t ef); | 76 | ptrdiff_t oldtop, ptrdiff_t ef); |
@@ -553,10 +553,12 @@ static void traversestrongtable (global_State *g, Table *h) { | |||
553 | static lu_mem traversetable (global_State *g, Table *h) { | 553 | static lu_mem traversetable (global_State *g, Table *h) { |
554 | const char *weakkey, *weakvalue; | 554 | const char *weakkey, *weakvalue; |
555 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); | 555 | const TValue *mode = gfasttm(g, h->metatable, TM_MODE); |
556 | TString *smode; | ||
556 | markobjectN(g, h->metatable); | 557 | markobjectN(g, h->metatable); |
557 | if (mode && ttisstring(mode) && /* is there a weak mode? */ | 558 | if (mode && ttisshrstring(mode) && /* is there a weak mode? */ |
558 | (cast_void(weakkey = strchr(svalue(mode), 'k')), | 559 | (cast_void(smode = tsvalue(mode)), |
559 | cast_void(weakvalue = strchr(svalue(mode), 'v')), | 560 | cast_void(weakkey = strchr(getshrstr(smode), 'k')), |
561 | cast_void(weakvalue = strchr(getshrstr(smode), 'v')), | ||
560 | (weakkey || weakvalue))) { /* is really weak? */ | 562 | (weakkey || weakvalue))) { /* is really weak? */ |
561 | if (!weakkey) /* strong keys? */ | 563 | if (!weakkey) /* strong keys? */ |
562 | traverseweakvalue(g, h); | 564 | traverseweakvalue(g, h); |
@@ -649,7 +651,9 @@ static int traversethread (global_State *g, lua_State *th) { | |||
649 | for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) | 651 | for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) |
650 | markobject(g, uv); /* open upvalues cannot be collected */ | 652 | markobject(g, uv); /* open upvalues cannot be collected */ |
651 | if (g->gcstate == GCSatomic) { /* final traversal? */ | 653 | if (g->gcstate == GCSatomic) { /* final traversal? */ |
652 | for (; o < th->stack_last.p + EXTRA_STACK; o++) | 654 | if (!g->gcemergency) |
655 | luaD_shrinkstack(th); /* do not change stack in emergency cycle */ | ||
656 | for (o = th->top.p; o < th->stack_last.p + EXTRA_STACK; o++) | ||
653 | setnilvalue(s2v(o)); /* clear dead stack slice */ | 657 | setnilvalue(s2v(o)); /* clear dead stack slice */ |
654 | /* 'remarkupvals' may have removed thread from 'twups' list */ | 658 | /* 'remarkupvals' may have removed thread from 'twups' list */ |
655 | if (!isintwups(th) && th->openupval != NULL) { | 659 | if (!isintwups(th) && th->openupval != NULL) { |
@@ -657,8 +661,6 @@ static int traversethread (global_State *g, lua_State *th) { | |||
657 | g->twups = th; | 661 | g->twups = th; |
658 | } | 662 | } |
659 | } | 663 | } |
660 | else if (!g->gcemergency) | ||
661 | luaD_shrinkstack(th); /* do not change stack in emergency cycle */ | ||
662 | return 1 + stacksize(th); | 664 | return 1 + stacksize(th); |
663 | } | 665 | } |
664 | 666 | ||
@@ -1420,7 +1422,7 @@ static void stepgenfull (lua_State *L, global_State *g) { | |||
1420 | setminordebt(g); | 1422 | setminordebt(g); |
1421 | } | 1423 | } |
1422 | else { /* another bad collection; stay in incremental mode */ | 1424 | else { /* another bad collection; stay in incremental mode */ |
1423 | g->GCestimate = gettotalbytes(g); /* first estimate */; | 1425 | g->GCestimate = gettotalbytes(g); /* first estimate */ |
1424 | entersweep(L); | 1426 | entersweep(L); |
1425 | luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ | 1427 | luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */ |
1426 | setpause(g); | 1428 | setpause(g); |
@@ -1615,7 +1617,7 @@ static lu_mem singlestep (lua_State *L) { | |||
1615 | case GCSenteratomic: { | 1617 | case GCSenteratomic: { |
1616 | work = atomic(L); /* work is what was traversed by 'atomic' */ | 1618 | work = atomic(L); /* work is what was traversed by 'atomic' */ |
1617 | entersweep(L); | 1619 | entersweep(L); |
1618 | g->GCestimate = gettotalbytes(g); /* first estimate */; | 1620 | g->GCestimate = gettotalbytes(g); /* first estimate */ |
1619 | break; | 1621 | break; |
1620 | } | 1622 | } |
1621 | case GCSswpallgc: { /* sweep "regular" objects */ | 1623 | case GCSswpallgc: { /* sweep "regular" objects */ |
@@ -1721,6 +1723,8 @@ static void fullinc (lua_State *L, global_State *g) { | |||
1721 | entersweep(L); /* sweep everything to turn them back to white */ | 1723 | entersweep(L); /* sweep everything to turn them back to white */ |
1722 | /* finish any pending sweep phase to start a new cycle */ | 1724 | /* finish any pending sweep phase to start a new cycle */ |
1723 | luaC_runtilstate(L, bitmask(GCSpause)); | 1725 | luaC_runtilstate(L, bitmask(GCSpause)); |
1726 | luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */ | ||
1727 | g->gcstate = GCSenteratomic; /* go straight to atomic phase ??? */ | ||
1724 | luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ | 1728 | luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */ |
1725 | /* estimate must be correct after a full GC cycle */ | 1729 | /* estimate must be correct after a full GC cycle */ |
1726 | lua_assert(g->GCestimate == gettotalbytes(g)); | 1730 | lua_assert(g->GCestimate == gettotalbytes(g)); |
@@ -249,6 +249,15 @@ static int math_type (lua_State *L) { | |||
249 | ** =================================================================== | 249 | ** =================================================================== |
250 | */ | 250 | */ |
251 | 251 | ||
252 | /* | ||
253 | ** This code uses lots of shifts. ANSI C does not allow shifts greater | ||
254 | ** than or equal to the width of the type being shifted, so some shifts | ||
255 | ** are written in convoluted ways to match that restriction. For | ||
256 | ** preprocessor tests, it assumes a width of 32 bits, so the maximum | ||
257 | ** shift there is 31 bits. | ||
258 | */ | ||
259 | |||
260 | |||
252 | /* number of binary digits in the mantissa of a float */ | 261 | /* number of binary digits in the mantissa of a float */ |
253 | #define FIGS l_floatatt(MANT_DIG) | 262 | #define FIGS l_floatatt(MANT_DIG) |
254 | 263 | ||
@@ -271,16 +280,19 @@ static int math_type (lua_State *L) { | |||
271 | 280 | ||
272 | /* 'long' has at least 64 bits */ | 281 | /* 'long' has at least 64 bits */ |
273 | #define Rand64 unsigned long | 282 | #define Rand64 unsigned long |
283 | #define SRand64 long | ||
274 | 284 | ||
275 | #elif !defined(LUA_USE_C89) && defined(LLONG_MAX) | 285 | #elif !defined(LUA_USE_C89) && defined(LLONG_MAX) |
276 | 286 | ||
277 | /* there is a 'long long' type (which must have at least 64 bits) */ | 287 | /* there is a 'long long' type (which must have at least 64 bits) */ |
278 | #define Rand64 unsigned long long | 288 | #define Rand64 unsigned long long |
289 | #define SRand64 long long | ||
279 | 290 | ||
280 | #elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3 | 291 | #elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3 |
281 | 292 | ||
282 | /* 'lua_Unsigned' has at least 64 bits */ | 293 | /* 'lua_Unsigned' has at least 64 bits */ |
283 | #define Rand64 lua_Unsigned | 294 | #define Rand64 lua_Unsigned |
295 | #define SRand64 lua_Integer | ||
284 | 296 | ||
285 | #endif | 297 | #endif |
286 | 298 | ||
@@ -319,23 +331,30 @@ static Rand64 nextrand (Rand64 *state) { | |||
319 | } | 331 | } |
320 | 332 | ||
321 | 333 | ||
322 | /* must take care to not shift stuff by more than 63 slots */ | ||
323 | |||
324 | |||
325 | /* | 334 | /* |
326 | ** Convert bits from a random integer into a float in the | 335 | ** Convert bits from a random integer into a float in the |
327 | ** interval [0,1), getting the higher FIG bits from the | 336 | ** interval [0,1), getting the higher FIG bits from the |
328 | ** random unsigned integer and converting that to a float. | 337 | ** random unsigned integer and converting that to a float. |
338 | ** Some old Microsoft compilers cannot cast an unsigned long | ||
339 | ** to a floating-point number, so we use a signed long as an | ||
340 | ** intermediary. When lua_Number is float or double, the shift ensures | ||
341 | ** that 'sx' is non negative; in that case, a good compiler will remove | ||
342 | ** the correction. | ||
329 | */ | 343 | */ |
330 | 344 | ||
331 | /* must throw out the extra (64 - FIGS) bits */ | 345 | /* must throw out the extra (64 - FIGS) bits */ |
332 | #define shift64_FIG (64 - FIGS) | 346 | #define shift64_FIG (64 - FIGS) |
333 | 347 | ||
334 | /* to scale to [0, 1), multiply by scaleFIG = 2^(-FIGS) */ | 348 | /* 2^(-FIGS) == 2^-1 / 2^(FIGS-1) */ |
335 | #define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1))) | 349 | #define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1))) |
336 | 350 | ||
337 | static lua_Number I2d (Rand64 x) { | 351 | static lua_Number I2d (Rand64 x) { |
338 | return (lua_Number)(trim64(x) >> shift64_FIG) * scaleFIG; | 352 | SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG); |
353 | lua_Number res = (lua_Number)(sx) * scaleFIG; | ||
354 | if (sx < 0) | ||
355 | res += 1.0; /* correct the two's complement if negative */ | ||
356 | lua_assert(0 <= res && res < 1); | ||
357 | return res; | ||
339 | } | 358 | } |
340 | 359 | ||
341 | /* convert a 'Rand64' to a 'lua_Unsigned' */ | 360 | /* convert a 'Rand64' to a 'lua_Unsigned' */ |
@@ -471,8 +490,6 @@ static lua_Number I2d (Rand64 x) { | |||
471 | 490 | ||
472 | #else /* 32 < FIGS <= 64 */ | 491 | #else /* 32 < FIGS <= 64 */ |
473 | 492 | ||
474 | /* must take care to not shift stuff by more than 31 slots */ | ||
475 | |||
476 | /* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ | 493 | /* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */ |
477 | #define scaleFIG \ | 494 | #define scaleFIG \ |
478 | (l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33))) | 495 | (l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33))) |
@@ -25,15 +25,6 @@ | |||
25 | 25 | ||
26 | 26 | ||
27 | /* | 27 | /* |
28 | ** LUA_IGMARK is a mark to ignore all before it when building the | ||
29 | ** luaopen_ function name. | ||
30 | */ | ||
31 | #if !defined (LUA_IGMARK) | ||
32 | #define LUA_IGMARK "-" | ||
33 | #endif | ||
34 | |||
35 | |||
36 | /* | ||
37 | ** LUA_CSUBSEP is the character that replaces dots in submodule names | 28 | ** LUA_CSUBSEP is the character that replaces dots in submodule names |
38 | ** when searching for a C loader. | 29 | ** when searching for a C loader. |
39 | ** LUA_LSUBSEP is the character that replaces dots in submodule names | 30 | ** LUA_LSUBSEP is the character that replaces dots in submodule names |
@@ -542,7 +542,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | |||
542 | addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ | 542 | addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ |
543 | clearbuff(&buff); /* empty buffer into the stack */ | 543 | clearbuff(&buff); /* empty buffer into the stack */ |
544 | lua_assert(buff.pushed == 1); | 544 | lua_assert(buff.pushed == 1); |
545 | return svalue(s2v(L->top.p - 1)); | 545 | return getstr(tsvalue(s2v(L->top.p - 1))); |
546 | } | 546 | } |
547 | 547 | ||
548 | 548 | ||
@@ -388,7 +388,7 @@ typedef struct GCObject { | |||
388 | typedef struct TString { | 388 | typedef struct TString { |
389 | CommonHeader; | 389 | CommonHeader; |
390 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ | 390 | lu_byte extra; /* reserved words for short strings; "has hash" for longs */ |
391 | lu_byte shrlen; /* length for short strings */ | 391 | lu_byte shrlen; /* length for short strings, 0xFF for long strings */ |
392 | unsigned int hash; | 392 | unsigned int hash; |
393 | union { | 393 | union { |
394 | size_t lnglen; /* length for long strings */ | 394 | size_t lnglen; /* length for long strings */ |
@@ -400,19 +400,17 @@ typedef struct TString { | |||
400 | 400 | ||
401 | 401 | ||
402 | /* | 402 | /* |
403 | ** Get the actual string (array of bytes) from a 'TString'. | 403 | ** Get the actual string (array of bytes) from a 'TString'. (Generic |
404 | ** version and specialized versions for long and short strings.) | ||
404 | */ | 405 | */ |
405 | #define getstr(ts) ((ts)->contents) | 406 | #define getstr(ts) ((ts)->contents) |
407 | #define getlngstr(ts) check_exp((ts)->shrlen == 0xFF, (ts)->contents) | ||
408 | #define getshrstr(ts) check_exp((ts)->shrlen != 0xFF, (ts)->contents) | ||
406 | 409 | ||
407 | 410 | ||
408 | /* get the actual string (array of bytes) from a Lua value */ | ||
409 | #define svalue(o) getstr(tsvalue(o)) | ||
410 | |||
411 | /* get string length from 'TString *s' */ | 411 | /* get string length from 'TString *s' */ |
412 | #define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen) | 412 | #define tsslen(s) \ |
413 | 413 | ((s)->shrlen != 0xFF ? (s)->shrlen : (s)->u.lnglen) | |
414 | /* get string length from 'TValue *o' */ | ||
415 | #define vslen(o) tsslen(tsvalue(o)) | ||
416 | 414 | ||
417 | /* }================================================================== */ | 415 | /* }================================================================== */ |
418 | 416 | ||
@@ -210,15 +210,15 @@ OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */ | |||
210 | OP_GETUPVAL,/* A B R[A] := UpValue[B] */ | 210 | OP_GETUPVAL,/* A B R[A] := UpValue[B] */ |
211 | OP_SETUPVAL,/* A B UpValue[B] := R[A] */ | 211 | OP_SETUPVAL,/* A B UpValue[B] := R[A] */ |
212 | 212 | ||
213 | OP_GETTABUP,/* A B C R[A] := UpValue[B][K[C]:string] */ | 213 | OP_GETTABUP,/* A B C R[A] := UpValue[B][K[C]:shortstring] */ |
214 | OP_GETTABLE,/* A B C R[A] := R[B][R[C]] */ | 214 | OP_GETTABLE,/* A B C R[A] := R[B][R[C]] */ |
215 | OP_GETI,/* A B C R[A] := R[B][C] */ | 215 | OP_GETI,/* A B C R[A] := R[B][C] */ |
216 | OP_GETFIELD,/* A B C R[A] := R[B][K[C]:string] */ | 216 | OP_GETFIELD,/* A B C R[A] := R[B][K[C]:shortstring] */ |
217 | 217 | ||
218 | OP_SETTABUP,/* A B C UpValue[A][K[B]:string] := RK(C) */ | 218 | OP_SETTABUP,/* A B C UpValue[A][K[B]:shortstring] := RK(C) */ |
219 | OP_SETTABLE,/* A B C R[A][R[B]] := RK(C) */ | 219 | OP_SETTABLE,/* A B C R[A][R[B]] := RK(C) */ |
220 | OP_SETI,/* A B C R[A][B] := RK(C) */ | 220 | OP_SETI,/* A B C R[A][B] := RK(C) */ |
221 | OP_SETFIELD,/* A B C R[A][K[B]:string] := RK(C) */ | 221 | OP_SETFIELD,/* A B C R[A][K[B]:shortstring] := RK(C) */ |
222 | 222 | ||
223 | OP_NEWTABLE,/* A B C k R[A] := {} */ | 223 | OP_NEWTABLE,/* A B C k R[A] := {} */ |
224 | 224 | ||
@@ -1022,10 +1022,11 @@ static int explist (LexState *ls, expdesc *v) { | |||
1022 | } | 1022 | } |
1023 | 1023 | ||
1024 | 1024 | ||
1025 | static void funcargs (LexState *ls, expdesc *f, int line) { | 1025 | static void funcargs (LexState *ls, expdesc *f) { |
1026 | FuncState *fs = ls->fs; | 1026 | FuncState *fs = ls->fs; |
1027 | expdesc args; | 1027 | expdesc args; |
1028 | int base, nparams; | 1028 | int base, nparams; |
1029 | int line = ls->linenumber; | ||
1029 | switch (ls->t.token) { | 1030 | switch (ls->t.token) { |
1030 | case '(': { /* funcargs -> '(' [ explist ] ')' */ | 1031 | case '(': { /* funcargs -> '(' [ explist ] ')' */ |
1031 | luaX_next(ls); | 1032 | luaX_next(ls); |
@@ -1063,8 +1064,8 @@ static void funcargs (LexState *ls, expdesc *f, int line) { | |||
1063 | } | 1064 | } |
1064 | init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); | 1065 | init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); |
1065 | luaK_fixline(fs, line); | 1066 | luaK_fixline(fs, line); |
1066 | fs->freereg = base+1; /* call remove function and arguments and leaves | 1067 | fs->freereg = base+1; /* call removes function and arguments and leaves |
1067 | (unless changed) one result */ | 1068 | one result (unless changed later) */ |
1068 | } | 1069 | } |
1069 | 1070 | ||
1070 | 1071 | ||
@@ -1103,7 +1104,6 @@ static void suffixedexp (LexState *ls, expdesc *v) { | |||
1103 | /* suffixedexp -> | 1104 | /* suffixedexp -> |
1104 | primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ | 1105 | primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ |
1105 | FuncState *fs = ls->fs; | 1106 | FuncState *fs = ls->fs; |
1106 | int line = ls->linenumber; | ||
1107 | primaryexp(ls, v); | 1107 | primaryexp(ls, v); |
1108 | for (;;) { | 1108 | for (;;) { |
1109 | switch (ls->t.token) { | 1109 | switch (ls->t.token) { |
@@ -1123,12 +1123,12 @@ static void suffixedexp (LexState *ls, expdesc *v) { | |||
1123 | luaX_next(ls); | 1123 | luaX_next(ls); |
1124 | codename(ls, &key); | 1124 | codename(ls, &key); |
1125 | luaK_self(fs, v, &key); | 1125 | luaK_self(fs, v, &key); |
1126 | funcargs(ls, v, line); | 1126 | funcargs(ls, v); |
1127 | break; | 1127 | break; |
1128 | } | 1128 | } |
1129 | case '(': case TK_STRING: case '{': { /* funcargs */ | 1129 | case '(': case TK_STRING: case '{': { /* funcargs */ |
1130 | luaK_exp2nextreg(fs, v); | 1130 | luaK_exp2nextreg(fs, v); |
1131 | funcargs(ls, v, line); | 1131 | funcargs(ls, v); |
1132 | break; | 1132 | break; |
1133 | } | 1133 | } |
1134 | default: return; | 1134 | default: return; |
@@ -119,7 +119,7 @@ CallInfo *luaE_extendCI (lua_State *L) { | |||
119 | /* | 119 | /* |
120 | ** free all CallInfo structures not in use by a thread | 120 | ** free all CallInfo structures not in use by a thread |
121 | */ | 121 | */ |
122 | void luaE_freeCI (lua_State *L) { | 122 | static void freeCI (lua_State *L) { |
123 | CallInfo *ci = L->ci; | 123 | CallInfo *ci = L->ci; |
124 | CallInfo *next = ci->next; | 124 | CallInfo *next = ci->next; |
125 | ci->next = NULL; | 125 | ci->next = NULL; |
@@ -204,7 +204,7 @@ static void freestack (lua_State *L) { | |||
204 | if (L->stack.p == NULL) | 204 | if (L->stack.p == NULL) |
205 | return; /* stack not completely built yet */ | 205 | return; /* stack not completely built yet */ |
206 | L->ci = &L->base_ci; /* free the entire 'ci' list */ | 206 | L->ci = &L->base_ci; /* free the entire 'ci' list */ |
207 | luaE_freeCI(L); | 207 | freeCI(L); |
208 | lua_assert(L->nci == 0); | 208 | lua_assert(L->nci == 0); |
209 | luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK); /* free stack */ | 209 | luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK); /* free stack */ |
210 | } | 210 | } |
@@ -436,7 +436,7 @@ void luaE_warning (lua_State *L, const char *msg, int tocont) { | |||
436 | void luaE_warnerror (lua_State *L, const char *where) { | 436 | void luaE_warnerror (lua_State *L, const char *where) { |
437 | TValue *errobj = s2v(L->top.p - 1); /* error object */ | 437 | TValue *errobj = s2v(L->top.p - 1); /* error object */ |
438 | const char *msg = (ttisstring(errobj)) | 438 | const char *msg = (ttisstring(errobj)) |
439 | ? svalue(errobj) | 439 | ? getstr(tsvalue(errobj)) |
440 | : "error object is not a string"; | 440 | : "error object is not a string"; |
441 | /* produce warning "error in %s (%s)" (where, msg) */ | 441 | /* produce warning "error in %s (%s)" (where, msg) */ |
442 | luaE_warning(L, "error in ", 1); | 442 | luaE_warning(L, "error in ", 1); |
@@ -181,7 +181,7 @@ struct CallInfo { | |||
181 | union { | 181 | union { |
182 | struct { /* only for Lua functions */ | 182 | struct { /* only for Lua functions */ |
183 | const Instruction *savedpc; | 183 | const Instruction *savedpc; |
184 | volatile l_signalT trap; | 184 | volatile l_signalT trap; /* function is tracing lines/counts */ |
185 | int nextraargs; /* # of extra arguments in vararg functions */ | 185 | int nextraargs; /* # of extra arguments in vararg functions */ |
186 | } l; | 186 | } l; |
187 | struct { /* only for C functions */ | 187 | struct { /* only for C functions */ |
@@ -396,7 +396,6 @@ union GCUnion { | |||
396 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); | 396 | LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); |
397 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | 397 | LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); |
398 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | 398 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); |
399 | LUAI_FUNC void luaE_freeCI (lua_State *L); | ||
400 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); | 399 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); |
401 | LUAI_FUNC void luaE_checkcstack (lua_State *L); | 400 | LUAI_FUNC void luaE_checkcstack (lua_State *L); |
402 | LUAI_FUNC void luaE_incCstack (lua_State *L); | 401 | LUAI_FUNC void luaE_incCstack (lua_State *L); |
@@ -36,7 +36,7 @@ int luaS_eqlngstr (TString *a, TString *b) { | |||
36 | lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); | 36 | lua_assert(a->tt == LUA_VLNGSTR && b->tt == LUA_VLNGSTR); |
37 | return (a == b) || /* same instance or... */ | 37 | return (a == b) || /* same instance or... */ |
38 | ((len == b->u.lnglen) && /* equal length and ... */ | 38 | ((len == b->u.lnglen) && /* equal length and ... */ |
39 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ | 39 | (memcmp(getlngstr(a), getlngstr(b), len) == 0)); /* equal contents */ |
40 | } | 40 | } |
41 | 41 | ||
42 | 42 | ||
@@ -52,7 +52,7 @@ unsigned int luaS_hashlongstr (TString *ts) { | |||
52 | lua_assert(ts->tt == LUA_VLNGSTR); | 52 | lua_assert(ts->tt == LUA_VLNGSTR); |
53 | if (ts->extra == 0) { /* no hash? */ | 53 | if (ts->extra == 0) { /* no hash? */ |
54 | size_t len = ts->u.lnglen; | 54 | size_t len = ts->u.lnglen; |
55 | ts->hash = luaS_hash(getstr(ts), len, ts->hash); | 55 | ts->hash = luaS_hash(getlngstr(ts), len, ts->hash); |
56 | ts->extra = 1; /* now it has its hash */ | 56 | ts->extra = 1; /* now it has its hash */ |
57 | } | 57 | } |
58 | return ts->hash; | 58 | return ts->hash; |
@@ -157,6 +157,7 @@ static TString *createstrobj (lua_State *L, size_t l, int tag, unsigned int h) { | |||
157 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { | 157 | TString *luaS_createlngstrobj (lua_State *L, size_t l) { |
158 | TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); | 158 | TString *ts = createstrobj(L, l, LUA_VLNGSTR, G(L)->seed); |
159 | ts->u.lnglen = l; | 159 | ts->u.lnglen = l; |
160 | ts->shrlen = 0xFF; /* signals that it is a long string */ | ||
160 | return ts; | 161 | return ts; |
161 | } | 162 | } |
162 | 163 | ||
@@ -193,7 +194,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
193 | TString **list = &tb->hash[lmod(h, tb->size)]; | 194 | TString **list = &tb->hash[lmod(h, tb->size)]; |
194 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ | 195 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ |
195 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { | 196 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { |
196 | if (l == ts->shrlen && (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { | 197 | if (l == ts->shrlen && (memcmp(str, getshrstr(ts), l * sizeof(char)) == 0)) { |
197 | /* found! */ | 198 | /* found! */ |
198 | if (isdead(g, ts)) /* dead (but not collected yet)? */ | 199 | if (isdead(g, ts)) /* dead (but not collected yet)? */ |
199 | changewhite(ts); /* resurrect it */ | 200 | changewhite(ts); /* resurrect it */ |
@@ -206,8 +207,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
206 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ | 207 | list = &tb->hash[lmod(h, tb->size)]; /* rehash with new size */ |
207 | } | 208 | } |
208 | ts = createstrobj(L, l, LUA_VSHRSTR, h); | 209 | ts = createstrobj(L, l, LUA_VSHRSTR, h); |
209 | memcpy(getstr(ts), str, l * sizeof(char)); | ||
210 | ts->shrlen = cast_byte(l); | 210 | ts->shrlen = cast_byte(l); |
211 | memcpy(getshrstr(ts), str, l * sizeof(char)); | ||
211 | ts->u.hnext = *list; | 212 | ts->u.hnext = *list; |
212 | *list = ts; | 213 | *list = ts; |
213 | tb->nuse++; | 214 | tb->nuse++; |
@@ -226,7 +227,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
226 | if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) | 227 | if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) |
227 | luaM_toobig(L); | 228 | luaM_toobig(L); |
228 | ts = luaS_createlngstrobj(L, l); | 229 | ts = luaS_createlngstrobj(L, l); |
229 | memcpy(getstr(ts), str, l * sizeof(char)); | 230 | memcpy(getlngstr(ts), str, l * sizeof(char)); |
230 | return ts; | 231 | return ts; |
231 | } | 232 | } |
232 | } | 233 | } |
@@ -252,7 +252,7 @@ LUAI_FUNC unsigned int luaH_realasize (const Table *t) { | |||
252 | return t->alimit; /* this is the size */ | 252 | return t->alimit; /* this is the size */ |
253 | else { | 253 | else { |
254 | unsigned int size = t->alimit; | 254 | unsigned int size = t->alimit; |
255 | /* compute the smallest power of 2 not smaller than 'n' */ | 255 | /* compute the smallest power of 2 not smaller than 'size' */ |
256 | size |= (size >> 1); | 256 | size |= (size >> 1); |
257 | size |= (size >> 2); | 257 | size |= (size >> 2); |
258 | size |= (size >> 4); | 258 | size |= (size >> 4); |
@@ -736,7 +736,8 @@ static Node *getfreepos (Table *t) { | |||
736 | ** put new key in its main position; otherwise (colliding node is in its main | 736 | ** put new key in its main position; otherwise (colliding node is in its main |
737 | ** position), new key goes to an empty position. | 737 | ** position), new key goes to an empty position. |
738 | */ | 738 | */ |
739 | void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) { | 739 | static void luaH_newkey (lua_State *L, Table *t, const TValue *key, |
740 | TValue *value) { | ||
740 | Node *mp; | 741 | Node *mp; |
741 | TValue aux; | 742 | TValue aux; |
742 | if (l_unlikely(ttisnil(key))) | 743 | if (l_unlikely(ttisnil(key))) |
@@ -130,8 +130,6 @@ LUAI_FUNC int luaH_pset (Table *t, const TValue *key, TValue *val); | |||
130 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, | 130 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, |
131 | TValue *value); | 131 | TValue *value); |
132 | LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key); | 132 | LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key); |
133 | LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, | ||
134 | TValue *value); | ||
135 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, | 133 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, |
136 | TValue *value); | 134 | TValue *value); |
137 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, | 135 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, |
@@ -9,7 +9,6 @@ | |||
9 | 9 | ||
10 | 10 | ||
11 | #include "lobject.h" | 11 | #include "lobject.h" |
12 | #include "lstate.h" | ||
13 | 12 | ||
14 | 13 | ||
15 | /* | 14 | /* |
@@ -96,8 +95,8 @@ LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, | |||
96 | int inv, int isfloat, TMS event); | 95 | int inv, int isfloat, TMS event); |
97 | 96 | ||
98 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, | 97 | LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, |
99 | CallInfo *ci, const Proto *p); | 98 | struct CallInfo *ci, const Proto *p); |
100 | LUAI_FUNC void luaT_getvarargs (lua_State *L, CallInfo *ci, | 99 | LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, |
101 | StkId where, int wanted); | 100 | StkId where, int wanted); |
102 | 101 | ||
103 | 102 | ||
@@ -210,12 +210,17 @@ static int dostring (lua_State *L, const char *s, const char *name) { | |||
210 | 210 | ||
211 | /* | 211 | /* |
212 | ** Receives 'globname[=modname]' and runs 'globname = require(modname)'. | 212 | ** Receives 'globname[=modname]' and runs 'globname = require(modname)'. |
213 | ** If there is no explicit modname and globname contains a '-', cut | ||
214 | ** the sufix after '-' (the "version") to make the global name. | ||
213 | */ | 215 | */ |
214 | static int dolibrary (lua_State *L, char *globname) { | 216 | static int dolibrary (lua_State *L, char *globname) { |
215 | int status; | 217 | int status; |
218 | char *suffix = NULL; | ||
216 | char *modname = strchr(globname, '='); | 219 | char *modname = strchr(globname, '='); |
217 | if (modname == NULL) /* no explicit name? */ | 220 | if (modname == NULL) { /* no explicit name? */ |
218 | modname = globname; /* module name is equal to global name */ | 221 | modname = globname; /* module name is equal to global name */ |
222 | suffix = strchr(modname, *LUA_IGMARK); /* look for a suffix mark */ | ||
223 | } | ||
219 | else { | 224 | else { |
220 | *modname = '\0'; /* global name ends here */ | 225 | *modname = '\0'; /* global name ends here */ |
221 | modname++; /* module name starts after the '=' */ | 226 | modname++; /* module name starts after the '=' */ |
@@ -223,8 +228,11 @@ static int dolibrary (lua_State *L, char *globname) { | |||
223 | lua_getglobal(L, "require"); | 228 | lua_getglobal(L, "require"); |
224 | lua_pushstring(L, modname); | 229 | lua_pushstring(L, modname); |
225 | status = docall(L, 1, 1); /* call 'require(modname)' */ | 230 | status = docall(L, 1, 1); /* call 'require(modname)' */ |
226 | if (status == LUA_OK) | 231 | if (status == LUA_OK) { |
232 | if (suffix != NULL) /* is there a suffix mark? */ | ||
233 | *suffix = '\0'; /* remove sufix from global name */ | ||
227 | lua_setglobal(L, globname); /* globname = require(modname) */ | 234 | lua_setglobal(L, globname); /* globname = require(modname) */ |
235 | } | ||
228 | return report(L, status); | 236 | return report(L, status); |
229 | } | 237 | } |
230 | 238 | ||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h $ | 2 | ** $Id: lua.h $ |
3 | ** Lua - A Scripting Language | 3 | ** Lua - A Scripting Language |
4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (www.lua.org) |
5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
6 | */ | 6 | */ |
7 | 7 | ||
@@ -13,20 +13,19 @@ | |||
13 | #include <stddef.h> | 13 | #include <stddef.h> |
14 | 14 | ||
15 | 15 | ||
16 | #include "luaconf.h" | 16 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2023 Lua.org, PUC-Rio" |
17 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" | ||
17 | 18 | ||
18 | 19 | ||
19 | #define LUA_VERSION_MAJOR "5" | 20 | #define LUA_VERSION_MAJOR_N 5 |
20 | #define LUA_VERSION_MINOR "4" | 21 | #define LUA_VERSION_MINOR_N 4 |
21 | #define LUA_VERSION_RELEASE "6" | 22 | #define LUA_VERSION_RELEASE_N 6 |
22 | 23 | ||
23 | #define LUA_VERSION_NUM 504 | 24 | #define LUA_VERSION_NUM (LUA_VERSION_MAJOR_N * 100 + LUA_VERSION_MINOR_N) |
24 | #define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 6) | 25 | #define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + LUA_VERSION_RELEASE_N) |
25 | 26 | ||
26 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR | 27 | |
27 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE | 28 | #include "luaconf.h" |
28 | #define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2023 Lua.org, PUC-Rio" | ||
29 | #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" | ||
30 | 29 | ||
31 | 30 | ||
32 | /* mark for precompiled code ('<esc>Lua') */ | 31 | /* mark for precompiled code ('<esc>Lua') */ |
@@ -496,6 +495,17 @@ struct lua_Debug { | |||
496 | /* }====================================================================== */ | 495 | /* }====================================================================== */ |
497 | 496 | ||
498 | 497 | ||
498 | #define LUAI_TOSTRAUX(x) #x | ||
499 | #define LUAI_TOSTR(x) LUAI_TOSTRAUX(x) | ||
500 | |||
501 | #define LUA_VERSION_MAJOR LUAI_TOSTR(LUA_VERSION_MAJOR_N) | ||
502 | #define LUA_VERSION_MINOR LUAI_TOSTR(LUA_VERSION_MINOR_N) | ||
503 | #define LUA_VERSION_RELEASE LUAI_TOSTR(LUA_VERSION_RELEASE_N) | ||
504 | |||
505 | #define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR | ||
506 | #define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE | ||
507 | |||
508 | |||
499 | /****************************************************************************** | 509 | /****************************************************************************** |
500 | * Copyright (C) 1994-2023 Lua.org, PUC-Rio. | 510 | * Copyright (C) 1994-2023 Lua.org, PUC-Rio. |
501 | * | 511 | * |
@@ -257,6 +257,15 @@ | |||
257 | 257 | ||
258 | #endif | 258 | #endif |
259 | 259 | ||
260 | |||
261 | /* | ||
262 | ** LUA_IGMARK is a mark to ignore all after it when building the | ||
263 | ** module name (e.g., used to build the luaopen_ function name). | ||
264 | ** Typically, the sufix after the mark is the module version, | ||
265 | ** as in "mod-v1.2.so". | ||
266 | */ | ||
267 | #define LUA_IGMARK "-" | ||
268 | |||
260 | /* }================================================================== */ | 269 | /* }================================================================== */ |
261 | 270 | ||
262 | 271 | ||
@@ -81,7 +81,7 @@ static size_t loadUnsigned (LoadState *S, size_t limit) { | |||
81 | 81 | ||
82 | 82 | ||
83 | static size_t loadSize (LoadState *S) { | 83 | static size_t loadSize (LoadState *S) { |
84 | return loadUnsigned(S, ~(size_t)0); | 84 | return loadUnsigned(S, MAX_SIZET); |
85 | } | 85 | } |
86 | 86 | ||
87 | 87 | ||
@@ -122,7 +122,7 @@ static TString *loadStringN (LoadState *S, Proto *p) { | |||
122 | ts = luaS_createlngstrobj(L, size); /* create string */ | 122 | ts = luaS_createlngstrobj(L, size); /* create string */ |
123 | setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */ | 123 | setsvalue2s(L, L->top.p, ts); /* anchor it ('loadVector' can GC) */ |
124 | luaD_inctop(L); | 124 | luaD_inctop(L); |
125 | loadVector(S, getstr(ts), size); /* load directly in final place */ | 125 | loadVector(S, getlngstr(ts), size); /* load directly in final place */ |
126 | L->top.p--; /* pop string */ | 126 | L->top.p--; /* pop string */ |
127 | } | 127 | } |
128 | luaC_objbarrier(L, p, ts); | 128 | luaC_objbarrier(L, p, ts); |
@@ -21,8 +21,7 @@ | |||
21 | /* | 21 | /* |
22 | ** Encode major-minor version in one byte, one nibble for each | 22 | ** Encode major-minor version in one byte, one nibble for each |
23 | */ | 23 | */ |
24 | #define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ | 24 | #define LUAC_VERSION (LUA_VERSION_MAJOR_N*16+LUA_VERSION_MINOR_N) |
25 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) | ||
26 | 25 | ||
27 | #define LUAC_FORMAT 0 /* this is the official format */ | 26 | #define LUAC_FORMAT 0 /* this is the official format */ |
28 | 27 | ||
@@ -91,8 +91,10 @@ static int l_strton (const TValue *obj, TValue *result) { | |||
91 | lua_assert(obj != result); | 91 | lua_assert(obj != result); |
92 | if (!cvt2num(obj)) /* is object not a string? */ | 92 | if (!cvt2num(obj)) /* is object not a string? */ |
93 | return 0; | 93 | return 0; |
94 | else | 94 | else { |
95 | return (luaO_str2num(svalue(obj), result) == vslen(obj) + 1); | 95 | TString *st = tsvalue(obj); |
96 | return (luaO_str2num(getstr(st), result) == tsslen(st) + 1); | ||
97 | } | ||
96 | } | 98 | } |
97 | 99 | ||
98 | 100 | ||
@@ -356,30 +358,32 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | |||
356 | 358 | ||
357 | 359 | ||
358 | /* | 360 | /* |
359 | ** Compare two strings 'ls' x 'rs', returning an integer less-equal- | 361 | ** Compare two strings 'ts1' x 'ts2', returning an integer less-equal- |
360 | ** -greater than zero if 'ls' is less-equal-greater than 'rs'. | 362 | ** -greater than zero if 'ts1' is less-equal-greater than 'ts2'. |
361 | ** The code is a little tricky because it allows '\0' in the strings | 363 | ** The code is a little tricky because it allows '\0' in the strings |
362 | ** and it uses 'strcoll' (to respect locales) for each segments | 364 | ** and it uses 'strcoll' (to respect locales) for each segment |
363 | ** of the strings. | 365 | ** of the strings. Note that segments can compare equal but still |
366 | ** have different lengths. | ||
364 | */ | 367 | */ |
365 | static int l_strcmp (const TString *ls, const TString *rs) { | 368 | static int l_strcmp (const TString *ts1, const TString *ts2) { |
366 | const char *l = getstr(ls); | 369 | const char *s1 = getstr(ts1); |
367 | size_t ll = tsslen(ls); | 370 | size_t rl1 = tsslen(ts1); /* real length */ |
368 | const char *r = getstr(rs); | 371 | const char *s2 = getstr(ts2); |
369 | size_t lr = tsslen(rs); | 372 | size_t rl2 = tsslen(ts2); |
370 | for (;;) { /* for each segment */ | 373 | for (;;) { /* for each segment */ |
371 | int temp = strcoll(l, r); | 374 | int temp = strcoll(s1, s2); |
372 | if (temp != 0) /* not equal? */ | 375 | if (temp != 0) /* not equal? */ |
373 | return temp; /* done */ | 376 | return temp; /* done */ |
374 | else { /* strings are equal up to a '\0' */ | 377 | else { /* strings are equal up to a '\0' */ |
375 | size_t len = strlen(l); /* index of first '\0' in both strings */ | 378 | size_t zl1 = strlen(s1); /* index of first '\0' in 's1' */ |
376 | if (len == lr) /* 'rs' is finished? */ | 379 | size_t zl2 = strlen(s2); /* index of first '\0' in 's2' */ |
377 | return (len == ll) ? 0 : 1; /* check 'ls' */ | 380 | if (zl2 == rl2) /* 's2' is finished? */ |
378 | else if (len == ll) /* 'ls' is finished? */ | 381 | return (zl1 == rl1) ? 0 : 1; /* check 's1' */ |
379 | return -1; /* 'ls' is less than 'rs' ('rs' is not finished) */ | 382 | else if (zl1 == rl1) /* 's1' is finished? */ |
380 | /* both strings longer than 'len'; go on comparing after the '\0' */ | 383 | return -1; /* 's1' is less than 's2' ('s2' is not finished) */ |
381 | len++; | 384 | /* both strings longer than 'zl'; go on comparing after the '\0' */ |
382 | l += len; ll -= len; r += len; lr -= len; | 385 | zl1++; zl2++; |
386 | s1 += zl1; rl1 -= zl1; s2 += zl2; rl2 -= zl2; | ||
383 | } | 387 | } |
384 | } | 388 | } |
385 | } | 389 | } |
@@ -614,8 +618,9 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { | |||
614 | static void copy2buff (StkId top, int n, char *buff) { | 618 | static void copy2buff (StkId top, int n, char *buff) { |
615 | size_t tl = 0; /* size already copied */ | 619 | size_t tl = 0; /* size already copied */ |
616 | do { | 620 | do { |
617 | size_t l = vslen(s2v(top - n)); /* length of string being copied */ | 621 | TString *st = tsvalue(s2v(top - n)); |
618 | memcpy(buff + tl, svalue(s2v(top - n)), l * sizeof(char)); | 622 | size_t l = tsslen(st); /* length of string being copied */ |
623 | memcpy(buff + tl, getstr(st), l * sizeof(char)); | ||
619 | tl += l; | 624 | tl += l; |
620 | } while (--n > 0); | 625 | } while (--n > 0); |
621 | } | 626 | } |
@@ -641,11 +646,11 @@ void luaV_concat (lua_State *L, int total) { | |||
641 | } | 646 | } |
642 | else { | 647 | else { |
643 | /* at least two non-empty string values; get as many as possible */ | 648 | /* at least two non-empty string values; get as many as possible */ |
644 | size_t tl = vslen(s2v(top - 1)); | 649 | size_t tl = tsslen(tsvalue(s2v(top - 1))); |
645 | TString *ts; | 650 | TString *ts; |
646 | /* collect total length and number of strings */ | 651 | /* collect total length and number of strings */ |
647 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { | 652 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { |
648 | size_t l = vslen(s2v(top - n - 1)); | 653 | size_t l = tsslen(tsvalue(s2v(top - n - 1))); |
649 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { | 654 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { |
650 | L->top.p = top - total; /* pop strings to avoid wasting stack */ | 655 | L->top.p = top - total; /* pop strings to avoid wasting stack */ |
651 | luaG_runerror(L, "string length overflow"); | 656 | luaG_runerror(L, "string length overflow"); |
@@ -659,7 +664,7 @@ void luaV_concat (lua_State *L, int total) { | |||
659 | } | 664 | } |
660 | else { /* long string; copy strings directly to final result */ | 665 | else { /* long string; copy strings directly to final result */ |
661 | ts = luaS_createlngstrobj(L, tl); | 666 | ts = luaS_createlngstrobj(L, tl); |
662 | copy2buff(top, n, getstr(ts)); | 667 | copy2buff(top, n, getlngstr(ts)); |
663 | } | 668 | } |
664 | setsvalue2s(L, top - n, ts); /* create result */ | 669 | setsvalue2s(L, top - n, ts); /* create result */ |
665 | } | 670 | } |
@@ -1145,18 +1150,11 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1145 | startfunc: | 1150 | startfunc: |
1146 | trap = L->hookmask; | 1151 | trap = L->hookmask; |
1147 | returning: /* trap already set */ | 1152 | returning: /* trap already set */ |
1148 | cl = clLvalue(s2v(ci->func.p)); | 1153 | cl = ci_func(ci); |
1149 | k = cl->p->k; | 1154 | k = cl->p->k; |
1150 | pc = ci->u.l.savedpc; | 1155 | pc = ci->u.l.savedpc; |
1151 | if (l_unlikely(trap)) { | 1156 | if (l_unlikely(trap)) |
1152 | if (pc == cl->p->code) { /* first instruction (not resuming)? */ | 1157 | trap = luaG_tracecall(L); |
1153 | if (cl->p->is_vararg) | ||
1154 | trap = 0; /* hooks will start after VARARGPREP instruction */ | ||
1155 | else /* check 'call' hook */ | ||
1156 | luaD_hookcall(L, ci); | ||
1157 | } | ||
1158 | ci->u.l.trap = 1; /* assume trap is on, for now */ | ||
1159 | } | ||
1160 | base = ci->func.p + 1; | 1158 | base = ci->func.p + 1; |
1161 | /* main loop of interpreter */ | 1159 | /* main loop of interpreter */ |
1162 | for (;;) { | 1160 | for (;;) { |
@@ -1242,7 +1240,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1242 | StkId ra = RA(i); | 1240 | StkId ra = RA(i); |
1243 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; | 1241 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; |
1244 | TValue *rc = KC(i); | 1242 | TValue *rc = KC(i); |
1245 | TString *key = tsvalue(rc); /* key must be a string */ | 1243 | TString *key = tsvalue(rc); /* key must be a short string */ |
1246 | int hres; | 1244 | int hres; |
1247 | luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, hres); | 1245 | luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, hres); |
1248 | if (hres != HOK) | 1246 | if (hres != HOK) |
@@ -1280,7 +1278,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1280 | StkId ra = RA(i); | 1278 | StkId ra = RA(i); |
1281 | TValue *rb = vRB(i); | 1279 | TValue *rb = vRB(i); |
1282 | TValue *rc = KC(i); | 1280 | TValue *rc = KC(i); |
1283 | TString *key = tsvalue(rc); /* key must be a string */ | 1281 | TString *key = tsvalue(rc); /* key must be a short string */ |
1284 | int hres; | 1282 | int hres; |
1285 | luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, hres); | 1283 | luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, hres); |
1286 | if (hres != HOK) | 1284 | if (hres != HOK) |
@@ -1292,7 +1290,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1292 | TValue *upval = cl->upvals[GETARG_A(i)]->v.p; | 1290 | TValue *upval = cl->upvals[GETARG_A(i)]->v.p; |
1293 | TValue *rb = KB(i); | 1291 | TValue *rb = KB(i); |
1294 | TValue *rc = RKC(i); | 1292 | TValue *rc = RKC(i); |
1295 | TString *key = tsvalue(rb); /* key must be a string */ | 1293 | TString *key = tsvalue(rb); /* key must be a short string */ |
1296 | luaV_fastset(upval, key, rc, hres, luaH_psetshortstr); | 1294 | luaV_fastset(upval, key, rc, hres, luaH_psetshortstr); |
1297 | if (hres == HOK) | 1295 | if (hres == HOK) |
1298 | luaV_finishfastset(L, upval, rc); | 1296 | luaV_finishfastset(L, upval, rc); |
@@ -1337,7 +1335,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1337 | int hres; | 1335 | int hres; |
1338 | TValue *rb = KB(i); | 1336 | TValue *rb = KB(i); |
1339 | TValue *rc = RKC(i); | 1337 | TValue *rc = RKC(i); |
1340 | TString *key = tsvalue(rb); /* key must be a string */ | 1338 | TString *key = tsvalue(rb); /* key must be a short string */ |
1341 | luaV_fastset(s2v(ra), key, rc, hres, luaH_psetshortstr); | 1339 | luaV_fastset(s2v(ra), key, rc, hres, luaH_psetshortstr); |
1342 | if (hres == HOK) | 1340 | if (hres == HOK) |
1343 | luaV_finishfastset(L, s2v(ra), rc); | 1341 | luaV_finishfastset(L, s2v(ra), rc); |
diff --git a/manual/manual.of b/manual/manual.of index f8d8ddd4..ad120f5e 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
@@ -9026,6 +9026,10 @@ Lua does not consult any environment variables. | |||
9026 | In particular, | 9026 | In particular, |
9027 | the values of @Lid{package.path} and @Lid{package.cpath} | 9027 | the values of @Lid{package.path} and @Lid{package.cpath} |
9028 | are set with the default paths defined in @id{luaconf.h}. | 9028 | are set with the default paths defined in @id{luaconf.h}. |
9029 | To signal to the libraries that this option is on, | ||
9030 | the stand-alone interpreter sets the field | ||
9031 | @idx{"LUA_NOENV"} in the registry to a true value. | ||
9032 | Other libraries may consult this field for the same purpose. | ||
9029 | 9033 | ||
9030 | The options @T{-e}, @T{-l}, and @T{-W} are handled in | 9034 | The options @T{-e}, @T{-l}, and @T{-W} are handled in |
9031 | the order they appear. | 9035 | the order they appear. |
diff --git a/testes/calls.lua b/testes/calls.lua index 2d562a24..a1938584 100644 --- a/testes/calls.lua +++ b/testes/calls.lua | |||
@@ -342,20 +342,6 @@ do -- another bug (in 5.4.0) | |||
342 | end | 342 | end |
343 | 343 | ||
344 | 344 | ||
345 | do -- another bug (since 5.2) | ||
346 | -- corrupted binary dump: list of upvalue names is larger than number | ||
347 | -- of upvalues, overflowing the array of upvalues. | ||
348 | local code = | ||
349 | "\x1b\x4c\x75\x61\x54\x00\x19\x93\x0d\x0a\x1a\x0a\x04\x08\x08\x78\x56\z | ||
350 | \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x77\x40\x00\x86\x40\z | ||
351 | \x74\x65\x6d\x70\x81\x81\x01\x00\x02\x82\x48\x00\x02\x00\xc7\x00\x01\z | ||
352 | \x00\x80\x80\x80\x82\x00\x00\x80\x81\x82\x78\x80\x82\x81\x86\x40\x74\z | ||
353 | \x65\x6d\x70" | ||
354 | |||
355 | assert(load(code)) -- segfaults in previous versions | ||
356 | end | ||
357 | |||
358 | |||
359 | x = string.dump(load("x = 1; return x")) | 345 | x = string.dump(load("x = 1; return x")) |
360 | a = assert(load(read1(x), nil, "b")) | 346 | a = assert(load(read1(x), nil, "b")) |
361 | assert(a() == 1 and _G.x == 1) | 347 | assert(a() == 1 and _G.x == 1) |
diff --git a/testes/db.lua b/testes/db.lua index 02b96aca..d3758c41 100644 --- a/testes/db.lua +++ b/testes/db.lua | |||
@@ -345,7 +345,7 @@ function f(a,b) | |||
345 | local _, y = debug.getlocal(1, 2) | 345 | local _, y = debug.getlocal(1, 2) |
346 | assert(x == a and y == b) | 346 | assert(x == a and y == b) |
347 | assert(debug.setlocal(2, 3, "pera") == "AA".."AA") | 347 | assert(debug.setlocal(2, 3, "pera") == "AA".."AA") |
348 | assert(debug.setlocal(2, 4, "maçã") == "B") | 348 | assert(debug.setlocal(2, 4, "manga") == "B") |
349 | x = debug.getinfo(2) | 349 | x = debug.getinfo(2) |
350 | assert(x.func == g and x.what == "Lua" and x.name == 'g' and | 350 | assert(x.func == g and x.what == "Lua" and x.name == 'g' and |
351 | x.nups == 2 and string.find(x.source, "^@.*db%.lua$")) | 351 | x.nups == 2 and string.find(x.source, "^@.*db%.lua$")) |
@@ -373,9 +373,9 @@ function g (...) | |||
373 | local arg = {...} | 373 | local arg = {...} |
374 | do local a,b,c; a=math.sin(40); end | 374 | do local a,b,c; a=math.sin(40); end |
375 | local feijao | 375 | local feijao |
376 | local AAAA,B = "xuxu", "mamão" | 376 | local AAAA,B = "xuxu", "abacate" |
377 | f(AAAA,B) | 377 | f(AAAA,B) |
378 | assert(AAAA == "pera" and B == "maçã") | 378 | assert(AAAA == "pera" and B == "manga") |
379 | do | 379 | do |
380 | local B = 13 | 380 | local B = 13 |
381 | local x,y = debug.getlocal(1,5) | 381 | local x,y = debug.getlocal(1,5) |
@@ -928,7 +928,7 @@ do | |||
928 | local cl = countlines(rest) | 928 | local cl = countlines(rest) |
929 | -- at most 10 lines in first part, 11 in second, plus '...' | 929 | -- at most 10 lines in first part, 11 in second, plus '...' |
930 | assert(cl <= 10 + 11 + 1) | 930 | assert(cl <= 10 + 11 + 1) |
931 | local brk = string.find(rest, "%.%.%.") | 931 | local brk = string.find(rest, "%.%.%.\t%(skip") |
932 | if brk then -- does message have '...'? | 932 | if brk then -- does message have '...'? |
933 | local rest1 = string.sub(rest, 1, brk) | 933 | local rest1 = string.sub(rest, 1, brk) |
934 | local rest2 = string.sub(rest, brk, #rest) | 934 | local rest2 = string.sub(rest, brk, #rest) |
diff --git a/testes/errors.lua b/testes/errors.lua index bf6f389d..01cfe906 100644 --- a/testes/errors.lua +++ b/testes/errors.lua | |||
@@ -121,6 +121,9 @@ assert(not string.find(doit"aaa={13}; local bbbb=1; aaa[bbbb](3)", "'bbbb'")) | |||
121 | checkmessage("aaa={13}; local bbbb=1; aaa[bbbb](3)", "number") | 121 | checkmessage("aaa={13}; local bbbb=1; aaa[bbbb](3)", "number") |
122 | checkmessage("aaa=(1)..{}", "a table value") | 122 | checkmessage("aaa=(1)..{}", "a table value") |
123 | 123 | ||
124 | -- bug in 5.4.6 | ||
125 | checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") | ||
126 | |||
124 | _G.aaa, _G.bbbb = nil | 127 | _G.aaa, _G.bbbb = nil |
125 | 128 | ||
126 | -- calls | 129 | -- calls |
@@ -392,19 +395,19 @@ lineerror("a\n=\n-\n\nprint\n;", 3) | |||
392 | 395 | ||
393 | lineerror([[ | 396 | lineerror([[ |
394 | a | 397 | a |
395 | ( | 398 | ( -- << |
396 | 23) | 399 | 23) |
397 | ]], 1) | 400 | ]], 2) |
398 | 401 | ||
399 | lineerror([[ | 402 | lineerror([[ |
400 | local a = {x = 13} | 403 | local a = {x = 13} |
401 | a | 404 | a |
402 | . | 405 | . |
403 | x | 406 | x |
404 | ( | 407 | ( -- << |
405 | 23 | 408 | 23 |
406 | ) | 409 | ) |
407 | ]], 2) | 410 | ]], 5) |
408 | 411 | ||
409 | lineerror([[ | 412 | lineerror([[ |
410 | local a = {x = 13} | 413 | local a = {x = 13} |
diff --git a/testes/files.lua b/testes/files.lua index be00bf3f..1476006e 100644 --- a/testes/files.lua +++ b/testes/files.lua | |||
@@ -92,8 +92,8 @@ assert(io.output():seek("end") == string.len("alo joao")) | |||
92 | 92 | ||
93 | assert(io.output():seek("set") == 0) | 93 | assert(io.output():seek("set") == 0) |
94 | 94 | ||
95 | assert(io.write('"álo"', "{a}\n", "second line\n", "third line \n")) | 95 | assert(io.write('"alo"', "{a}\n", "second line\n", "third line \n")) |
96 | assert(io.write('çfourth_line')) | 96 | assert(io.write('Xfourth_line')) |
97 | io.output(io.stdout) | 97 | io.output(io.stdout) |
98 | collectgarbage() -- file should be closed by GC | 98 | collectgarbage() -- file should be closed by GC |
99 | assert(io.input() == io.stdin and rawequal(io.output(), io.stdout)) | 99 | assert(io.input() == io.stdin and rawequal(io.output(), io.stdout)) |
@@ -300,14 +300,14 @@ do -- test error returns | |||
300 | end | 300 | end |
301 | checkerr("invalid format", io.read, "x") | 301 | checkerr("invalid format", io.read, "x") |
302 | assert(io.read(0) == "") -- not eof | 302 | assert(io.read(0) == "") -- not eof |
303 | assert(io.read(5, 'l') == '"álo"') | 303 | assert(io.read(5, 'l') == '"alo"') |
304 | assert(io.read(0) == "") | 304 | assert(io.read(0) == "") |
305 | assert(io.read() == "second line") | 305 | assert(io.read() == "second line") |
306 | local x = io.input():seek() | 306 | local x = io.input():seek() |
307 | assert(io.read() == "third line ") | 307 | assert(io.read() == "third line ") |
308 | assert(io.input():seek("set", x)) | 308 | assert(io.input():seek("set", x)) |
309 | assert(io.read('L') == "third line \n") | 309 | assert(io.read('L') == "third line \n") |
310 | assert(io.read(1) == "ç") | 310 | assert(io.read(1) == "X") |
311 | assert(io.read(string.len"fourth_line") == "fourth_line") | 311 | assert(io.read(string.len"fourth_line") == "fourth_line") |
312 | assert(io.input():seek("cur", -string.len"fourth_line")) | 312 | assert(io.input():seek("cur", -string.len"fourth_line")) |
313 | assert(io.read() == "fourth_line") | 313 | assert(io.read() == "fourth_line") |
diff --git a/testes/main.lua b/testes/main.lua index f59badcf..11b14b44 100644 --- a/testes/main.lua +++ b/testes/main.lua | |||
@@ -27,17 +27,19 @@ do | |||
27 | end | 27 | end |
28 | print("progname: "..progname) | 28 | print("progname: "..progname) |
29 | 29 | ||
30 | local prepfile = function (s, p) | 30 | |
31 | p = p or prog | 31 | local prepfile = function (s, mod, p) |
32 | io.output(p) | 32 | mod = mod and "wb" or "w" -- mod true means binary files |
33 | io.write(s) | 33 | p = p or prog -- file to write the program |
34 | assert(io.close()) | 34 | local f = io.open(p, mod) |
35 | f:write(s) | ||
36 | assert(f:close()) | ||
35 | end | 37 | end |
36 | 38 | ||
37 | local function getoutput () | 39 | local function getoutput () |
38 | io.input(out) | 40 | local f = io.open(out) |
39 | local t = io.read("a") | 41 | local t = f:read("a") |
40 | io.input():close() | 42 | f:close() |
41 | assert(os.remove(out)) | 43 | assert(os.remove(out)) |
42 | return t | 44 | return t |
43 | end | 45 | end |
@@ -65,10 +67,11 @@ local function RUN (p, ...) | |||
65 | assert(os.execute(s)) | 67 | assert(os.execute(s)) |
66 | end | 68 | end |
67 | 69 | ||
70 | |||
68 | local function NoRun (msg, p, ...) | 71 | local function NoRun (msg, p, ...) |
69 | p = string.gsub(p, "lua", '"'..progname..'"', 1) | 72 | p = string.gsub(p, "lua", '"'..progname..'"', 1) |
70 | local s = string.format(p, ...) | 73 | local s = string.format(p, ...) |
71 | s = string.format("%s 2> %s", s, out) -- will send error to 'out' | 74 | s = string.format("%s >%s 2>&1", s, out) -- send output and error to 'out' |
72 | assert(not os.execute(s)) | 75 | assert(not os.execute(s)) |
73 | assert(string.find(getoutput(), msg, 1, true)) -- check error message | 76 | assert(string.find(getoutput(), msg, 1, true)) -- check error message |
74 | end | 77 | end |
@@ -108,17 +111,17 @@ RUN('lua %s > %s', prog, out) | |||
108 | checkout("3\n") | 111 | checkout("3\n") |
109 | 112 | ||
110 | -- bad BOMs | 113 | -- bad BOMs |
111 | prepfile("\xEF") | 114 | prepfile("\xEF", true) |
112 | NoRun("unexpected symbol", 'lua %s > %s', prog, out) | 115 | NoRun("unexpected symbol", 'lua %s', prog) |
113 | 116 | ||
114 | prepfile("\xEF\xBB") | 117 | prepfile("\xEF\xBB", true) |
115 | NoRun("unexpected symbol", 'lua %s > %s', prog, out) | 118 | NoRun("unexpected symbol", 'lua %s', prog) |
116 | 119 | ||
117 | prepfile("\xEFprint(3)") | 120 | prepfile("\xEFprint(3)", true) |
118 | NoRun("unexpected symbol", 'lua %s > %s', prog, out) | 121 | NoRun("unexpected symbol", 'lua %s', prog) |
119 | 122 | ||
120 | prepfile("\xEF\xBBprint(3)") | 123 | prepfile("\xEF\xBBprint(3)", true) |
121 | NoRun("unexpected symbol", 'lua %s > %s', prog, out) | 124 | NoRun("unexpected symbol", 'lua %s', prog) |
122 | 125 | ||
123 | 126 | ||
124 | -- test option '-' | 127 | -- test option '-' |
@@ -213,7 +216,7 @@ convert("a;b;;c") | |||
213 | 216 | ||
214 | -- test -l over multiple libraries | 217 | -- test -l over multiple libraries |
215 | prepfile("print(1); a=2; return {x=15}") | 218 | prepfile("print(1); a=2; return {x=15}") |
216 | prepfile(("print(a); print(_G['%s'].x)"):format(prog), otherprog) | 219 | prepfile(("print(a); print(_G['%s'].x)"):format(prog), false, otherprog) |
217 | RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out) | 220 | RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out) |
218 | checkout("1\n2\n15\n2\n15\n") | 221 | checkout("1\n2\n15\n2\n15\n") |
219 | 222 | ||
@@ -222,6 +225,13 @@ prepfile("print(str.upper'alo alo', m.max(10, 20))") | |||
222 | RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out) | 225 | RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out) |
223 | checkout("0.0\nALO ALO\t20\n") | 226 | checkout("0.0\nALO ALO\t20\n") |
224 | 227 | ||
228 | |||
229 | -- test module names with version sufix ("libs/lib2-v2") | ||
230 | RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s", | ||
231 | out) | ||
232 | checkout("true\n") | ||
233 | |||
234 | |||
225 | -- test 'arg' table | 235 | -- test 'arg' table |
226 | local a = [[ | 236 | local a = [[ |
227 | assert(#arg == 3 and arg[1] == 'a' and | 237 | assert(#arg == 3 and arg[1] == 'a' and |
@@ -237,7 +247,7 @@ RUN('lua "-e " -- %s a b c', prog) -- "-e " runs an empty command | |||
237 | 247 | ||
238 | -- test 'arg' availability in libraries | 248 | -- test 'arg' availability in libraries |
239 | prepfile"assert(arg)" | 249 | prepfile"assert(arg)" |
240 | prepfile("assert(arg)", otherprog) | 250 | prepfile("assert(arg)", false, otherprog) |
241 | RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) | 251 | RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) |
242 | 252 | ||
243 | -- test messing up the 'arg' table | 253 | -- test messing up the 'arg' table |
@@ -413,7 +423,7 @@ prepfile[[#comment in 1st line without \n at the end]] | |||
413 | RUN('lua %s', prog) | 423 | RUN('lua %s', prog) |
414 | 424 | ||
415 | -- first-line comment with binary file | 425 | -- first-line comment with binary file |
416 | prepfile("#comment\n" .. string.dump(load("print(3)"))) | 426 | prepfile("#comment\n" .. string.dump(load("print(3)")), true) |
417 | RUN('lua %s > %s', prog, out) | 427 | RUN('lua %s > %s', prog, out) |
418 | checkout('3\n') | 428 | checkout('3\n') |
419 | 429 | ||
diff --git a/testes/pm.lua b/testes/pm.lua index 795596d4..44454dff 100644 --- a/testes/pm.lua +++ b/testes/pm.lua | |||
@@ -1,6 +1,9 @@ | |||
1 | -- $Id: testes/pm.lua $ | 1 | -- $Id: testes/pm.lua $ |
2 | -- See Copyright Notice in file all.lua | 2 | -- See Copyright Notice in file all.lua |
3 | 3 | ||
4 | -- UTF-8 file | ||
5 | |||
6 | |||
4 | print('testing pattern matching') | 7 | print('testing pattern matching') |
5 | 8 | ||
6 | local function checkerror (msg, f, ...) | 9 | local function checkerror (msg, f, ...) |
@@ -50,6 +53,19 @@ assert(f('aLo_ALO', '%a*') == 'aLo') | |||
50 | 53 | ||
51 | assert(f(" \n\r*&\n\r xuxu \n\n", "%g%g%g+") == "xuxu") | 54 | assert(f(" \n\r*&\n\r xuxu \n\n", "%g%g%g+") == "xuxu") |
52 | 55 | ||
56 | |||
57 | -- Adapt a pattern to UTF-8 | ||
58 | local function PU (p) | ||
59 | -- break '?' into each individual byte of a character | ||
60 | p = string.gsub(p, "(" .. utf8.charpattern .. ")%?", function (c) | ||
61 | return string.gsub(c, ".", "%0?") | ||
62 | end) | ||
63 | -- change '.' to utf-8 character patterns | ||
64 | p = string.gsub(p, "%.", utf8.charpattern) | ||
65 | return p | ||
66 | end | ||
67 | |||
68 | |||
53 | assert(f('aaab', 'a*') == 'aaa'); | 69 | assert(f('aaab', 'a*') == 'aaa'); |
54 | assert(f('aaa', '^.*$') == 'aaa'); | 70 | assert(f('aaa', '^.*$') == 'aaa'); |
55 | assert(f('aaa', 'b*') == ''); | 71 | assert(f('aaa', 'b*') == ''); |
@@ -73,16 +89,16 @@ assert(f('aaa', '^.-$') == 'aaa') | |||
73 | assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab') | 89 | assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab') |
74 | assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab') | 90 | assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab') |
75 | assert(f('alo xo', '.o$') == 'xo') | 91 | assert(f('alo xo', '.o$') == 'xo') |
76 | assert(f(' \n isto é assim', '%S%S*') == 'isto') | 92 | assert(f(' \n isto é assim', '%S%S*') == 'isto') |
77 | assert(f(' \n isto é assim', '%S*$') == 'assim') | 93 | assert(f(' \n isto é assim', '%S*$') == 'assim') |
78 | assert(f(' \n isto é assim', '[a-z]*$') == 'assim') | 94 | assert(f(' \n isto é assim', '[a-z]*$') == 'assim') |
79 | assert(f('um caracter ? extra', '[^%sa-z]') == '?') | 95 | assert(f('um caracter ? extra', '[^%sa-z]') == '?') |
80 | assert(f('', 'a?') == '') | 96 | assert(f('', 'a?') == '') |
81 | assert(f('á', 'á?') == 'á') | 97 | assert(f('á', PU'á?') == 'á') |
82 | assert(f('ábl', 'á?b?l?') == 'ábl') | 98 | assert(f('ábl', PU'á?b?l?') == 'ábl') |
83 | assert(f(' ábl', 'á?b?l?') == '') | 99 | assert(f(' ábl', PU'á?b?l?') == '') |
84 | assert(f('aa', '^aa?a?a') == 'aa') | 100 | assert(f('aa', '^aa?a?a') == 'aa') |
85 | assert(f(']]]áb', '[^]]') == 'á') | 101 | assert(f(']]]áb', '[^]]+') == 'áb') |
86 | assert(f("0alo alo", "%x*") == "0a") | 102 | assert(f("0alo alo", "%x*") == "0a") |
87 | assert(f("alo alo", "%C+") == "alo alo") | 103 | assert(f("alo alo", "%C+") == "alo alo") |
88 | print('+') | 104 | print('+') |
@@ -136,28 +152,28 @@ assert(string.match("alo xyzK", "(%w+)K") == "xyz") | |||
136 | assert(string.match("254 K", "(%d*)K") == "") | 152 | assert(string.match("254 K", "(%d*)K") == "") |
137 | assert(string.match("alo ", "(%w*)$") == "") | 153 | assert(string.match("alo ", "(%w*)$") == "") |
138 | assert(not string.match("alo ", "(%w+)$")) | 154 | assert(not string.match("alo ", "(%w+)$")) |
139 | assert(string.find("(álo)", "%(á") == 1) | 155 | assert(string.find("(álo)", "%(á") == 1) |
140 | local a, b, c, d, e = string.match("âlo alo", "^(((.).).* (%w*))$") | 156 | local a, b, c, d, e = string.match("âlo alo", PU"^(((.).). (%w*))$") |
141 | assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil) | 157 | assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil) |
142 | a, b, c, d = string.match('0123456789', '(.+(.?)())') | 158 | a, b, c, d = string.match('0123456789', '(.+(.?)())') |
143 | assert(a == '0123456789' and b == '' and c == 11 and d == nil) | 159 | assert(a == '0123456789' and b == '' and c == 11 and d == nil) |
144 | print('+') | 160 | print('+') |
145 | 161 | ||
146 | assert(string.gsub('ülo ülo', 'ü', 'x') == 'xlo xlo') | 162 | assert(string.gsub('ülo ülo', 'ü', 'x') == 'xlo xlo') |
147 | assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim | 163 | assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim |
148 | assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim | 164 | assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim |
149 | assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ') | 165 | assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ') |
150 | local t = "abç d" | 166 | local t = "abç d" |
151 | a, b = string.gsub(t, '(.)', '%1@') | 167 | a, b = string.gsub(t, PU'(.)', '%1@') |
152 | assert('@'..a == string.gsub(t, '', '@') and b == 5) | 168 | assert(a == "a@b@ç@ @d@" and b == 5) |
153 | a, b = string.gsub('abçd', '(.)', '%0@', 2) | 169 | a, b = string.gsub('abçd', PU'(.)', '%0@', 2) |
154 | assert(a == 'a@b@çd' and b == 2) | 170 | assert(a == 'a@b@çd' and b == 2) |
155 | assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o') | 171 | assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o') |
156 | assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") == | 172 | assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") == |
157 | "xyz=abc-abc=xyz") | 173 | "xyz=abc-abc=xyz") |
158 | assert(string.gsub("abc", "%w", "%1%0") == "aabbcc") | 174 | assert(string.gsub("abc", "%w", "%1%0") == "aabbcc") |
159 | assert(string.gsub("abc", "%w+", "%0%1") == "abcabc") | 175 | assert(string.gsub("abc", "%w+", "%0%1") == "abcabc") |
160 | assert(string.gsub('áéí', '$', '\0óú') == 'áéí\0óú') | 176 | assert(string.gsub('áéÃ', '$', '\0óú') == 'áéÃ\0óú') |
161 | assert(string.gsub('', '^', 'r') == 'r') | 177 | assert(string.gsub('', '^', 'r') == 'r') |
162 | assert(string.gsub('', '$', 'r') == 'r') | 178 | assert(string.gsub('', '$', 'r') == 'r') |
163 | print('+') | 179 | print('+') |
@@ -188,8 +204,8 @@ do | |||
188 | end | 204 | end |
189 | 205 | ||
190 | function f(a,b) return string.gsub(a,'.',b) end | 206 | function f(a,b) return string.gsub(a,'.',b) end |
191 | assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|", "|([^|]*)|([^|]*)|", f) == | 207 | assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|", "|([^|]*)|([^|]*)|", f) == |
192 | "trocar tudo em bbbbb é alalalalalal") | 208 | "trocar tudo em bbbbb é alalalalalal") |
193 | 209 | ||
194 | local function dostring (s) return load(s, "")() or "" end | 210 | local function dostring (s) return load(s, "")() or "" end |
195 | assert(string.gsub("alo $a='x'$ novamente $return a$", | 211 | assert(string.gsub("alo $a='x'$ novamente $return a$", |
diff --git a/testes/sort.lua b/testes/sort.lua index 52919b8c..40bb2d8a 100644 --- a/testes/sort.lua +++ b/testes/sort.lua | |||
@@ -289,7 +289,7 @@ timesort(a, limit, function(x,y) return nil end, "equal") | |||
289 | 289 | ||
290 | for i,v in pairs(a) do assert(v == false) end | 290 | for i,v in pairs(a) do assert(v == false) end |
291 | 291 | ||
292 | AA = {"álo", "\0first :-)", "alo", "then this one", "45", "and a new"} | 292 | AA = {"\xE1lo", "\0first :-)", "alo", "then this one", "45", "and a new"} |
293 | table.sort(AA) | 293 | table.sort(AA) |
294 | check(AA) | 294 | check(AA) |
295 | 295 | ||
diff --git a/testes/strings.lua b/testes/strings.lua index b033c6ab..90983edd 100644 --- a/testes/strings.lua +++ b/testes/strings.lua | |||
@@ -1,6 +1,9 @@ | |||
1 | -- $Id: testes/strings.lua $ | 1 | -- $Id: testes/strings.lua $ |
2 | -- See Copyright Notice in file all.lua | 2 | -- See Copyright Notice in file all.lua |
3 | 3 | ||
4 | -- ISO Latin encoding | ||
5 | |||
6 | |||
4 | print('testing strings and string library') | 7 | print('testing strings and string library') |
5 | 8 | ||
6 | local maxi <const> = math.maxinteger | 9 | local maxi <const> = math.maxinteger |
diff --git a/testes/utf8.lua b/testes/utf8.lua index c5a9dd3f..efadbd5c 100644 --- a/testes/utf8.lua +++ b/testes/utf8.lua | |||
@@ -1,6 +1,8 @@ | |||
1 | -- $Id: testes/utf8.lua $ | 1 | -- $Id: testes/utf8.lua $ |
2 | -- See Copyright Notice in file all.lua | 2 | -- See Copyright Notice in file all.lua |
3 | 3 | ||
4 | -- UTF-8 file | ||
5 | |||
4 | print "testing UTF-8 library" | 6 | print "testing UTF-8 library" |
5 | 7 | ||
6 | local utf8 = require'utf8' | 8 | local utf8 = require'utf8' |