diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-11-03 15:39:14 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2023-11-03 15:39:14 -0300 |
| commit | fa075b79530af1cbc977349f2e467d69ce01202c (patch) | |
| tree | 300e10cd086a9812331b954d46552dbf420b0a8a | |
| parent | 08a077d673b25cf1fbfe21794f240f4ff4999667 (diff) | |
| parent | 7923dbbf72da303ca1cca17efd24725668992f15 (diff) | |
| download | lua-fa075b79530af1cbc977349f2e467d69ce01202c.tar.gz lua-fa075b79530af1cbc977349f2e467d69ce01202c.tar.bz2 lua-fa075b79530af1cbc977349f2e467d69ce01202c.zip | |
Merge branch 'master' into newarray
| -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' |
