aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lapi.c4
-rw-r--r--lcode.c29
-rw-r--r--lcode.h3
-rw-r--r--ldebug.c177
-rw-r--r--ldebug.h1
-rw-r--r--ldo.c6
-rw-r--r--ldo.h1
-rw-r--r--lgc.c20
-rw-r--r--lmathlib.c31
-rw-r--r--loadlib.c9
-rw-r--r--lobject.c2
-rw-r--r--lobject.h18
-rw-r--r--lopcodes.h8
-rw-r--r--lparser.c12
-rw-r--r--lstate.c6
-rw-r--r--lstate.h3
-rw-r--r--lstring.c11
-rw-r--r--ltable.c5
-rw-r--r--ltable.h2
-rw-r--r--ltm.h5
-rw-r--r--lua.c12
-rw-r--r--lua.h32
-rw-r--r--luaconf.h9
-rw-r--r--lundump.c4
-rw-r--r--lundump.h3
-rw-r--r--lvm.c76
-rw-r--r--manual/manual.of4
-rw-r--r--testes/calls.lua14
-rw-r--r--testes/db.lua8
-rw-r--r--testes/errors.lua11
-rw-r--r--testes/files.lua8
-rw-r--r--testes/main.lua50
-rw-r--r--testes/pm.lua56
-rw-r--r--testes/sort.lua2
-rw-r--r--testes/strings.lua3
-rw-r--r--testes/utf8.lua2
36 files changed, 369 insertions, 278 deletions
diff --git a/lapi.c b/lapi.c
index 99c8473e..76c9d31b 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
diff --git a/lcode.c b/lcode.c
index 25623df7..29db5002 100644
--- a/lcode.c
+++ b/lcode.c
@@ -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*/
418int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) { 418static 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
672void luaK_int (FuncState *fs, int reg, lua_Integer i) { 672void 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) {
680static void luaK_float (FuncState *fs, int reg, lua_Number f) { 680static 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*/
1028int luaK_exp2RK (FuncState *fs, expdesc *e) { 1028static 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
1038static void codeABRK (FuncState *fs, OpCode o, int a, int b, 1038static 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*/
1220static int isKstr (FuncState *fs, expdesc *e) { 1220static 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*/
1228int luaK_isKint (expdesc *e) { 1228static 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*/
1237static int isCint (expdesc *e) { 1237static 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*/
1246static int isSCint (expdesc *e) { 1246static 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*/
1460static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, 1461static 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 }
diff --git a/lcode.h b/lcode.h
index 32658244..0b971fc4 100644
--- a/lcode.h
+++ b/lcode.h
@@ -61,10 +61,8 @@ typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
61 61
62LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); 62LUAI_FUNC int luaK_code (FuncState *fs, Instruction i);
63LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 63LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
64LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx);
65LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, 64LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A,
66 int B, int C, int k); 65 int B, int C, int k);
67LUAI_FUNC int luaK_isKint (expdesc *e);
68LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); 66LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v);
69LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 67LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
70LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 68LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
@@ -76,7 +74,6 @@ LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
76LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 74LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
77LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 75LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
78LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 76LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
79LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
80LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 77LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
81LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 78LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
82LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 79LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
diff --git a/ldebug.c b/ldebug.c
index 28b1caab..b1f16ac9 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -417,40 +417,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
417** ======================================================= 417** =======================================================
418*/ 418*/
419 419
420static 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*/
427static 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*/
436static 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*/
446static 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
455static int filterpc (int pc, int jmptarget) { 421static 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*/
515static const char *gxf (const Proto *p, int pc, Instruction i, int isup) { 480static 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
526static const char *getobjname (const Proto *p, int lastpc, int reg, 493static 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*/
527static 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*/
537static 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*/
550static 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*/
564static 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*/
891int 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
diff --git a/ldebug.h b/ldebug.h
index 2c3074c6..2bfce3cb 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -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);
59LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 59LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
60LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); 60LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc);
61LUAI_FUNC int luaG_tracecall (lua_State *L);
61 62
62 63
63#endif 64#endif
diff --git a/ldo.c b/ldo.c
index 2a0017ca..bd8d965f 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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*/
412StkId luaD_tryfuncTM (lua_State *L, StkId func) { 412static 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 }
diff --git a/ldo.h b/ldo.h
index 1aa446ad..56008ab3 100644
--- a/ldo.h
+++ b/ldo.h
@@ -71,7 +71,6 @@ LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
71LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); 71LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
72LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 72LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
73LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 73LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
74LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func);
75LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); 74LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status);
76LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 75LUAI_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);
diff --git a/lgc.c b/lgc.c
index 0f423282..f291cd17 100644
--- a/lgc.c
+++ b/lgc.c
@@ -553,10 +553,12 @@ static void traversestrongtable (global_State *g, Table *h) {
553static lu_mem traversetable (global_State *g, Table *h) { 553static 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));
diff --git a/lmathlib.c b/lmathlib.c
index d0b1e1e5..f140d623 100644
--- a/lmathlib.c
+++ b/lmathlib.c
@@ -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
337static lua_Number I2d (Rand64 x) { 351static 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)))
diff --git a/loadlib.c b/loadlib.c
index d792dffa..6d289fce 100644
--- a/loadlib.c
+++ b/loadlib.c
@@ -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
diff --git a/lobject.c b/lobject.c
index f73ffc6d..9cfa5227 100644
--- a/lobject.c
+++ b/lobject.c
@@ -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
diff --git a/lobject.h b/lobject.h
index 25e268be..342197c4 100644
--- a/lobject.h
+++ b/lobject.h
@@ -388,7 +388,7 @@ typedef struct GCObject {
388typedef struct TString { 388typedef 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
diff --git a/lopcodes.h b/lopcodes.h
index 4c551453..46911cac 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -210,15 +210,15 @@ OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */
210OP_GETUPVAL,/* A B R[A] := UpValue[B] */ 210OP_GETUPVAL,/* A B R[A] := UpValue[B] */
211OP_SETUPVAL,/* A B UpValue[B] := R[A] */ 211OP_SETUPVAL,/* A B UpValue[B] := R[A] */
212 212
213OP_GETTABUP,/* A B C R[A] := UpValue[B][K[C]:string] */ 213OP_GETTABUP,/* A B C R[A] := UpValue[B][K[C]:shortstring] */
214OP_GETTABLE,/* A B C R[A] := R[B][R[C]] */ 214OP_GETTABLE,/* A B C R[A] := R[B][R[C]] */
215OP_GETI,/* A B C R[A] := R[B][C] */ 215OP_GETI,/* A B C R[A] := R[B][C] */
216OP_GETFIELD,/* A B C R[A] := R[B][K[C]:string] */ 216OP_GETFIELD,/* A B C R[A] := R[B][K[C]:shortstring] */
217 217
218OP_SETTABUP,/* A B C UpValue[A][K[B]:string] := RK(C) */ 218OP_SETTABUP,/* A B C UpValue[A][K[B]:shortstring] := RK(C) */
219OP_SETTABLE,/* A B C R[A][R[B]] := RK(C) */ 219OP_SETTABLE,/* A B C R[A][R[B]] := RK(C) */
220OP_SETI,/* A B C R[A][B] := RK(C) */ 220OP_SETI,/* A B C R[A][B] := RK(C) */
221OP_SETFIELD,/* A B C R[A][K[B]:string] := RK(C) */ 221OP_SETFIELD,/* A B C R[A][K[B]:shortstring] := RK(C) */
222 222
223OP_NEWTABLE,/* A B C k R[A] := {} */ 223OP_NEWTABLE,/* A B C k R[A] := {} */
224 224
diff --git a/lparser.c b/lparser.c
index b745f236..2b888c7c 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1022,10 +1022,11 @@ static int explist (LexState *ls, expdesc *v) {
1022} 1022}
1023 1023
1024 1024
1025static void funcargs (LexState *ls, expdesc *f, int line) { 1025static 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;
diff --git a/lstate.c b/lstate.c
index d10cd88c..390e9c1a 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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*/
122void luaE_freeCI (lua_State *L) { 122static 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) {
436void luaE_warnerror (lua_State *L, const char *where) { 436void 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);
diff --git a/lstate.h b/lstate.h
index 8bf6600e..007704c8 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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 {
396LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 396LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
397LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 397LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
398LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 398LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
399LUAI_FUNC void luaE_freeCI (lua_State *L);
400LUAI_FUNC void luaE_shrinkCI (lua_State *L); 399LUAI_FUNC void luaE_shrinkCI (lua_State *L);
401LUAI_FUNC void luaE_checkcstack (lua_State *L); 400LUAI_FUNC void luaE_checkcstack (lua_State *L);
402LUAI_FUNC void luaE_incCstack (lua_State *L); 401LUAI_FUNC void luaE_incCstack (lua_State *L);
diff --git a/lstring.c b/lstring.c
index 13dcaf42..e921dd0f 100644
--- a/lstring.c
+++ b/lstring.c
@@ -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) {
157TString *luaS_createlngstrobj (lua_State *L, size_t l) { 157TString *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}
diff --git a/ltable.c b/ltable.c
index b7362a36..8c2bc3b2 100644
--- a/ltable.c
+++ b/ltable.c
@@ -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*/
739void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) { 739static 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)))
diff --git a/ltable.h b/ltable.h
index b401aba1..1f6d6aa4 100644
--- a/ltable.h
+++ b/ltable.h
@@ -130,8 +130,6 @@ LUAI_FUNC int luaH_pset (Table *t, const TValue *key, TValue *val);
130LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 130LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
131 TValue *value); 131 TValue *value);
132LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key); 132LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key);
133LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key,
134 TValue *value);
135LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 133LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key,
136 TValue *value); 134 TValue *value);
137LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 135LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key,
diff --git a/ltm.h b/ltm.h
index c309e2ae..73b833c6 100644
--- a/ltm.h
+++ b/ltm.h
@@ -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
98LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, 97LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams,
99 CallInfo *ci, const Proto *p); 98 struct CallInfo *ci, const Proto *p);
100LUAI_FUNC void luaT_getvarargs (lua_State *L, CallInfo *ci, 99LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci,
101 StkId where, int wanted); 100 StkId where, int wanted);
102 101
103 102
diff --git a/lua.c b/lua.c
index 0ff88454..3af5ce6a 100644
--- a/lua.c
+++ b/lua.c
@@ -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*/
214static int dolibrary (lua_State *L, char *globname) { 216static 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
diff --git a/lua.h b/lua.h
index fd16cf80..040cc8e4 100644
--- a/lua.h
+++ b/lua.h
@@ -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*
diff --git a/luaconf.h b/luaconf.h
index 137103ed..acebe29c 100644
--- a/luaconf.h
+++ b/luaconf.h
@@ -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
diff --git a/lundump.c b/lundump.c
index 02aed64f..e8d92a85 100644
--- a/lundump.c
+++ b/lundump.c
@@ -81,7 +81,7 @@ static size_t loadUnsigned (LoadState *S, size_t limit) {
81 81
82 82
83static size_t loadSize (LoadState *S) { 83static 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);
diff --git a/lundump.h b/lundump.h
index f3748a99..bc71ced8 100644
--- a/lundump.h
+++ b/lundump.h
@@ -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
diff --git a/lvm.c b/lvm.c
index 927272df..9b71ff31 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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*/
365static int l_strcmp (const TString *ls, const TString *rs) { 368static 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) {
614static void copy2buff (StkId top, int n, char *buff) { 618static 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.
9026In particular, 9026In particular,
9027the values of @Lid{package.path} and @Lid{package.cpath} 9027the values of @Lid{package.path} and @Lid{package.cpath}
9028are set with the default paths defined in @id{luaconf.h}. 9028are set with the default paths defined in @id{luaconf.h}.
9029To signal to the libraries that this option is on,
9030the stand-alone interpreter sets the field
9031@idx{"LUA_NOENV"} in the registry to a true value.
9032Other libraries may consult this field for the same purpose.
9029 9033
9030The options @T{-e}, @T{-l}, and @T{-W} are handled in 9034The options @T{-e}, @T{-l}, and @T{-W} are handled in
9031the order they appear. 9035the 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)
342end 342end
343 343
344 344
345do -- 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
356end
357
358
359x = string.dump(load("x = 1; return x")) 345x = string.dump(load("x = 1; return x"))
360a = assert(load(read1(x), nil, "b")) 346a = assert(load(read1(x), nil, "b"))
361assert(a() == 1 and _G.x == 1) 347assert(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'"))
121checkmessage("aaa={13}; local bbbb=1; aaa[bbbb](3)", "number") 121checkmessage("aaa={13}; local bbbb=1; aaa[bbbb](3)", "number")
122checkmessage("aaa=(1)..{}", "a table value") 122checkmessage("aaa=(1)..{}", "a table value")
123 123
124-- bug in 5.4.6
125checkmessage("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
393lineerror([[ 396lineerror([[
394a 397a
395( 398( -- <<
39623) 39923)
397]], 1) 400]], 2)
398 401
399lineerror([[ 402lineerror([[
400local a = {x = 13} 403local a = {x = 13}
401a 404a
402. 405.
403x 406x
404( 407( -- <<
40523 40823
406) 409)
407]], 2) 410]], 5)
408 411
409lineerror([[ 412lineerror([[
410local a = {x = 13} 413local 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
93assert(io.output():seek("set") == 0) 93assert(io.output():seek("set") == 0)
94 94
95assert(io.write('"álo"', "{a}\n", "second line\n", "third line \n")) 95assert(io.write('"alo"', "{a}\n", "second line\n", "third line \n"))
96assert(io.write('çfourth_line')) 96assert(io.write('Xfourth_line'))
97io.output(io.stdout) 97io.output(io.stdout)
98collectgarbage() -- file should be closed by GC 98collectgarbage() -- file should be closed by GC
99assert(io.input() == io.stdin and rawequal(io.output(), io.stdout)) 99assert(io.input() == io.stdin and rawequal(io.output(), io.stdout))
@@ -300,14 +300,14 @@ do -- test error returns
300end 300end
301checkerr("invalid format", io.read, "x") 301checkerr("invalid format", io.read, "x")
302assert(io.read(0) == "") -- not eof 302assert(io.read(0) == "") -- not eof
303assert(io.read(5, 'l') == '"álo"') 303assert(io.read(5, 'l') == '"alo"')
304assert(io.read(0) == "") 304assert(io.read(0) == "")
305assert(io.read() == "second line") 305assert(io.read() == "second line")
306local x = io.input():seek() 306local x = io.input():seek()
307assert(io.read() == "third line ") 307assert(io.read() == "third line ")
308assert(io.input():seek("set", x)) 308assert(io.input():seek("set", x))
309assert(io.read('L') == "third line \n") 309assert(io.read('L') == "third line \n")
310assert(io.read(1) == "ç") 310assert(io.read(1) == "X")
311assert(io.read(string.len"fourth_line") == "fourth_line") 311assert(io.read(string.len"fourth_line") == "fourth_line")
312assert(io.input():seek("cur", -string.len"fourth_line")) 312assert(io.input():seek("cur", -string.len"fourth_line"))
313assert(io.read() == "fourth_line") 313assert(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
27end 27end
28print("progname: "..progname) 28print("progname: "..progname)
29 29
30local prepfile = function (s, p) 30
31 p = p or prog 31local 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())
35end 37end
36 38
37local function getoutput () 39local 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
43end 45end
@@ -65,10 +67,11 @@ local function RUN (p, ...)
65 assert(os.execute(s)) 67 assert(os.execute(s))
66end 68end
67 69
70
68local function NoRun (msg, p, ...) 71local 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
74end 77end
@@ -108,17 +111,17 @@ RUN('lua %s > %s', prog, out)
108checkout("3\n") 111checkout("3\n")
109 112
110-- bad BOMs 113-- bad BOMs
111prepfile("\xEF") 114prepfile("\xEF", true)
112NoRun("unexpected symbol", 'lua %s > %s', prog, out) 115NoRun("unexpected symbol", 'lua %s', prog)
113 116
114prepfile("\xEF\xBB") 117prepfile("\xEF\xBB", true)
115NoRun("unexpected symbol", 'lua %s > %s', prog, out) 118NoRun("unexpected symbol", 'lua %s', prog)
116 119
117prepfile("\xEFprint(3)") 120prepfile("\xEFprint(3)", true)
118NoRun("unexpected symbol", 'lua %s > %s', prog, out) 121NoRun("unexpected symbol", 'lua %s', prog)
119 122
120prepfile("\xEF\xBBprint(3)") 123prepfile("\xEF\xBBprint(3)", true)
121NoRun("unexpected symbol", 'lua %s > %s', prog, out) 124NoRun("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
215prepfile("print(1); a=2; return {x=15}") 218prepfile("print(1); a=2; return {x=15}")
216prepfile(("print(a); print(_G['%s'].x)"):format(prog), otherprog) 219prepfile(("print(a); print(_G['%s'].x)"):format(prog), false, otherprog)
217RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out) 220RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out)
218checkout("1\n2\n15\n2\n15\n") 221checkout("1\n2\n15\n2\n15\n")
219 222
@@ -222,6 +225,13 @@ prepfile("print(str.upper'alo alo', m.max(10, 20))")
222RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out) 225RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out)
223checkout("0.0\nALO ALO\t20\n") 226checkout("0.0\nALO ALO\t20\n")
224 227
228
229-- test module names with version sufix ("libs/lib2-v2")
230RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s",
231 out)
232checkout("true\n")
233
234
225-- test 'arg' table 235-- test 'arg' table
226local a = [[ 236local 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
239prepfile"assert(arg)" 249prepfile"assert(arg)"
240prepfile("assert(arg)", otherprog) 250prepfile("assert(arg)", false, otherprog)
241RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) 251RUN('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]]
413RUN('lua %s', prog) 423RUN('lua %s', prog)
414 424
415-- first-line comment with binary file 425-- first-line comment with binary file
416prepfile("#comment\n" .. string.dump(load("print(3)"))) 426prepfile("#comment\n" .. string.dump(load("print(3)")), true)
417RUN('lua %s > %s', prog, out) 427RUN('lua %s > %s', prog, out)
418checkout('3\n') 428checkout('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
4print('testing pattern matching') 7print('testing pattern matching')
5 8
6local function checkerror (msg, f, ...) 9local function checkerror (msg, f, ...)
@@ -50,6 +53,19 @@ assert(f('aLo_ALO', '%a*') == 'aLo')
50 53
51assert(f(" \n\r*&\n\r xuxu \n\n", "%g%g%g+") == "xuxu") 54assert(f(" \n\r*&\n\r xuxu \n\n", "%g%g%g+") == "xuxu")
52 55
56
57-- Adapt a pattern to UTF-8
58local 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
66end
67
68
53assert(f('aaab', 'a*') == 'aaa'); 69assert(f('aaab', 'a*') == 'aaa');
54assert(f('aaa', '^.*$') == 'aaa'); 70assert(f('aaa', '^.*$') == 'aaa');
55assert(f('aaa', 'b*') == ''); 71assert(f('aaa', 'b*') == '');
@@ -73,16 +89,16 @@ assert(f('aaa', '^.-$') == 'aaa')
73assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab') 89assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab')
74assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab') 90assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab')
75assert(f('alo xo', '.o$') == 'xo') 91assert(f('alo xo', '.o$') == 'xo')
76assert(f(' \n isto é assim', '%S%S*') == 'isto') 92assert(f(' \n isto é assim', '%S%S*') == 'isto')
77assert(f(' \n isto é assim', '%S*$') == 'assim') 93assert(f(' \n isto é assim', '%S*$') == 'assim')
78assert(f(' \n isto é assim', '[a-z]*$') == 'assim') 94assert(f(' \n isto é assim', '[a-z]*$') == 'assim')
79assert(f('um caracter ? extra', '[^%sa-z]') == '?') 95assert(f('um caracter ? extra', '[^%sa-z]') == '?')
80assert(f('', 'a?') == '') 96assert(f('', 'a?') == '')
81assert(f('á', 'á?') == 'á') 97assert(f('á', PU'á?') == 'á')
82assert(f('ábl', 'á?b?l?') == 'ábl') 98assert(f('ábl', PU'á?b?l?') == 'ábl')
83assert(f(' ábl', 'á?b?l?') == '') 99assert(f(' ábl', PU'á?b?l?') == '')
84assert(f('aa', '^aa?a?a') == 'aa') 100assert(f('aa', '^aa?a?a') == 'aa')
85assert(f(']]]áb', '[^]]') == 'á') 101assert(f(']]]áb', '[^]]+') == 'áb')
86assert(f("0alo alo", "%x*") == "0a") 102assert(f("0alo alo", "%x*") == "0a")
87assert(f("alo alo", "%C+") == "alo alo") 103assert(f("alo alo", "%C+") == "alo alo")
88print('+') 104print('+')
@@ -136,28 +152,28 @@ assert(string.match("alo xyzK", "(%w+)K") == "xyz")
136assert(string.match("254 K", "(%d*)K") == "") 152assert(string.match("254 K", "(%d*)K") == "")
137assert(string.match("alo ", "(%w*)$") == "") 153assert(string.match("alo ", "(%w*)$") == "")
138assert(not string.match("alo ", "(%w+)$")) 154assert(not string.match("alo ", "(%w+)$"))
139assert(string.find("(álo)", "%(á") == 1) 155assert(string.find("(álo)", "%(á") == 1)
140local a, b, c, d, e = string.match("âlo alo", "^(((.).).* (%w*))$") 156local a, b, c, d, e = string.match("âlo alo", PU"^(((.).). (%w*))$")
141assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil) 157assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil)
142a, b, c, d = string.match('0123456789', '(.+(.?)())') 158a, b, c, d = string.match('0123456789', '(.+(.?)())')
143assert(a == '0123456789' and b == '' and c == 11 and d == nil) 159assert(a == '0123456789' and b == '' and c == 11 and d == nil)
144print('+') 160print('+')
145 161
146assert(string.gsub('ülo ülo', 'ü', 'x') == 'xlo xlo') 162assert(string.gsub('ülo ülo', 'ü', 'x') == 'xlo xlo')
147assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim 163assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim
148assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim 164assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim
149assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ') 165assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ')
150local t = "abç d" 166local t = "abç d"
151a, b = string.gsub(t, '(.)', '%1@') 167a, b = string.gsub(t, PU'(.)', '%1@')
152assert('@'..a == string.gsub(t, '', '@') and b == 5) 168assert(a == "a@b@ç@ @d@" and b == 5)
153a, b = string.gsub('abçd', '(.)', '%0@', 2) 169a, b = string.gsub('abçd', PU'(.)', '%0@', 2)
154assert(a == 'a@b@çd' and b == 2) 170assert(a == 'a@b@çd' and b == 2)
155assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o') 171assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o')
156assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") == 172assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") ==
157 "xyz=abc-abc=xyz") 173 "xyz=abc-abc=xyz")
158assert(string.gsub("abc", "%w", "%1%0") == "aabbcc") 174assert(string.gsub("abc", "%w", "%1%0") == "aabbcc")
159assert(string.gsub("abc", "%w+", "%0%1") == "abcabc") 175assert(string.gsub("abc", "%w+", "%0%1") == "abcabc")
160assert(string.gsub('áéí', '$', '\0óú') == 'áéí\0óú') 176assert(string.gsub('áéí', '$', '\0óú') == 'áéí\0óú')
161assert(string.gsub('', '^', 'r') == 'r') 177assert(string.gsub('', '^', 'r') == 'r')
162assert(string.gsub('', '$', 'r') == 'r') 178assert(string.gsub('', '$', 'r') == 'r')
163print('+') 179print('+')
@@ -188,8 +204,8 @@ do
188end 204end
189 205
190function f(a,b) return string.gsub(a,'.',b) end 206function f(a,b) return string.gsub(a,'.',b) end
191assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|", "|([^|]*)|([^|]*)|", f) == 207assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|", "|([^|]*)|([^|]*)|", f) ==
192 "trocar tudo em bbbbb é alalalalalal") 208 "trocar tudo em bbbbb é alalalalalal")
193 209
194local function dostring (s) return load(s, "")() or "" end 210local function dostring (s) return load(s, "")() or "" end
195assert(string.gsub("alo $a='x'$ novamente $return a$", 211assert(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
290for i,v in pairs(a) do assert(v == false) end 290for i,v in pairs(a) do assert(v == false) end
291 291
292AA = {"álo", "\0first :-)", "alo", "then this one", "45", "and a new"} 292AA = {"\xE1lo", "\0first :-)", "alo", "then this one", "45", "and a new"}
293table.sort(AA) 293table.sort(AA)
294check(AA) 294check(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
4print('testing strings and string library') 7print('testing strings and string library')
5 8
6local maxi <const> = math.maxinteger 9local 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
4print "testing UTF-8 library" 6print "testing UTF-8 library"
5 7
6local utf8 = require'utf8' 8local utf8 = require'utf8'