aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lcode.c104
-rw-r--r--lcode.h3
-rw-r--r--lcorolib.c4
-rw-r--r--ldebug.c31
-rw-r--r--ldo.c20
-rw-r--r--ldo.h1
-rw-r--r--ldump.c8
-rw-r--r--llex.c2
-rw-r--r--llimits.h2
-rw-r--r--loadlib.c9
-rw-r--r--lopcodes.h10
-rw-r--r--loslib.c21
-rw-r--r--lparser.c8
-rw-r--r--lstate.c6
-rw-r--r--lstate.h1
-rw-r--r--lstrlib.c2
-rw-r--r--ltable.c5
-rw-r--r--ltable.h2
-rw-r--r--ltests.c2
-rw-r--r--ltm.h5
-rw-r--r--lua.c14
-rw-r--r--lua.h38
-rw-r--r--luaconf.h9
-rw-r--r--lundump.c2
-rw-r--r--lvm.c50
-rw-r--r--makefile3
-rwxr-xr-xmanual/2html2
-rw-r--r--manual/manual.of52
-rw-r--r--onelua.c20
-rw-r--r--testes/calls.lua14
-rw-r--r--testes/db.lua2
-rw-r--r--testes/errors.lua8
-rw-r--r--testes/main.lua50
33 files changed, 305 insertions, 205 deletions
diff --git a/lcode.c b/lcode.c
index 911dbd5f..caac6ba3 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)) {
@@ -1352,6 +1353,35 @@ static int constfolding (FuncState *fs, int op, expdesc *e1,
1352 1353
1353 1354
1354/* 1355/*
1356** Convert a BinOpr to an OpCode (ORDER OPR - ORDER OP)
1357*/
1358l_sinline OpCode binopr2op (BinOpr opr, BinOpr baser, OpCode base) {
1359 lua_assert(baser <= opr &&
1360 ((baser == OPR_ADD && opr <= OPR_SHR) ||
1361 (baser == OPR_LT && opr <= OPR_LE)));
1362 return cast(OpCode, (cast_int(opr) - cast_int(baser)) + cast_int(base));
1363}
1364
1365
1366/*
1367** Convert a UnOpr to an OpCode (ORDER OPR - ORDER OP)
1368*/
1369l_sinline OpCode unopr2op (UnOpr opr) {
1370 return cast(OpCode, (cast_int(opr) - cast_int(OPR_MINUS)) +
1371 cast_int(OP_UNM));
1372}
1373
1374
1375/*
1376** Convert a BinOpr to a tag method (ORDER OPR - ORDER TM)
1377*/
1378l_sinline TMS binopr2TM (BinOpr opr) {
1379 lua_assert(OPR_ADD <= opr && opr <= OPR_SHR);
1380 return cast(TMS, (cast_int(opr) - cast_int(OPR_ADD)) + cast_int(TM_ADD));
1381}
1382
1383
1384/*
1355** Emit code for unary expressions that "produce values" 1385** Emit code for unary expressions that "produce values"
1356** (everything but 'not'). 1386** (everything but 'not').
1357** Expression to produce final result will be encoded in 'e'. 1387** Expression to produce final result will be encoded in 'e'.
@@ -1389,15 +1419,15 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
1389** Emit code for binary expressions that "produce values" over 1419** Emit code for binary expressions that "produce values" over
1390** two registers. 1420** two registers.
1391*/ 1421*/
1392static void codebinexpval (FuncState *fs, OpCode op, 1422static void codebinexpval (FuncState *fs, BinOpr opr,
1393 expdesc *e1, expdesc *e2, int line) { 1423 expdesc *e1, expdesc *e2, int line) {
1424 OpCode op = binopr2op(opr, OPR_ADD, OP_ADD);
1394 int v2 = luaK_exp2anyreg(fs, e2); /* make sure 'e2' is in a register */ 1425 int v2 = luaK_exp2anyreg(fs, e2); /* make sure 'e2' is in a register */
1395 /* 'e1' must be already in a register or it is a constant */ 1426 /* 'e1' must be already in a register or it is a constant */
1396 lua_assert((VNIL <= e1->k && e1->k <= VKSTR) || 1427 lua_assert((VNIL <= e1->k && e1->k <= VKSTR) ||
1397 e1->k == VNONRELOC || e1->k == VRELOC); 1428 e1->k == VNONRELOC || e1->k == VRELOC);
1398 lua_assert(OP_ADD <= op && op <= OP_SHR); 1429 lua_assert(OP_ADD <= op && op <= OP_SHR);
1399 finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, 1430 finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, binopr2TM(opr));
1400 cast(TMS, (op - OP_ADD) + TM_ADD));
1401} 1431}
1402 1432
1403 1433
@@ -1418,9 +1448,9 @@ static void codebini (FuncState *fs, OpCode op,
1418*/ 1448*/
1419static void codebinK (FuncState *fs, BinOpr opr, 1449static void codebinK (FuncState *fs, BinOpr opr,
1420 expdesc *e1, expdesc *e2, int flip, int line) { 1450 expdesc *e1, expdesc *e2, int flip, int line) {
1421 TMS event = cast(TMS, opr + TM_ADD); 1451 TMS event = binopr2TM(opr);
1422 int v2 = e2->u.info; /* K index */ 1452 int v2 = e2->u.info; /* K index */
1423 OpCode op = cast(OpCode, opr + OP_ADDK); 1453 OpCode op = binopr2op(opr, OPR_ADD, OP_ADDK);
1424 finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event); 1454 finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event);
1425} 1455}
1426 1456
@@ -1430,7 +1460,7 @@ static void codebinK (FuncState *fs, BinOpr opr,
1430*/ 1460*/
1431static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2, 1461static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2,
1432 OpCode op, int line, TMS event) { 1462 OpCode op, int line, TMS event) {
1433 if (!luaK_isKint(e2)) 1463 if (!isKint(e2))
1434 return 0; /* not an integer constant */ 1464 return 0; /* not an integer constant */
1435 else { 1465 else {
1436 lua_Integer i2 = e2->u.ival; 1466 lua_Integer i2 = e2->u.ival;
@@ -1457,10 +1487,9 @@ static void swapexps (expdesc *e1, expdesc *e2) {
1457*/ 1487*/
1458static void codebinNoK (FuncState *fs, BinOpr opr, 1488static void codebinNoK (FuncState *fs, BinOpr opr,
1459 expdesc *e1, expdesc *e2, int flip, int line) { 1489 expdesc *e1, expdesc *e2, int flip, int line) {
1460 OpCode op = cast(OpCode, opr + OP_ADD);
1461 if (flip) 1490 if (flip)
1462 swapexps(e1, e2); /* back to original order */ 1491 swapexps(e1, e2); /* back to original order */
1463 codebinexpval(fs, op, e1, e2, line); /* use standard operators */ 1492 codebinexpval(fs, opr, e1, e2, line); /* use standard operators */
1464} 1493}
1465 1494
1466 1495
@@ -1490,7 +1519,7 @@ static void codecommutative (FuncState *fs, BinOpr op,
1490 flip = 1; 1519 flip = 1;
1491 } 1520 }
1492 if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */ 1521 if (op == OPR_ADD && isSCint(e2)) /* immediate operand? */
1493 codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD); 1522 codebini(fs, OP_ADDI, e1, e2, flip, line, TM_ADD);
1494 else 1523 else
1495 codearith(fs, op, e1, e2, flip, line); 1524 codearith(fs, op, e1, e2, flip, line);
1496} 1525}
@@ -1518,25 +1547,27 @@ static void codebitwise (FuncState *fs, BinOpr opr,
1518** Emit code for order comparisons. When using an immediate operand, 1547** Emit code for order comparisons. When using an immediate operand,
1519** 'isfloat' tells whether the original value was a float. 1548** 'isfloat' tells whether the original value was a float.
1520*/ 1549*/
1521static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) { 1550static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1522 int r1, r2; 1551 int r1, r2;
1523 int im; 1552 int im;
1524 int isfloat = 0; 1553 int isfloat = 0;
1554 OpCode op;
1525 if (isSCnumber(e2, &im, &isfloat)) { 1555 if (isSCnumber(e2, &im, &isfloat)) {
1526 /* use immediate operand */ 1556 /* use immediate operand */
1527 r1 = luaK_exp2anyreg(fs, e1); 1557 r1 = luaK_exp2anyreg(fs, e1);
1528 r2 = im; 1558 r2 = im;
1529 op = cast(OpCode, (op - OP_LT) + OP_LTI); 1559 op = binopr2op(opr, OPR_LT, OP_LTI);
1530 } 1560 }
1531 else if (isSCnumber(e1, &im, &isfloat)) { 1561 else if (isSCnumber(e1, &im, &isfloat)) {
1532 /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */ 1562 /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
1533 r1 = luaK_exp2anyreg(fs, e2); 1563 r1 = luaK_exp2anyreg(fs, e2);
1534 r2 = im; 1564 r2 = im;
1535 op = (op == OP_LT) ? OP_GTI : OP_GEI; 1565 op = binopr2op(opr, OPR_LT, OP_GTI);
1536 } 1566 }
1537 else { /* regular case, compare two registers */ 1567 else { /* regular case, compare two registers */
1538 r1 = luaK_exp2anyreg(fs, e1); 1568 r1 = luaK_exp2anyreg(fs, e1);
1539 r2 = luaK_exp2anyreg(fs, e2); 1569 r2 = luaK_exp2anyreg(fs, e2);
1570 op = binopr2op(opr, OPR_LT, OP_LT);
1540 } 1571 }
1541 freeexps(fs, e1, e2); 1572 freeexps(fs, e1, e2);
1542 e1->u.info = condjump(fs, op, r1, r2, isfloat, 1); 1573 e1->u.info = condjump(fs, op, r1, r2, isfloat, 1);
@@ -1562,7 +1593,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1562 op = OP_EQI; 1593 op = OP_EQI;
1563 r2 = im; /* immediate operand */ 1594 r2 = im; /* immediate operand */
1564 } 1595 }
1565 else if (luaK_exp2RK(fs, e2)) { /* 2nd expression is constant? */ 1596 else if (exp2RK(fs, e2)) { /* 2nd expression is constant? */
1566 op = OP_EQK; 1597 op = OP_EQK;
1567 r2 = e2->u.info; /* constant index */ 1598 r2 = e2->u.info; /* constant index */
1568 } 1599 }
@@ -1579,16 +1610,16 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
1579/* 1610/*
1580** Apply prefix operation 'op' to expression 'e'. 1611** Apply prefix operation 'op' to expression 'e'.
1581*/ 1612*/
1582void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { 1613void luaK_prefix (FuncState *fs, UnOpr opr, expdesc *e, int line) {
1583 static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP}; 1614 static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
1584 luaK_dischargevars(fs, e); 1615 luaK_dischargevars(fs, e);
1585 switch (op) { 1616 switch (opr) {
1586 case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */ 1617 case OPR_MINUS: case OPR_BNOT: /* use 'ef' as fake 2nd operand */
1587 if (constfolding(fs, op + LUA_OPUNM, e, &ef)) 1618 if (constfolding(fs, opr + LUA_OPUNM, e, &ef))
1588 break; 1619 break;
1589 /* else */ /* FALLTHROUGH */ 1620 /* else */ /* FALLTHROUGH */
1590 case OPR_LEN: 1621 case OPR_LEN:
1591 codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line); 1622 codeunexpval(fs, unopr2op(opr), e, line);
1592 break; 1623 break;
1593 case OPR_NOT: codenot(fs, e); break; 1624 case OPR_NOT: codenot(fs, e); break;
1594 default: lua_assert(0); 1625 default: lua_assert(0);
@@ -1628,7 +1659,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
1628 } 1659 }
1629 case OPR_EQ: case OPR_NE: { 1660 case OPR_EQ: case OPR_NE: {
1630 if (!tonumeral(v, NULL)) 1661 if (!tonumeral(v, NULL))
1631 luaK_exp2RK(fs, v); 1662 exp2RK(fs, v);
1632 /* else keep numeral, which may be an immediate operand */ 1663 /* else keep numeral, which may be an immediate operand */
1633 break; 1664 break;
1634 } 1665 }
@@ -1718,30 +1749,27 @@ void luaK_posfix (FuncState *fs, BinOpr opr,
1718 /* coded as (r1 >> -I) */; 1749 /* coded as (r1 >> -I) */;
1719 } 1750 }
1720 else /* regular case (two registers) */ 1751 else /* regular case (two registers) */
1721 codebinexpval(fs, OP_SHL, e1, e2, line); 1752 codebinexpval(fs, opr, e1, e2, line);
1722 break; 1753 break;
1723 } 1754 }
1724 case OPR_SHR: { 1755 case OPR_SHR: {
1725 if (isSCint(e2)) 1756 if (isSCint(e2))
1726 codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */ 1757 codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR); /* r1 >> I */
1727 else /* regular case (two registers) */ 1758 else /* regular case (two registers) */
1728 codebinexpval(fs, OP_SHR, e1, e2, line); 1759 codebinexpval(fs, opr, e1, e2, line);
1729 break; 1760 break;
1730 } 1761 }
1731 case OPR_EQ: case OPR_NE: { 1762 case OPR_EQ: case OPR_NE: {
1732 codeeq(fs, opr, e1, e2); 1763 codeeq(fs, opr, e1, e2);
1733 break; 1764 break;
1734 } 1765 }
1735 case OPR_LT: case OPR_LE: {
1736 OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
1737 codeorder(fs, op, e1, e2);
1738 break;
1739 }
1740 case OPR_GT: case OPR_GE: { 1766 case OPR_GT: case OPR_GE: {
1741 /* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */ 1767 /* '(a > b)' <=> '(b < a)'; '(a >= b)' <=> '(b <= a)' */
1742 OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
1743 swapexps(e1, e2); 1768 swapexps(e1, e2);
1744 codeorder(fs, op, e1, e2); 1769 opr = cast(BinOpr, (opr - OPR_GT) + OPR_LT);
1770 } /* FALLTHROUGH */
1771 case OPR_LT: case OPR_LE: {
1772 codeorder(fs, opr, e1, e2);
1745 break; 1773 break;
1746 } 1774 }
1747 default: lua_assert(0); 1775 default: lua_assert(0);
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/lcorolib.c b/lcorolib.c
index 40b880b1..c64adf08 100644
--- a/lcorolib.c
+++ b/lcorolib.c
@@ -76,7 +76,7 @@ static int luaB_auxwrap (lua_State *L) {
76 if (l_unlikely(r < 0)) { /* error? */ 76 if (l_unlikely(r < 0)) { /* error? */
77 int stat = lua_status(co); 77 int stat = lua_status(co);
78 if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */ 78 if (stat != LUA_OK && stat != LUA_YIELD) { /* error in the coroutine? */
79 stat = lua_resetthread(co, L); /* close its tbc variables */ 79 stat = lua_closethread(co, L); /* close its tbc variables */
80 lua_assert(stat != LUA_OK); 80 lua_assert(stat != LUA_OK);
81 lua_xmove(co, L, 1); /* move error message to the caller */ 81 lua_xmove(co, L, 1); /* move error message to the caller */
82 } 82 }
@@ -172,7 +172,7 @@ static int luaB_close (lua_State *L) {
172 int status = auxstatus(L, co); 172 int status = auxstatus(L, co);
173 switch (status) { 173 switch (status) {
174 case COS_DEAD: case COS_YIELD: { 174 case COS_DEAD: case COS_YIELD: {
175 status = lua_resetthread(co, L); 175 status = lua_closethread(co, L);
176 if (status == LUA_OK) { 176 if (status == LUA_OK) {
177 lua_pushboolean(L, 1); 177 lua_pushboolean(L, 1);
178 return 1; 178 return 1;
diff --git a/ldebug.c b/ldebug.c
index 3fae5cf2..28b1caab 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -656,18 +656,19 @@ static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
656 656
657 657
658/* 658/*
659** Check whether pointer 'o' points to some value in the stack 659** Check whether pointer 'o' points to some value in the stack frame of
660** frame of the current function. Because 'o' may not point to a 660** the current function and, if so, returns its index. Because 'o' may
661** value in this stack, we cannot compare it with the region 661** not point to a value in this stack, we cannot compare it with the
662** boundaries (undefined behaviour in ISO C). 662** region boundaries (undefined behavior in ISO C).
663*/ 663*/
664static int isinstack (CallInfo *ci, const TValue *o) { 664static int instack (CallInfo *ci, const TValue *o) {
665 StkId pos; 665 int pos;
666 for (pos = ci->func.p + 1; pos < ci->top.p; pos++) { 666 StkId base = ci->func.p + 1;
667 if (o == s2v(pos)) 667 for (pos = 0; base + pos < ci->top.p; pos++) {
668 return 1; 668 if (o == s2v(base + pos))
669 return pos;
669 } 670 }
670 return 0; /* not found */ 671 return -1; /* not found */
671} 672}
672 673
673 674
@@ -708,9 +709,11 @@ static const char *varinfo (lua_State *L, const TValue *o) {
708 const char *kind = NULL; 709 const char *kind = NULL;
709 if (isLua(ci)) { 710 if (isLua(ci)) {
710 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ 711 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
711 if (!kind && isinstack(ci, o)) /* no? try a register */ 712 if (!kind) { /* not an upvalue? */
712 kind = getobjname(ci_func(ci)->p, currentpc(ci), 713 int reg = instack(ci, o); /* try a register */
713 cast_int(cast(StkId, o) - (ci->func.p + 1)), &name); 714 if (reg >= 0) /* is 'o' a register? */
715 kind = getobjname(ci_func(ci)->p, currentpc(ci), reg, &name);
716 }
714 } 717 }
715 return formatvarinfo(L, kind, name); 718 return formatvarinfo(L, kind, name);
716} 719}
@@ -845,7 +848,7 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
845 if (p->lineinfo == NULL) /* no debug information? */ 848 if (p->lineinfo == NULL) /* no debug information? */
846 return 0; 849 return 0;
847 if (newpc - oldpc < MAXIWTHABS / 2) { /* not too far apart? */ 850 if (newpc - oldpc < MAXIWTHABS / 2) { /* not too far apart? */
848 int delta = 0; /* line diference */ 851 int delta = 0; /* line difference */
849 int pc = oldpc; 852 int pc = oldpc;
850 for (;;) { 853 for (;;) {
851 int lineinfo = p->lineinfo[++pc]; 854 int lineinfo = p->lineinfo[++pc];
diff --git a/ldo.c b/ldo.c
index 54518aff..3df6a4b8 100644
--- a/ldo.c
+++ b/ldo.c
@@ -299,17 +299,13 @@ static int stackinuse (lua_State *L) {
299*/ 299*/
300void luaD_shrinkstack (lua_State *L) { 300void luaD_shrinkstack (lua_State *L) {
301 int inuse = stackinuse(L); 301 int inuse = stackinuse(L);
302 int nsize = inuse * 2; /* proposed new size */ 302 int max = (inuse > LUAI_MAXSTACK / 3) ? LUAI_MAXSTACK : inuse * 3;
303 int max = inuse * 3; /* maximum "reasonable" size */
304 if (max > LUAI_MAXSTACK) {
305 max = LUAI_MAXSTACK; /* respect stack limit */
306 if (nsize > LUAI_MAXSTACK)
307 nsize = LUAI_MAXSTACK;
308 }
309 /* if thread is currently not handling a stack overflow and its 303 /* if thread is currently not handling a stack overflow and its
310 size is larger than maximum "reasonable" size, shrink it */ 304 size is larger than maximum "reasonable" size, shrink it */
311 if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) 305 if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) {
306 int nsize = (inuse > LUAI_MAXSTACK / 2) ? LUAI_MAXSTACK : inuse * 2;
312 luaD_reallocstack(L, nsize, 0); /* ok if that fails */ 307 luaD_reallocstack(L, nsize, 0); /* ok if that fails */
308 }
313 else /* don't change stack */ 309 else /* don't change stack */
314 condmovestack(L,{},{}); /* (change only for debugging) */ 310 condmovestack(L,{},{}); /* (change only for debugging) */
315 luaE_shrinkCI(L); /* shrink CI list */ 311 luaE_shrinkCI(L); /* shrink CI list */
@@ -413,7 +409,7 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
413** 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
414** an error if there is no '__call' metafield. 410** an error if there is no '__call' metafield.
415*/ 411*/
416StkId luaD_tryfuncTM (lua_State *L, StkId func) { 412static StkId tryfuncTM (lua_State *L, StkId func) {
417 const TValue *tm; 413 const TValue *tm;
418 StkId p; 414 StkId p;
419 checkstackp(L, 1, func); /* space for metamethod */ 415 checkstackp(L, 1, func); /* space for metamethod */
@@ -572,7 +568,7 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
572 return -1; 568 return -1;
573 } 569 }
574 default: { /* not a function */ 570 default: { /* not a function */
575 func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ 571 func = tryfuncTM(L, func); /* try to get '__call' metamethod */
576 /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */ 572 /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */
577 narg1++; 573 narg1++;
578 goto retry; /* try again */ 574 goto retry; /* try again */
@@ -613,7 +609,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
613 return ci; 609 return ci;
614 } 610 }
615 default: { /* not a function */ 611 default: { /* not a function */
616 func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ 612 func = tryfuncTM(L, func); /* try to get '__call' metamethod */
617 /* return luaD_precall(L, func, nresults); */ 613 /* return luaD_precall(L, func, nresults); */
618 goto retry; /* try again with metamethod */ 614 goto retry; /* try again with metamethod */
619 } 615 }
@@ -629,7 +625,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
629** check the stack before doing anything else. 'luaD_precall' already 625** check the stack before doing anything else. 'luaD_precall' already
630** does that. 626** does that.
631*/ 627*/
632l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) { 628l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 inc) {
633 CallInfo *ci; 629 CallInfo *ci;
634 L->nCcalls += inc; 630 L->nCcalls += inc;
635 if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) { 631 if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) {
diff --git a/ldo.h b/ldo.h
index b050fc08..4bc75030 100644
--- a/ldo.h
+++ b/ldo.h
@@ -59,7 +59,6 @@ LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
59LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); 59LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
60LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 60LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
61LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 61LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
62LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func);
63LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); 62LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status);
64LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 63LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
65 ptrdiff_t oldtop, ptrdiff_t ef); 64 ptrdiff_t oldtop, ptrdiff_t ef);
diff --git a/ldump.c b/ldump.c
index a99d7ec5..3e91190c 100644
--- a/ldump.c
+++ b/ldump.c
@@ -10,6 +10,7 @@
10#include "lprefix.h" 10#include "lprefix.h"
11 11
12 12
13#include <limits.h>
13#include <stddef.h> 14#include <stddef.h>
14 15
15#include "lua.h" 16#include "lua.h"
@@ -59,8 +60,11 @@ static void dumpByte (DumpState *D, int y) {
59} 60}
60 61
61 62
62/* dumpInt Buff Size */ 63/*
63#define DIBS ((sizeof(size_t) * 8 / 7) + 1) 64** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6"
65** rounds up the division.)
66*/
67#define DIBS ((sizeof(size_t) * CHAR_BIT + 6) / 7)
64 68
65static void dumpSize (DumpState *D, size_t x) { 69static void dumpSize (DumpState *D, size_t x) {
66 lu_byte buff[DIBS]; 70 lu_byte buff[DIBS];
diff --git a/llex.c b/llex.c
index b0dc0acc..5fc39a5c 100644
--- a/llex.c
+++ b/llex.c
@@ -128,7 +128,7 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
128** ensuring there is only one copy of each unique string. The table 128** ensuring there is only one copy of each unique string. The table
129** here is used as a set: the string enters as the key, while its value 129** here is used as a set: the string enters as the key, while its value
130** is irrelevant. We use the string itself as the value only because it 130** is irrelevant. We use the string itself as the value only because it
131** is a TValue readly available. Later, the code generation can change 131** is a TValue readily available. Later, the code generation can change
132** this value. 132** this value.
133*/ 133*/
134TString *luaX_newstring (LexState *ls, const char *str, size_t l) { 134TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
diff --git a/llimits.h b/llimits.h
index 03cc51cb..47dee9a6 100644
--- a/llimits.h
+++ b/llimits.h
@@ -81,7 +81,7 @@ typedef signed char ls_byte;
81#if defined(UINTPTR_MAX) /* even in C99 this type is optional */ 81#if defined(UINTPTR_MAX) /* even in C99 this type is optional */
82#define L_P2I uintptr_t 82#define L_P2I uintptr_t
83#else /* no 'intptr'? */ 83#else /* no 'intptr'? */
84#define L_P2I uintmax_t /* use the largerst available integer */ 84#define L_P2I uintmax_t /* use the largest available integer */
85#endif 85#endif
86#else /* C89 option */ 86#else /* C89 option */
87#define L_P2I size_t 87#define L_P2I size_t
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/lopcodes.h b/lopcodes.h
index 7c274515..46911cac 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -21,7 +21,7 @@ iABC C(8) | B(8) |k| A(8) | Op(7) |
21iABx Bx(17) | A(8) | Op(7) | 21iABx Bx(17) | A(8) | Op(7) |
22iAsBx sBx (signed)(17) | A(8) | Op(7) | 22iAsBx sBx (signed)(17) | A(8) | Op(7) |
23iAx Ax(25) | Op(7) | 23iAx Ax(25) | Op(7) |
24isJ sJ(25) | Op(7) | 24isJ sJ (signed)(25) | Op(7) |
25 25
26 A signed argument is represented in excess K: the represented value is 26 A signed argument is represented in excess K: the represented value is
27 the written unsigned value minus K, where K is half the maximum for the 27 the written unsigned value minus K, where K is half the maximum for the
@@ -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/loslib.c b/loslib.c
index 89ac06bc..ad5a9276 100644
--- a/loslib.c
+++ b/loslib.c
@@ -30,23 +30,14 @@
30*/ 30*/
31#if !defined(LUA_STRFTIMEOPTIONS) /* { */ 31#if !defined(LUA_STRFTIMEOPTIONS) /* { */
32 32
33/* options for ANSI C 89 (only 1-char options) */
34#define L_STRFTIMEC89 "aAbBcdHIjmMpSUwWxXyYZ%"
35
36/* options for ISO C 99 and POSIX */
37#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
38 "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
39
40/* options for Windows */
41#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
42 "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
43
44#if defined(LUA_USE_WINDOWS) 33#if defined(LUA_USE_WINDOWS)
45#define LUA_STRFTIMEOPTIONS L_STRFTIMEWIN 34#define LUA_STRFTIMEOPTIONS "aAbBcdHIjmMpSUwWxXyYzZ%" \
46#elif defined(LUA_USE_C89) 35 "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y" /* two-char options */
47#define LUA_STRFTIMEOPTIONS L_STRFTIMEC89 36#elif defined(LUA_USE_C89) /* ANSI C 89 (only 1-char options) */
37#define LUA_STRFTIMEOPTIONS "aAbBcdHIjmMpSUwWxXyYZ%"
48#else /* C99 specification */ 38#else /* C99 specification */
49#define LUA_STRFTIMEOPTIONS L_STRFTIMEC99 39#define LUA_STRFTIMEOPTIONS "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
40 "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy" /* two-char options */
50#endif 41#endif
51 42
52#endif /* } */ 43#endif /* } */
diff --git a/lparser.c b/lparser.c
index c0eb7890..2ac04160 100644
--- a/lparser.c
+++ b/lparser.c
@@ -529,12 +529,12 @@ static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
529 529
530/* 530/*
531** Solves the goto at index 'g' to given 'label' and removes it 531** Solves the goto at index 'g' to given 'label' and removes it
532** from the list of pending goto's. 532** from the list of pending gotos.
533** If it jumps into the scope of some variable, raises an error. 533** If it jumps into the scope of some variable, raises an error.
534*/ 534*/
535static void solvegoto (LexState *ls, int g, Labeldesc *label) { 535static void solvegoto (LexState *ls, int g, Labeldesc *label) {
536 int i; 536 int i;
537 Labellist *gl = &ls->dyd->gt; /* list of goto's */ 537 Labellist *gl = &ls->dyd->gt; /* list of gotos */
538 Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */ 538 Labeldesc *gt = &gl->arr[g]; /* goto to be resolved */
539 lua_assert(eqstr(gt->name, label->name)); 539 lua_assert(eqstr(gt->name, label->name));
540 if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */ 540 if (l_unlikely(gt->nactvar < label->nactvar)) /* enter some scope? */
@@ -588,7 +588,7 @@ static int newgotoentry (LexState *ls, TString *name, int line, int pc) {
588/* 588/*
589** Solves forward jumps. Check whether new label 'lb' matches any 589** Solves forward jumps. Check whether new label 'lb' matches any
590** pending gotos in current block and solves them. Return true 590** pending gotos in current block and solves them. Return true
591** if any of the goto's need to close upvalues. 591** if any of the gotos need to close upvalues.
592*/ 592*/
593static int solvegotos (LexState *ls, Labeldesc *lb) { 593static int solvegotos (LexState *ls, Labeldesc *lb) {
594 Labellist *gl = &ls->dyd->gt; 594 Labellist *gl = &ls->dyd->gt;
@@ -609,7 +609,7 @@ static int solvegotos (LexState *ls, Labeldesc *lb) {
609/* 609/*
610** Create a new label with the given 'name' at the given 'line'. 610** Create a new label with the given 'name' at the given 'line'.
611** 'last' tells whether label is the last non-op statement in its 611** 'last' tells whether label is the last non-op statement in its
612** block. Solves all pending goto's to this new label and adds 612** block. Solves all pending gotos to this new label and adds
613** a close instruction if necessary. 613** a close instruction if necessary.
614** Returns true iff it added a close instruction. 614** Returns true iff it added a close instruction.
615*/ 615*/
diff --git a/lstate.c b/lstate.c
index 1ce6b9a1..37301c3c 100644
--- a/lstate.c
+++ b/lstate.c
@@ -88,7 +88,7 @@ CallInfo *luaE_extendCI (lua_State *L) {
88/* 88/*
89** free all CallInfo structures not in use by a thread 89** free all CallInfo structures not in use by a thread
90*/ 90*/
91void luaE_freeCI (lua_State *L) { 91static void freeCI (lua_State *L) {
92 CallInfo *ci = L->ci; 92 CallInfo *ci = L->ci;
93 CallInfo *next = ci->next; 93 CallInfo *next = ci->next;
94 ci->next = NULL; 94 ci->next = NULL;
@@ -173,7 +173,7 @@ static void freestack (lua_State *L) {
173 if (L->stack.p == NULL) 173 if (L->stack.p == NULL)
174 return; /* stack not completely built yet */ 174 return; /* stack not completely built yet */
175 L->ci = &L->base_ci; /* free the entire 'ci' list */ 175 L->ci = &L->base_ci; /* free the entire 'ci' list */
176 luaE_freeCI(L); 176 freeCI(L);
177 lua_assert(L->nci == 0); 177 lua_assert(L->nci == 0);
178 luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK); /* free stack */ 178 luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK); /* free stack */
179} 179}
@@ -309,7 +309,7 @@ int luaE_resetthread (lua_State *L, int status) {
309} 309}
310 310
311 311
312LUA_API int lua_resetthread (lua_State *L, lua_State *from) { 312LUA_API int lua_closethread (lua_State *L, lua_State *from) {
313 int status; 313 int status;
314 lua_lock(L); 314 lua_lock(L);
315 L->nCcalls = (from) ? getCcalls(from) : 0; 315 L->nCcalls = (from) ? getCcalls(from) : 0;
diff --git a/lstate.h b/lstate.h
index 50273295..488d2c5a 100644
--- a/lstate.h
+++ b/lstate.h
@@ -399,7 +399,6 @@ union GCUnion {
399LUAI_FUNC void luaE_setdebt (global_State *g, l_obj debt); 399LUAI_FUNC void luaE_setdebt (global_State *g, l_obj debt);
400LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 400LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
401LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 401LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
402LUAI_FUNC void luaE_freeCI (lua_State *L);
403LUAI_FUNC void luaE_shrinkCI (lua_State *L); 402LUAI_FUNC void luaE_shrinkCI (lua_State *L);
404LUAI_FUNC void luaE_checkcstack (lua_State *L); 403LUAI_FUNC void luaE_checkcstack (lua_State *L);
405LUAI_FUNC void luaE_incCstack (lua_State *L); 404LUAI_FUNC void luaE_incCstack (lua_State *L);
diff --git a/lstrlib.c b/lstrlib.c
index ce07d9bc..e29c09b9 100644
--- a/lstrlib.c
+++ b/lstrlib.c
@@ -571,7 +571,7 @@ static const char *match_capture (MatchState *ms, const char *s, int l) {
571static const char *match (MatchState *ms, const char *s, const char *p) { 571static const char *match (MatchState *ms, const char *s, const char *p) {
572 if (l_unlikely(ms->matchdepth-- == 0)) 572 if (l_unlikely(ms->matchdepth-- == 0))
573 luaL_error(ms->L, "pattern too complex"); 573 luaL_error(ms->L, "pattern too complex");
574 init: /* using goto's to optimize tail recursion */ 574 init: /* using goto to optimize tail recursion */
575 if (p != ms->p_end) { /* end of pattern? */ 575 if (p != ms->p_end) { /* end of pattern? */
576 switch (*p) { 576 switch (*p) {
577 case '(': { /* start capture */ 577 case '(': { /* start capture */
diff --git a/ltable.c b/ltable.c
index 485563f3..8db26bdc 100644
--- a/ltable.c
+++ b/ltable.c
@@ -278,10 +278,12 @@ LUAI_FUNC unsigned int luaH_realasize (const Table *t) {
278 size |= (size >> 2); 278 size |= (size >> 2);
279 size |= (size >> 4); 279 size |= (size >> 4);
280 size |= (size >> 8); 280 size |= (size >> 8);
281#if (UINT_MAX >> 14) > 3 /* unsigned int has more than 16 bits */
281 size |= (size >> 16); 282 size |= (size >> 16);
282#if (UINT_MAX >> 30) > 3 283#if (UINT_MAX >> 30) > 3
283 size |= (size >> 32); /* unsigned int has more than 32 bits */ 284 size |= (size >> 32); /* unsigned int has more than 32 bits */
284#endif 285#endif
286#endif
285 size++; 287 size++;
286 lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size); 288 lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size);
287 return size; 289 return size;
@@ -710,7 +712,8 @@ static Node *getfreepos (Table *t) {
710** put new key in its main position; otherwise (colliding node is in its main 712** put new key in its main position; otherwise (colliding node is in its main
711** position), new key goes to an empty position. 713** position), new key goes to an empty position.
712*/ 714*/
713void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) { 715static void luaH_newkey (lua_State *L, Table *t, const TValue *key,
716 TValue *value) {
714 Node *mp; 717 Node *mp;
715 TValue aux; 718 TValue aux;
716 if (l_unlikely(ttisnil(key))) 719 if (l_unlikely(ttisnil(key)))
diff --git a/ltable.h b/ltable.h
index dce8c2f7..30cfc8be 100644
--- a/ltable.h
+++ b/ltable.h
@@ -51,8 +51,6 @@ LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
51LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 51LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
52LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 52LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
53LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 53LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
54LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key,
55 TValue *value);
56LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 54LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key,
57 TValue *value); 55 TValue *value);
58LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 56LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key,
diff --git a/ltests.c b/ltests.c
index 456e83e1..e218778a 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1526,7 +1526,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
1526 lua_newthread(L1); 1526 lua_newthread(L1);
1527 } 1527 }
1528 else if EQ("resetthread") { 1528 else if EQ("resetthread") {
1529 lua_pushinteger(L1, lua_resetthread(L1, L)); 1529 lua_pushinteger(L1, lua_resetthread(L1)); /* deprecated */
1530 } 1530 }
1531 else if EQ("newuserdata") { 1531 else if EQ("newuserdata") {
1532 lua_newuserdata(L1, getnum); 1532 lua_newuserdata(L1, getnum);
diff --git a/ltm.h b/ltm.h
index 82a26a96..f3872655 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 af20754e..1e884b07 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
@@ -670,7 +678,7 @@ int main (int argc, char **argv) {
670 l_message(argv[0], "cannot create state: not enough memory"); 678 l_message(argv[0], "cannot create state: not enough memory");
671 return EXIT_FAILURE; 679 return EXIT_FAILURE;
672 } 680 }
673 lua_gc(L, LUA_GCSTOP); /* stop GC while buidling state */ 681 lua_gc(L, LUA_GCSTOP); /* stop GC while building state */
674 lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */ 682 lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
675 lua_pushinteger(L, argc); /* 1st argument */ 683 lua_pushinteger(L, argc); /* 1st argument */
676 lua_pushlightuserdata(L, argv); /* 2nd argument */ 684 lua_pushlightuserdata(L, argv); /* 2nd argument */
diff --git a/lua.h b/lua.h
index e950dfb4..699b7ca7 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 "5" 21#define LUA_VERSION_MINOR_N 5
21#define LUA_VERSION_RELEASE "0" 22#define LUA_VERSION_RELEASE_N 0
22 23
23#define LUA_VERSION_NUM 505 24#define LUA_VERSION_NUM (LUA_VERSION_MAJOR_N * 100 + LUA_VERSION_MINOR_N)
24#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0) 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-2022 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') */
@@ -164,7 +163,7 @@ LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud,
164 unsigned int seed); 163 unsigned int seed);
165LUA_API void (lua_close) (lua_State *L); 164LUA_API void (lua_close) (lua_State *L);
166LUA_API lua_State *(lua_newthread) (lua_State *L); 165LUA_API lua_State *(lua_newthread) (lua_State *L);
167LUA_API int (lua_resetthread) (lua_State *L, lua_State *from); 166LUA_API int (lua_closethread) (lua_State *L, lua_State *from);
168 167
169LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); 168LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
170 169
@@ -426,6 +425,8 @@ LUA_API void (lua_closeslot) (lua_State *L, int idx);
426 425
427#define LUA_NUMTAGS LUA_NUMTYPES 426#define LUA_NUMTAGS LUA_NUMTYPES
428 427
428#define lua_resetthread(L) lua_closethread(L,NULL)
429
429/* }============================================================== */ 430/* }============================================================== */
430 431
431/* 432/*
@@ -496,8 +497,19 @@ struct lua_Debug {
496/* }====================================================================== */ 497/* }====================================================================== */
497 498
498 499
500#define LUAI_TOSTRAUX(x) #x
501#define LUAI_TOSTR(x) LUAI_TOSTRAUX(x)
502
503#define LUA_VERSION_MAJOR LUAI_TOSTR(LUA_VERSION_MAJOR_N)
504#define LUA_VERSION_MINOR LUAI_TOSTR(LUA_VERSION_MINOR_N)
505#define LUA_VERSION_RELEASE LUAI_TOSTR(LUA_VERSION_RELEASE_N)
506
507#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
508#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
509
510
499/****************************************************************************** 511/******************************************************************************
500* Copyright (C) 1994-2022 Lua.org, PUC-Rio. 512* Copyright (C) 1994-2023 Lua.org, PUC-Rio.
501* 513*
502* Permission is hereby granted, free of charge, to any person obtaining 514* Permission is hereby granted, free of charge, to any person obtaining
503* a copy of this software and associated documentation files (the 515* a copy of this software and associated documentation files (the
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 3bff463f..1df15e53 100644
--- a/lundump.c
+++ b/lundump.c
@@ -261,6 +261,8 @@ static void loadDebug (LoadState *S, Proto *f) {
261 f->locvars[i].endpc = loadInt(S); 261 f->locvars[i].endpc = loadInt(S);
262 } 262 }
263 n = loadInt(S); 263 n = loadInt(S);
264 if (n != 0) /* does it have debug information? */
265 n = f->sizeupvalues; /* must be this many */
264 for (i = 0; i < n; i++) 266 for (i = 0; i < n; i++)
265 f->upvalues[i].name = loadStringN(S, f); 267 f->upvalues[i].name = loadStringN(S, f);
266} 268}
diff --git a/lvm.c b/lvm.c
index 8ab8753d..a3128c3d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -367,30 +367,32 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
367 367
368 368
369/* 369/*
370** Compare two strings 'ls' x 'rs', returning an integer less-equal- 370** Compare two strings 'ts1' x 'ts2', returning an integer less-equal-
371** -greater than zero if 'ls' is less-equal-greater than 'rs'. 371** -greater than zero if 'ts1' is less-equal-greater than 'ts2'.
372** The code is a little tricky because it allows '\0' in the strings 372** The code is a little tricky because it allows '\0' in the strings
373** and it uses 'strcoll' (to respect locales) for each segments 373** and it uses 'strcoll' (to respect locales) for each segment
374** of the strings. 374** of the strings. Note that segments can compare equal but still
375** have different lengths.
375*/ 376*/
376static int l_strcmp (const TString *ls, const TString *rs) { 377static int l_strcmp (const TString *ts1, const TString *ts2) {
377 const char *l = getstr(ls); 378 const char *s1 = getstr(ts1);
378 size_t ll = tsslen(ls); 379 size_t rl1 = tsslen(ts1); /* real length */
379 const char *r = getstr(rs); 380 const char *s2 = getstr(ts2);
380 size_t lr = tsslen(rs); 381 size_t rl2 = tsslen(ts2);
381 for (;;) { /* for each segment */ 382 for (;;) { /* for each segment */
382 int temp = strcoll(l, r); 383 int temp = strcoll(s1, s2);
383 if (temp != 0) /* not equal? */ 384 if (temp != 0) /* not equal? */
384 return temp; /* done */ 385 return temp; /* done */
385 else { /* strings are equal up to a '\0' */ 386 else { /* strings are equal up to a '\0' */
386 size_t len = strlen(l); /* index of first '\0' in both strings */ 387 size_t zl1 = strlen(s1); /* index of first '\0' in 's1' */
387 if (len == lr) /* 'rs' is finished? */ 388 size_t zl2 = strlen(s2); /* index of first '\0' in 's2' */
388 return (len == ll) ? 0 : 1; /* check 'ls' */ 389 if (zl2 == rl2) /* 's2' is finished? */
389 else if (len == ll) /* 'ls' is finished? */ 390 return (zl1 == rl1) ? 0 : 1; /* check 's1' */
390 return -1; /* 'ls' is less than 'rs' ('rs' is not finished) */ 391 else if (zl1 == rl1) /* 's1' is finished? */
391 /* both strings longer than 'len'; go on comparing after the '\0' */ 392 return -1; /* 's1' is less than 's2' ('s2' is not finished) */
392 len++; 393 /* both strings longer than 'zl'; go on comparing after the '\0' */
393 l += len; ll -= len; r += len; lr -= len; 394 zl1++; zl2++;
395 s1 += zl1; rl1 -= zl1; s2 += zl2; rl2 -= zl2;
394 } 396 }
395 } 397 }
396} 398}
@@ -1254,7 +1256,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1254 const TValue *slot; 1256 const TValue *slot;
1255 TValue *upval = cl->upvals[GETARG_B(i)]->v.p; 1257 TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
1256 TValue *rc = KC(i); 1258 TValue *rc = KC(i);
1257 TString *key = tsvalue(rc); /* key must be a string */ 1259 TString *key = tsvalue(rc); /* key must be a short string */
1258 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { 1260 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
1259 setobj2s(L, ra, slot); 1261 setobj2s(L, ra, slot);
1260 } 1262 }
@@ -1297,7 +1299,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1297 const TValue *slot; 1299 const TValue *slot;
1298 TValue *rb = vRB(i); 1300 TValue *rb = vRB(i);
1299 TValue *rc = KC(i); 1301 TValue *rc = KC(i);
1300 TString *key = tsvalue(rc); /* key must be a string */ 1302 TString *key = tsvalue(rc); /* key must be a short string */
1301 if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) { 1303 if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) {
1302 setobj2s(L, ra, slot); 1304 setobj2s(L, ra, slot);
1303 } 1305 }
@@ -1310,7 +1312,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1310 TValue *upval = cl->upvals[GETARG_A(i)]->v.p; 1312 TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
1311 TValue *rb = KB(i); 1313 TValue *rb = KB(i);
1312 TValue *rc = RKC(i); 1314 TValue *rc = RKC(i);
1313 TString *key = tsvalue(rb); /* key must be a string */ 1315 TString *key = tsvalue(rb); /* key must be a short string */
1314 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) { 1316 if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
1315 luaV_finishfastset(L, upval, slot, rc); 1317 luaV_finishfastset(L, upval, slot, rc);
1316 } 1318 }
@@ -1353,7 +1355,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1353 const TValue *slot; 1355 const TValue *slot;
1354 TValue *rb = KB(i); 1356 TValue *rb = KB(i);
1355 TValue *rc = RKC(i); 1357 TValue *rc = RKC(i);
1356 TString *key = tsvalue(rb); /* key must be a string */ 1358 TString *key = tsvalue(rb); /* key must be a short string */
1357 if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) { 1359 if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) {
1358 luaV_finishfastset(L, s2v(ra), slot, rc); 1360 luaV_finishfastset(L, s2v(ra), slot, rc);
1359 } 1361 }
@@ -1411,6 +1413,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1411 vmbreak; 1413 vmbreak;
1412 } 1414 }
1413 vmcase(OP_MODK) { 1415 vmcase(OP_MODK) {
1416 savestate(L, ci); /* in case of division by 0 */
1414 op_arithK(L, luaV_mod, luaV_modf); 1417 op_arithK(L, luaV_mod, luaV_modf);
1415 vmbreak; 1418 vmbreak;
1416 } 1419 }
@@ -1423,6 +1426,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1423 vmbreak; 1426 vmbreak;
1424 } 1427 }
1425 vmcase(OP_IDIVK) { 1428 vmcase(OP_IDIVK) {
1429 savestate(L, ci); /* in case of division by 0 */
1426 op_arithK(L, luaV_idiv, luai_numidiv); 1430 op_arithK(L, luaV_idiv, luai_numidiv);
1427 vmbreak; 1431 vmbreak;
1428 } 1432 }
@@ -1471,6 +1475,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1471 vmbreak; 1475 vmbreak;
1472 } 1476 }
1473 vmcase(OP_MOD) { 1477 vmcase(OP_MOD) {
1478 savestate(L, ci); /* in case of division by 0 */
1474 op_arith(L, luaV_mod, luaV_modf); 1479 op_arith(L, luaV_mod, luaV_modf);
1475 vmbreak; 1480 vmbreak;
1476 } 1481 }
@@ -1483,6 +1488,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1483 vmbreak; 1488 vmbreak;
1484 } 1489 }
1485 vmcase(OP_IDIV) { /* floor division */ 1490 vmcase(OP_IDIV) { /* floor division */
1491 savestate(L, ci); /* in case of division by 0 */
1486 op_arith(L, luaV_idiv, luai_numidiv); 1492 op_arith(L, luaV_idiv, luai_numidiv);
1487 vmbreak; 1493 vmbreak;
1488 } 1494 }
diff --git a/makefile b/makefile
index ee56c672..38e21f1f 100644
--- a/makefile
+++ b/makefile
@@ -8,7 +8,6 @@ CWARNSCPP= \
8 -Wfatal-errors \ 8 -Wfatal-errors \
9 -Wextra \ 9 -Wextra \
10 -Wshadow \ 10 -Wshadow \
11 -Wsign-compare \
12 -Wundef \ 11 -Wundef \
13 -Wwrite-strings \ 12 -Wwrite-strings \
14 -Wredundant-decls \ 13 -Wredundant-decls \
@@ -60,7 +59,7 @@ CWARNS= $(CWARNSCPP) $(CWARNSC) $(CWARNGCC)
60 59
61# The following options help detect "undefined behavior"s that seldom 60# The following options help detect "undefined behavior"s that seldom
62# create problems; some are only available in newer gcc versions. To 61# create problems; some are only available in newer gcc versions. To
63# use some of them, we also have to define an enrivonment variable 62# use some of them, we also have to define an environment variable
64# ASAN_OPTIONS="detect_invalid_pointer_pairs=2". 63# ASAN_OPTIONS="detect_invalid_pointer_pairs=2".
65# -fsanitize=undefined 64# -fsanitize=undefined
66# -fsanitize=pointer-subtract -fsanitize=address -fsanitize=pointer-compare 65# -fsanitize=pointer-subtract -fsanitize=address -fsanitize=pointer-compare
diff --git a/manual/2html b/manual/2html
index a4d860dd..43fd8913 100755
--- a/manual/2html
+++ b/manual/2html
@@ -30,7 +30,7 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
30<p> 30<p>
31<small> 31<small>
32<a href="http://www.lua.org/copyright.html">Copyright</a> 32<a href="http://www.lua.org/copyright.html">Copyright</a>
33&copy; 2022 Lua.org, PUC-Rio. All rights reserved. 33&copy; 2023 Lua.org, PUC-Rio. All rights reserved.
34</small> 34</small>
35<hr> 35<hr>
36 36
diff --git a/manual/manual.of b/manual/manual.of
index 446517ec..1e219f9a 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -20,7 +20,7 @@ making it ideal for configuration, scripting,
20and rapid prototyping. 20and rapid prototyping.
21 21
22Lua is implemented as a library, written in @emphx{clean C}, 22Lua is implemented as a library, written in @emphx{clean C},
23the common subset of C and C++. 23the common subset of @N{standard C} and C++.
24The Lua distribution includes a host program called @id{lua}, 24The Lua distribution includes a host program called @id{lua},
25which uses the Lua library to offer a complete, 25which uses the Lua library to offer a complete,
26standalone Lua interpreter, 26standalone Lua interpreter,
@@ -3161,6 +3161,27 @@ when called through this function.
3161 3161
3162} 3162}
3163 3163
3164@APIEntry{int lua_closethread (lua_State *L, lua_State *from);|
3165@apii{0,?,-}
3166
3167Resets a thread, cleaning its call stack and closing all pending
3168to-be-closed variables.
3169Returns a status code:
3170@Lid{LUA_OK} for no errors in the thread
3171(either the original error that stopped the thread or
3172errors in closing methods),
3173or an error status otherwise.
3174In case of error,
3175leaves the error object on the top of the stack.
3176
3177The parameter @id{from} represents the coroutine that is resetting @id{L}.
3178If there is no such coroutine,
3179this parameter can be @id{NULL}.
3180
3181(This function was introduced in @N{release 5.4.6}.)
3182
3183}
3184
3164@APIEntry{int lua_compare (lua_State *L, int index1, int index2, int op);| 3185@APIEntry{int lua_compare (lua_State *L, int index1, int index2, int op);|
3165@apii{0,0,e} 3186@apii{0,0,e}
3166 3187
@@ -4157,23 +4178,12 @@ and then pops the top element.
4157 4178
4158} 4179}
4159 4180
4160@APIEntry{int lua_resetthread (lua_State *L, lua_State *from);| 4181@APIEntry{int lua_resetthread (lua_State *L);|
4161@apii{0,?,-} 4182@apii{0,?,-}
4162 4183
4163Resets a thread, cleaning its call stack and closing all pending 4184This function is deprecated;
4164to-be-closed variables. 4185it is equivalent to @Lid{lua_closethread} with
4165Returns a status code: 4186@id{from} being @id{NULL}.
4166@Lid{LUA_OK} for no errors in the thread
4167(either the original error that stopped the thread or
4168errors in closing methods),
4169or an error status otherwise.
4170In case of error,
4171leaves the error object on the top of the stack.
4172
4173The parameter @id{from} represents the coroutine that is resetting @id{L}.
4174If there is no such coroutine,
4175this parameter can be @id{NULL}.
4176(This parameter was introduced in @N{release 5.4.5}.)
4177 4187
4178} 4188}
4179 4189
@@ -5787,7 +5797,7 @@ with @id{tname} in the registry.
5787 5797
5788Creates a new Lua state. 5798Creates a new Lua state.
5789It calls @Lid{lua_newstate} with an 5799It calls @Lid{lua_newstate} with an
5790allocator based on the @N{standard C} allocation functions 5800allocator based on the @N{ISO C} allocation functions
5791and then sets a warning function and a panic function @see{C-error} 5801and then sets a warning function and a panic function @see{C-error}
5792that print messages to the standard error output. 5802that print messages to the standard error output.
5793 5803
@@ -6905,10 +6915,10 @@ including if necessary a path and an extension.
6905@id{funcname} must be the exact name exported by the @N{C library} 6915@id{funcname} must be the exact name exported by the @N{C library}
6906(which may depend on the @N{C compiler} and linker used). 6916(which may depend on the @N{C compiler} and linker used).
6907 6917
6908This function is not supported by @N{ISO C}. 6918This functionality is not supported by @N{ISO C}.
6909As such, it is only available on some platforms 6919As such, @id{loadlib} is only available on some platforms:
6910(Windows, Linux, Mac OS X, Solaris, BSD, 6920Linux, Windows, Mac OS X, Solaris, BSD,
6911plus other Unix systems that support the @id{dlfcn} standard). 6921plus other Unix systems that support the @id{dlfcn} standard.
6912 6922
6913This function is inherently insecure, 6923This function is inherently insecure,
6914as it allows Lua to call any function in any readable dynamic 6924as it allows Lua to call any function in any readable dynamic
diff --git a/onelua.c b/onelua.c
index 3c605981..2a434961 100644
--- a/onelua.c
+++ b/onelua.c
@@ -1,5 +1,14 @@
1/* 1/*
2* one.c -- Lua core, libraries, and interpreter in a single file 2** Lua core, libraries, and interpreter in a single file.
3** Compiling just this file generates a complete Lua stand-alone
4** program:
5**
6** $ gcc -O2 -std=c99 -o lua onelua.c -lm
7**
8** or
9**
10** $ gcc -O2 -std=c89 -DLUA_USE_C89 -o lua onelua.c -lm
11**
3*/ 12*/
4 13
5/* default is to build the full interpreter */ 14/* default is to build the full interpreter */
@@ -11,8 +20,12 @@
11#endif 20#endif
12#endif 21#endif
13 22
14/* choose suitable platform-specific features */ 23
15/* some of these may need extra libraries such as -ldl -lreadline -lncurses */ 24/*
25** Choose suitable platform-specific features. Default is no
26** platform-specific features. Some of these options may need extra
27** libraries such as -ldl -lreadline -lncurses
28*/
16#if 0 29#if 0
17#define LUA_USE_LINUX 30#define LUA_USE_LINUX
18#define LUA_USE_MACOSX 31#define LUA_USE_MACOSX
@@ -20,6 +33,7 @@
20#define LUA_ANSI 33#define LUA_ANSI
21#endif 34#endif
22 35
36
23/* no need to change anything below this line ----------------------------- */ 37/* no need to change anything below this line ----------------------------- */
24 38
25#include "lprefix.h" 39#include "lprefix.h"
diff --git a/testes/calls.lua b/testes/calls.lua
index 9a5eed0b..559ca935 100644
--- a/testes/calls.lua
+++ b/testes/calls.lua
@@ -342,6 +342,20 @@ 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\x55\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
345x = string.dump(load("x = 1; return x")) 359x = string.dump(load("x = 1; return x"))
346a = assert(load(read1(x), nil, "b")) 360a = assert(load(read1(x), nil, "b"))
347assert(a() == 1 and _G.x == 1) 361assert(a() == 1 and _G.x == 1)
diff --git a/testes/db.lua b/testes/db.lua
index 02b96aca..67b58934 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -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 cf0ab526..bf6f389d 100644
--- a/testes/errors.lua
+++ b/testes/errors.lua
@@ -444,6 +444,14 @@ if not b then
444 end 444 end
445end]], 5) 445end]], 5)
446 446
447
448-- bug in 5.4.0
449lineerror([[
450 local a = 0
451 local b = 1
452 local c = b % a
453]], 3)
454
447do 455do
448 -- Force a negative estimate for base line. Error in instruction 2 456 -- Force a negative estimate for base line. Error in instruction 2
449 -- (after VARARGPREP, GETGLOBAL), with first absolute line information 457 -- (after VARARGPREP, GETGLOBAL), with first absolute line information
diff --git a/testes/main.lua b/testes/main.lua
index 40cbe548..dde72a74 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