瀏覽代碼

Merge branch 'master' into nextversion

Roberto Ierusalimschy 2 年之前
父節點
當前提交
ab6a949522
共有 33 個文件被更改,包括 305 次插入205 次删除
  1. 66 38
      lcode.c
  2. 0 3
      lcode.h
  3. 2 2
      lcorolib.c
  4. 17 14
      ldebug.c
  5. 8 12
      ldo.c
  6. 0 1
      ldo.h
  7. 6 2
      ldump.c
  8. 1 1
      llex.c
  9. 1 1
      llimits.h
  10. 0 9
      loadlib.c
  11. 5 5
      lopcodes.h
  12. 6 15
      loslib.c
  13. 4 4
      lparser.c
  14. 3 3
      lstate.c
  15. 0 1
      lstate.h
  16. 1 1
      lstrlib.c
  17. 4 1
      ltable.c
  18. 0 2
      ltable.h
  19. 1 1
      ltests.c
  20. 2 3
      ltm.h
  21. 11 3
      lua.c
  22. 25 13
      lua.h
  23. 9 0
      luaconf.h
  24. 2 0
      lundump.c
  25. 28 22
      lvm.c
  26. 1 2
      makefile
  27. 1 1
      manual/2html
  28. 31 21
      manual/manual.of
  29. 17 3
      onelua.c
  30. 14 0
      testes/calls.lua
  31. 1 1
      testes/db.lua
  32. 8 0
      testes/errors.lua
  33. 30 20
      testes/main.lua

+ 66 - 38
lcode.c

@@ -415,7 +415,7 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
 /*
 /*
 ** Format and emit an 'iAsBx' instruction.
 ** Format and emit an 'iAsBx' instruction.
 */
 */
-int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) {
+static int codeAsBx (FuncState *fs, OpCode o, int a, int bc) {
   unsigned int b = bc + OFFSET_sBx;
   unsigned int b = bc + OFFSET_sBx;
   lua_assert(getOpMode(o) == iAsBx);
   lua_assert(getOpMode(o) == iAsBx);
   lua_assert(a <= MAXARG_A && b <= MAXARG_Bx);
   lua_assert(a <= MAXARG_A && b <= MAXARG_Bx);
@@ -671,7 +671,7 @@ static int fitsBx (lua_Integer i) {
 
 
 void luaK_int (FuncState *fs, int reg, lua_Integer i) {
 void luaK_int (FuncState *fs, int reg, lua_Integer i) {
   if (fitsBx(i))
   if (fitsBx(i))
-    luaK_codeAsBx(fs, OP_LOADI, reg, cast_int(i));
+    codeAsBx(fs, OP_LOADI, reg, cast_int(i));
   else
   else
     luaK_codek(fs, reg, luaK_intK(fs, i));
     luaK_codek(fs, reg, luaK_intK(fs, i));
 }
 }
@@ -680,7 +680,7 @@ void luaK_int (FuncState *fs, int reg, lua_Integer i) {
 static void luaK_float (FuncState *fs, int reg, lua_Number f) {
 static void luaK_float (FuncState *fs, int reg, lua_Number f) {
   lua_Integer fi;
   lua_Integer fi;
   if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi))
   if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi))
-    luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi));
+    codeAsBx(fs, OP_LOADF, reg, cast_int(fi));
   else
   else
     luaK_codek(fs, reg, luaK_numberK(fs, f));
     luaK_codek(fs, reg, luaK_numberK(fs, f));
 }
 }
@@ -1025,7 +1025,7 @@ static int luaK_exp2K (FuncState *fs, expdesc *e) {
 ** in the range of R/K indices).
 ** in the range of R/K indices).
 ** Returns 1 iff expression is K.
 ** Returns 1 iff expression is K.
 */
 */
-int luaK_exp2RK (FuncState *fs, expdesc *e) {
+static int exp2RK (FuncState *fs, expdesc *e) {
   if (luaK_exp2K(fs, e))
   if (luaK_exp2K(fs, e))
     return 1;
     return 1;
   else {  /* not a constant in the right range: put it in a register */
   else {  /* not a constant in the right range: put it in a register */
@@ -1037,7 +1037,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
 
 
 static void codeABRK (FuncState *fs, OpCode o, int a, int b,
 static void codeABRK (FuncState *fs, OpCode o, int a, int b,
                       expdesc *ec) {
                       expdesc *ec) {
-  int k = luaK_exp2RK(fs, ec);
+  int k = exp2RK(fs, ec);
   luaK_codeABCk(fs, o, a, b, ec->u.info, k);
   luaK_codeABCk(fs, o, a, b, ec->u.info, k);
 }
 }
 
 
@@ -1215,7 +1215,7 @@ static void codenot (FuncState *fs, expdesc *e) {
 
 
 
 
 /*
 /*
-** Check whether expression 'e' is a small literal string
+** Check whether expression 'e' is a short literal string
 */
 */
 static int isKstr (FuncState *fs, expdesc *e) {
 static int isKstr (FuncState *fs, expdesc *e) {
   return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B &&
   return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B &&
@@ -1225,7 +1225,7 @@ static int isKstr (FuncState *fs, expdesc *e) {
 /*
 /*
 ** Check whether expression 'e' is a literal integer.
 ** Check whether expression 'e' is a literal integer.
 */
 */
-int luaK_isKint (expdesc *e) {
+static int isKint (expdesc *e) {
   return (e->k == VKINT && !hasjumps(e));
   return (e->k == VKINT && !hasjumps(e));
 }
 }
 
 
@@ -1235,7 +1235,7 @@ int luaK_isKint (expdesc *e) {
 ** proper range to fit in register C
 ** proper range to fit in register C
 */
 */
 static int isCint (expdesc *e) {
 static int isCint (expdesc *e) {
-  return luaK_isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C));
+  return isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C));
 }
 }
 
 
 
 
@@ -1244,7 +1244,7 @@ static int isCint (expdesc *e) {
 ** proper range to fit in register sC
 ** proper range to fit in register sC
 */
 */
 static int isSCint (expdesc *e) {
 static int isSCint (expdesc *e) {
-  return luaK_isKint(e) && fitsC(e->u.ival);
+  return isKint(e) && fitsC(e->u.ival);
 }
 }
 
 
 
 
@@ -1283,15 +1283,16 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
   if (t->k == VUPVAL && !isKstr(fs, k))  /* upvalue indexed by non 'Kstr'? */
   if (t->k == VUPVAL && !isKstr(fs, k))  /* upvalue indexed by non 'Kstr'? */
     luaK_exp2anyreg(fs, t);  /* put it in a register */
     luaK_exp2anyreg(fs, t);  /* put it in a register */
   if (t->k == VUPVAL) {
   if (t->k == VUPVAL) {
+    lua_assert(isKstr(fs, k));
     t->u.ind.t = t->u.info;  /* upvalue index */
     t->u.ind.t = t->u.info;  /* upvalue index */
-    t->u.ind.idx = k->u.info;  /* literal string */
+    t->u.ind.idx = k->u.info;  /* literal short string */
     t->k = VINDEXUP;
     t->k = VINDEXUP;
   }
   }
   else {
   else {
     /* register index of the table */
     /* register index of the table */
     t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info;
     t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info;
     if (isKstr(fs, k)) {
     if (isKstr(fs, k)) {
-      t->u.ind.idx = k->u.info;  /* literal string */
+      t->u.ind.idx = k->u.info;  /* literal short string */
       t->k = VINDEXSTR;
       t->k = VINDEXSTR;
     }
     }
     else if (isCint(k)) {
     else if (isCint(k)) {
@@ -1351,6 +1352,35 @@ static int constfolding (FuncState *fs, int op, expdesc *e1,
 }
 }
 
 
 
 
+/*
+** Convert a BinOpr to an OpCode  (ORDER OPR - ORDER OP)
+*/
+l_sinline OpCode binopr2op (BinOpr opr, BinOpr baser, OpCode base) {
+  lua_assert(baser <= opr &&
+            ((baser == OPR_ADD && opr <= OPR_SHR) ||
+             (baser == OPR_LT && opr <= OPR_LE)));
+  return cast(OpCode, (cast_int(opr) - cast_int(baser)) + cast_int(base));
+}
+
+
+/*
+** Convert a UnOpr to an OpCode  (ORDER OPR - ORDER OP)
+*/
+l_sinline OpCode unopr2op (UnOpr opr) {
+  return cast(OpCode, (cast_int(opr) - cast_int(OPR_MINUS)) +
+                                       cast_int(OP_UNM));
+}
+
+
+/*
+** Convert a BinOpr to a tag method  (ORDER OPR - ORDER TM)
+*/
+l_sinline TMS binopr2TM (BinOpr opr) {
+  lua_assert(OPR_ADD <= opr && opr <= OPR_SHR);
+  return cast(TMS, (cast_int(opr) - cast_int(OPR_ADD)) + cast_int(TM_ADD));
+}
+
+
 /*
 /*
 ** Emit code for unary expressions that "produce values"
 ** Emit code for unary expressions that "produce values"
 ** (everything but 'not').
 ** (everything but 'not').
@@ -1389,15 +1419,15 @@ static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
 ** Emit code for binary expressions that "produce values" over
 ** Emit code for binary expressions that "produce values" over
 ** two registers.
 ** two registers.
 */
 */
-static void codebinexpval (FuncState *fs, OpCode op,
+static void codebinexpval (FuncState *fs, BinOpr opr,
                            expdesc *e1, expdesc *e2, int line) {
                            expdesc *e1, expdesc *e2, int line) {
+  OpCode op = binopr2op(opr, OPR_ADD, OP_ADD);
   int v2 = luaK_exp2anyreg(fs, e2);  /* make sure 'e2' is in a register */
   int v2 = luaK_exp2anyreg(fs, e2);  /* make sure 'e2' is in a register */
   /* 'e1' must be already in a register or it is a constant */
   /* 'e1' must be already in a register or it is a constant */
   lua_assert((VNIL <= e1->k && e1->k <= VKSTR) ||
   lua_assert((VNIL <= e1->k && e1->k <= VKSTR) ||
              e1->k == VNONRELOC || e1->k == VRELOC);
              e1->k == VNONRELOC || e1->k == VRELOC);
   lua_assert(OP_ADD <= op && op <= OP_SHR);
   lua_assert(OP_ADD <= op && op <= OP_SHR);
-  finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN,
-                  cast(TMS, (op - OP_ADD) + TM_ADD));
+  finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN, binopr2TM(opr));
 }
 }
 
 
 
 
@@ -1418,9 +1448,9 @@ static void codebini (FuncState *fs, OpCode op,
 */
 */
 static void codebinK (FuncState *fs, BinOpr opr,
 static void codebinK (FuncState *fs, BinOpr opr,
                       expdesc *e1, expdesc *e2, int flip, int line) {
                       expdesc *e1, expdesc *e2, int flip, int line) {
-  TMS event = cast(TMS, opr + TM_ADD);
+  TMS event = binopr2TM(opr);
   int v2 = e2->u.info;  /* K index */
   int v2 = e2->u.info;  /* K index */
-  OpCode op = cast(OpCode, opr + OP_ADDK);
+  OpCode op = binopr2op(opr, OPR_ADD, OP_ADDK);
   finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event);
   finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event);
 }
 }
 
 
@@ -1430,7 +1460,7 @@ static void codebinK (FuncState *fs, BinOpr opr,
 */
 */
 static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2,
 static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2,
                              OpCode op, int line, TMS event) {
                              OpCode op, int line, TMS event) {
-  if (!luaK_isKint(e2))
+  if (!isKint(e2))
     return 0;  /* not an integer constant */
     return 0;  /* not an integer constant */
   else {
   else {
     lua_Integer i2 = e2->u.ival;
     lua_Integer i2 = e2->u.ival;
@@ -1457,10 +1487,9 @@ static void swapexps (expdesc *e1, expdesc *e2) {
 */
 */
 static void codebinNoK (FuncState *fs, BinOpr opr,
 static void codebinNoK (FuncState *fs, BinOpr opr,
                         expdesc *e1, expdesc *e2, int flip, int line) {
                         expdesc *e1, expdesc *e2, int flip, int line) {
-  OpCode op = cast(OpCode, opr + OP_ADD);
   if (flip)
   if (flip)
     swapexps(e1, e2);  /* back to original order */
     swapexps(e1, e2);  /* back to original order */
-  codebinexpval(fs, op, e1, e2, line);  /* use standard operators */
+  codebinexpval(fs, opr, e1, e2, line);  /* use standard operators */
 }
 }
 
 
 
 
@@ -1490,7 +1519,7 @@ static void codecommutative (FuncState *fs, BinOpr op,
     flip = 1;
     flip = 1;
   }
   }
   if (op == OPR_ADD && isSCint(e2))  /* immediate operand? */
   if (op == OPR_ADD && isSCint(e2))  /* immediate operand? */
-    codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD);
+    codebini(fs, OP_ADDI, e1, e2, flip, line, TM_ADD);
   else
   else
     codearith(fs, op, e1, e2, flip, line);
     codearith(fs, op, e1, e2, flip, line);
 }
 }
@@ -1518,25 +1547,27 @@ static void codebitwise (FuncState *fs, BinOpr opr,
 ** Emit code for order comparisons. When using an immediate operand,
 ** Emit code for order comparisons. When using an immediate operand,
 ** 'isfloat' tells whether the original value was a float.
 ** 'isfloat' tells whether the original value was a float.
 */
 */
-static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
+static void codeorder (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
   int r1, r2;
   int r1, r2;
   int im;
   int im;
   int isfloat = 0;
   int isfloat = 0;
+  OpCode op;
   if (isSCnumber(e2, &im, &isfloat)) {
   if (isSCnumber(e2, &im, &isfloat)) {
     /* use immediate operand */
     /* use immediate operand */
     r1 = luaK_exp2anyreg(fs, e1);
     r1 = luaK_exp2anyreg(fs, e1);
     r2 = im;
     r2 = im;
-    op = cast(OpCode, (op - OP_LT) + OP_LTI);
+    op = binopr2op(opr, OPR_LT, OP_LTI);
   }
   }
   else if (isSCnumber(e1, &im, &isfloat)) {
   else if (isSCnumber(e1, &im, &isfloat)) {
     /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
     /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
     r1 = luaK_exp2anyreg(fs, e2);
     r1 = luaK_exp2anyreg(fs, e2);
     r2 = im;
     r2 = im;
-    op = (op == OP_LT) ? OP_GTI : OP_GEI;
+    op = binopr2op(opr, OPR_LT, OP_GTI);
   }
   }
   else {  /* regular case, compare two registers */
   else {  /* regular case, compare two registers */
     r1 = luaK_exp2anyreg(fs, e1);
     r1 = luaK_exp2anyreg(fs, e1);
     r2 = luaK_exp2anyreg(fs, e2);
     r2 = luaK_exp2anyreg(fs, e2);
+    op = binopr2op(opr, OPR_LT, OP_LT);
   }
   }
   freeexps(fs, e1, e2);
   freeexps(fs, e1, e2);
   e1->u.info = condjump(fs, op, r1, r2, isfloat, 1);
   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) {
     op = OP_EQI;
     op = OP_EQI;
     r2 = im;  /* immediate operand */
     r2 = im;  /* immediate operand */
   }
   }
-  else if (luaK_exp2RK(fs, e2)) {  /* 2nd expression is constant? */
+  else if (exp2RK(fs, e2)) {  /* 2nd expression is constant? */
     op = OP_EQK;
     op = OP_EQK;
     r2 = e2->u.info;  /* constant index */
     r2 = e2->u.info;  /* constant index */
   }
   }
@@ -1579,16 +1610,16 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
 /*
 /*
 ** Apply prefix operation 'op' to expression 'e'.
 ** Apply prefix operation 'op' to expression 'e'.
 */
 */
-void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
+void luaK_prefix (FuncState *fs, UnOpr opr, expdesc *e, int line) {
   static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
   static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
   luaK_dischargevars(fs, e);
   luaK_dischargevars(fs, e);
-  switch (op) {
+  switch (opr) {
     case OPR_MINUS: case OPR_BNOT:  /* use 'ef' as fake 2nd operand */
     case OPR_MINUS: case OPR_BNOT:  /* use 'ef' as fake 2nd operand */
-      if (constfolding(fs, op + LUA_OPUNM, e, &ef))
+      if (constfolding(fs, opr + LUA_OPUNM, e, &ef))
         break;
         break;
       /* else */ /* FALLTHROUGH */
       /* else */ /* FALLTHROUGH */
     case OPR_LEN:
     case OPR_LEN:
-      codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line);
+      codeunexpval(fs, unopr2op(opr), e, line);
       break;
       break;
     case OPR_NOT: codenot(fs, e); break;
     case OPR_NOT: codenot(fs, e); break;
     default: lua_assert(0);
     default: lua_assert(0);
@@ -1628,7 +1659,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
     }
     }
     case OPR_EQ: case OPR_NE: {
     case OPR_EQ: case OPR_NE: {
       if (!tonumeral(v, NULL))
       if (!tonumeral(v, NULL))
-        luaK_exp2RK(fs, v);
+        exp2RK(fs, v);
       /* else keep numeral, which may be an immediate operand */
       /* else keep numeral, which may be an immediate operand */
       break;
       break;
     }
     }
@@ -1718,30 +1749,27 @@ void luaK_posfix (FuncState *fs, BinOpr opr,
         /* coded as (r1 >> -I) */;
         /* coded as (r1 >> -I) */;
       }
       }
       else  /* regular case (two registers) */
       else  /* regular case (two registers) */
-       codebinexpval(fs, OP_SHL, e1, e2, line);
+       codebinexpval(fs, opr, e1, e2, line);
       break;
       break;
     }
     }
     case OPR_SHR: {
     case OPR_SHR: {
       if (isSCint(e2))
       if (isSCint(e2))
         codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR);  /* r1 >> I */
         codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR);  /* r1 >> I */
       else  /* regular case (two registers) */
       else  /* regular case (two registers) */
-        codebinexpval(fs, OP_SHR, e1, e2, line);
+        codebinexpval(fs, opr, e1, e2, line);
       break;
       break;
     }
     }
     case OPR_EQ: case OPR_NE: {
     case OPR_EQ: case OPR_NE: {
       codeeq(fs, opr, e1, e2);
       codeeq(fs, opr, e1, e2);
       break;
       break;
     }
     }
-    case OPR_LT: case OPR_LE: {
-      OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
-      codeorder(fs, op, e1, e2);
-      break;
-    }
     case OPR_GT: case OPR_GE: {
     case OPR_GT: case OPR_GE: {
       /* '(a > b)' <=> '(b < a)';  '(a >= b)' <=> '(b <= a)' */
       /* '(a > b)' <=> '(b < a)';  '(a >= b)' <=> '(b <= a)' */
-      OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
       swapexps(e1, e2);
       swapexps(e1, e2);
-      codeorder(fs, op, e1, e2);
+      opr = cast(BinOpr, (opr - OPR_GT) + OPR_LT);
+    }  /* FALLTHROUGH */
+    case OPR_LT: case OPR_LE: {
+      codeorder(fs, opr, e1, e2);
       break;
       break;
     }
     }
     default: lua_assert(0);
     default: lua_assert(0);

+ 0 - 3
lcode.h

@@ -61,10 +61,8 @@ typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
 
 
 LUAI_FUNC int luaK_code (FuncState *fs, Instruction i);
 LUAI_FUNC int luaK_code (FuncState *fs, Instruction i);
 LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
 LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
-LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx);
 LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A,
 LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A,
                                             int B, int C, int k);
                                             int B, int C, int k);
-LUAI_FUNC int luaK_isKint (expdesc *e);
 LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v);
 LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v);
 LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
 LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
 LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
 LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
@@ -76,7 +74,6 @@ LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
-LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
 LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
 LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
 LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
 LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
 LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);

+ 2 - 2
lcorolib.c

@@ -76,7 +76,7 @@ static int luaB_auxwrap (lua_State *L) {
   if (l_unlikely(r < 0)) {  /* error? */
   if (l_unlikely(r < 0)) {  /* error? */
     int stat = lua_status(co);
     int stat = lua_status(co);
     if (stat != LUA_OK && stat != LUA_YIELD) {  /* error in the coroutine? */
     if (stat != LUA_OK && stat != LUA_YIELD) {  /* error in the coroutine? */
-      stat = lua_resetthread(co, L);  /* close its tbc variables */
+      stat = lua_closethread(co, L);  /* close its tbc variables */
       lua_assert(stat != LUA_OK);
       lua_assert(stat != LUA_OK);
       lua_xmove(co, L, 1);  /* move error message to the caller */
       lua_xmove(co, L, 1);  /* move error message to the caller */
     }
     }
@@ -172,7 +172,7 @@ static int luaB_close (lua_State *L) {
   int status = auxstatus(L, co);
   int status = auxstatus(L, co);
   switch (status) {
   switch (status) {
     case COS_DEAD: case COS_YIELD: {
     case COS_DEAD: case COS_YIELD: {
-      status = lua_resetthread(co, L);
+      status = lua_closethread(co, L);
       if (status == LUA_OK) {
       if (status == LUA_OK) {
         lua_pushboolean(L, 1);
         lua_pushboolean(L, 1);
         return 1;
         return 1;

+ 17 - 14
ldebug.c

@@ -656,18 +656,19 @@ static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
 
 
 
 
 /*
 /*
-** Check whether pointer 'o' points to some value in the stack
-** frame of the current function. Because 'o' may not point to a
-** value in this stack, we cannot compare it with the region
-** boundaries (undefined behaviour in ISO C).
+** Check whether pointer 'o' points to some value in the stack frame of
+** the current function and, if so, returns its index.  Because 'o' may
+** not point to a value in this stack, we cannot compare it with the
+** region boundaries (undefined behavior in ISO C).
 */
 */
-static int isinstack (CallInfo *ci, const TValue *o) {
-  StkId pos;
-  for (pos = ci->func.p + 1; pos < ci->top.p; pos++) {
-    if (o == s2v(pos))
-      return 1;
+static int instack (CallInfo *ci, const TValue *o) {
+  int pos;
+  StkId base = ci->func.p + 1;
+  for (pos = 0; base + pos < ci->top.p; pos++) {
+    if (o == s2v(base + pos))
+      return pos;
   }
   }
-  return 0;  /* not found */
+  return -1;  /* not found */
 }
 }
 
 
 
 
@@ -708,9 +709,11 @@ static const char *varinfo (lua_State *L, const TValue *o) {
   const char *kind = NULL;
   const char *kind = NULL;
   if (isLua(ci)) {
   if (isLua(ci)) {
     kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
     kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
-    if (!kind && isinstack(ci, o))  /* no? try a register */
-      kind = getobjname(ci_func(ci)->p, currentpc(ci),
-                        cast_int(cast(StkId, o) - (ci->func.p + 1)), &name);
+    if (!kind) {  /* not an upvalue? */
+      int reg = instack(ci, o);  /* try a register */
+      if (reg >= 0)  /* is 'o' a register? */
+        kind = getobjname(ci_func(ci)->p, currentpc(ci), reg, &name);
+    }
   }
   }
   return formatvarinfo(L, kind, name);
   return formatvarinfo(L, kind, name);
 }
 }
@@ -845,7 +848,7 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
   if (p->lineinfo == NULL)  /* no debug information? */
   if (p->lineinfo == NULL)  /* no debug information? */
     return 0;
     return 0;
   if (newpc - oldpc < MAXIWTHABS / 2) {  /* not too far apart? */
   if (newpc - oldpc < MAXIWTHABS / 2) {  /* not too far apart? */
-    int delta = 0;  /* line diference */
+    int delta = 0;  /* line difference */
     int pc = oldpc;
     int pc = oldpc;
     for (;;) {
     for (;;) {
       int lineinfo = p->lineinfo[++pc];
       int lineinfo = p->lineinfo[++pc];

+ 8 - 12
ldo.c

@@ -299,17 +299,13 @@ static int stackinuse (lua_State *L) {
 */
 */
 void luaD_shrinkstack (lua_State *L) {
 void luaD_shrinkstack (lua_State *L) {
   int inuse = stackinuse(L);
   int inuse = stackinuse(L);
-  int nsize = inuse * 2;  /* proposed new size */
-  int max = inuse * 3;  /* maximum "reasonable" size */
-  if (max > LUAI_MAXSTACK) {
-    max = LUAI_MAXSTACK;  /* respect stack limit */
-    if (nsize > LUAI_MAXSTACK)
-      nsize = LUAI_MAXSTACK;
-  }
+  int max = (inuse > LUAI_MAXSTACK / 3) ? LUAI_MAXSTACK : inuse * 3;
   /* if thread is currently not handling a stack overflow and its
   /* if thread is currently not handling a stack overflow and its
      size is larger than maximum "reasonable" size, shrink it */
      size is larger than maximum "reasonable" size, shrink it */
-  if (inuse <= LUAI_MAXSTACK && stacksize(L) > max)
+  if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) {
+    int nsize = (inuse > LUAI_MAXSTACK / 2) ? LUAI_MAXSTACK : inuse * 2;
     luaD_reallocstack(L, nsize, 0);  /* ok if that fails */
     luaD_reallocstack(L, nsize, 0);  /* ok if that fails */
+  }
   else  /* don't change stack */
   else  /* don't change stack */
     condmovestack(L,{},{});  /* (change only for debugging) */
     condmovestack(L,{},{});  /* (change only for debugging) */
   luaE_shrinkCI(L);  /* shrink CI list */
   luaE_shrinkCI(L);  /* shrink CI list */
@@ -413,7 +409,7 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
 ** stack, below original 'func', so that 'luaD_precall' can call it. Raise
 ** stack, below original 'func', so that 'luaD_precall' can call it. Raise
 ** an error if there is no '__call' metafield.
 ** an error if there is no '__call' metafield.
 */
 */
-StkId luaD_tryfuncTM (lua_State *L, StkId func) {
+static StkId tryfuncTM (lua_State *L, StkId func) {
   const TValue *tm;
   const TValue *tm;
   StkId p;
   StkId p;
   checkstackp(L, 1, func);  /* space for metamethod */
   checkstackp(L, 1, func);  /* space for metamethod */
@@ -572,7 +568,7 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
       return -1;
       return -1;
     }
     }
     default: {  /* not a function */
     default: {  /* not a function */
-      func = luaD_tryfuncTM(L, func);  /* try to get '__call' metamethod */
+      func = tryfuncTM(L, func);  /* try to get '__call' metamethod */
       /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */
       /* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */
       narg1++;
       narg1++;
       goto retry;  /* try again */
       goto retry;  /* try again */
@@ -613,7 +609,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
       return ci;
       return ci;
     }
     }
     default: {  /* not a function */
     default: {  /* not a function */
-      func = luaD_tryfuncTM(L, func);  /* try to get '__call' metamethod */
+      func = tryfuncTM(L, func);  /* try to get '__call' metamethod */
       /* return luaD_precall(L, func, nresults); */
       /* return luaD_precall(L, func, nresults); */
       goto retry;  /* try again with metamethod */
       goto retry;  /* try again with metamethod */
     }
     }
@@ -629,7 +625,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
 ** check the stack before doing anything else. 'luaD_precall' already
 ** check the stack before doing anything else. 'luaD_precall' already
 ** does that.
 ** does that.
 */
 */
-l_sinline void ccall (lua_State *L, StkId func, int nResults, int inc) {
+l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 inc) {
   CallInfo *ci;
   CallInfo *ci;
   L->nCcalls += inc;
   L->nCcalls += inc;
   if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) {
   if (l_unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) {

+ 0 - 1
ldo.h

@@ -59,7 +59,6 @@ LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
 LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
 LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
 LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
 LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
 LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
 LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
-LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func);
 LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status);
 LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status);
 LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
 LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
                                         ptrdiff_t oldtop, ptrdiff_t ef);
                                         ptrdiff_t oldtop, ptrdiff_t ef);

+ 6 - 2
ldump.c

@@ -10,6 +10,7 @@
 #include "lprefix.h"
 #include "lprefix.h"
 
 
 
 
+#include <limits.h>
 #include <stddef.h>
 #include <stddef.h>
 
 
 #include "lua.h"
 #include "lua.h"
@@ -59,8 +60,11 @@ static void dumpByte (DumpState *D, int y) {
 }
 }
 
 
 
 
-/* dumpInt Buff Size */
-#define DIBS    ((sizeof(size_t) * 8 / 7) + 1)
+/*
+** 'dumpSize' buffer size: each byte can store up to 7 bits. (The "+6"
+** rounds up the division.)
+*/
+#define DIBS    ((sizeof(size_t) * CHAR_BIT + 6) / 7)
 
 
 static void dumpSize (DumpState *D, size_t x) {
 static void dumpSize (DumpState *D, size_t x) {
   lu_byte buff[DIBS];
   lu_byte buff[DIBS];

+ 1 - 1
llex.c

@@ -128,7 +128,7 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
 ** ensuring there is only one copy of each unique string.  The table
 ** ensuring there is only one copy of each unique string.  The table
 ** here is used as a set: the string enters as the key, while its value
 ** here is used as a set: the string enters as the key, while its value
 ** is irrelevant. We use the string itself as the value only because it
 ** is irrelevant. We use the string itself as the value only because it
-** is a TValue readly available. Later, the code generation can change
+** is a TValue readily available. Later, the code generation can change
 ** this value.
 ** this value.
 */
 */
 TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
 TString *luaX_newstring (LexState *ls, const char *str, size_t l) {

+ 1 - 1
llimits.h

@@ -81,7 +81,7 @@ typedef signed char ls_byte;
 #if defined(UINTPTR_MAX)  /* even in C99 this type is optional */
 #if defined(UINTPTR_MAX)  /* even in C99 this type is optional */
 #define L_P2I	uintptr_t
 #define L_P2I	uintptr_t
 #else  /* no 'intptr'? */
 #else  /* no 'intptr'? */
-#define L_P2I	uintmax_t  /* use the largerst available integer */
+#define L_P2I	uintmax_t  /* use the largest available integer */
 #endif
 #endif
 #else  /* C89 option */
 #else  /* C89 option */
 #define L_P2I	size_t
 #define L_P2I	size_t

+ 0 - 9
loadlib.c

@@ -24,15 +24,6 @@
 #include "lualib.h"
 #include "lualib.h"
 
 
 
 
-/*
-** LUA_IGMARK is a mark to ignore all before it when building the
-** luaopen_ function name.
-*/
-#if !defined (LUA_IGMARK)
-#define LUA_IGMARK		"-"
-#endif
-
-
 /*
 /*
 ** LUA_CSUBSEP is the character that replaces dots in submodule names
 ** LUA_CSUBSEP is the character that replaces dots in submodule names
 ** when searching for a C loader.
 ** when searching for a C loader.

+ 5 - 5
lopcodes.h

@@ -21,7 +21,7 @@ iABC          C(8)     |      B(8)     |k|     A(8)      |   Op(7)     |
 iABx                Bx(17)               |     A(8)      |   Op(7)     |
 iABx                Bx(17)               |     A(8)      |   Op(7)     |
 iAsBx              sBx (signed)(17)      |     A(8)      |   Op(7)     |
 iAsBx              sBx (signed)(17)      |     A(8)      |   Op(7)     |
 iAx                           Ax(25)                     |   Op(7)     |
 iAx                           Ax(25)                     |   Op(7)     |
-isJ                           sJ(25)                     |   Op(7)     |
+isJ                           sJ (signed)(25)            |   Op(7)     |
 
 
   A signed argument is represented in excess K: the represented value is
   A signed argument is represented in excess K: the represented value is
   the written unsigned value minus K, where K is half the maximum for the
   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		*/
 OP_GETUPVAL,/*	A B	R[A] := UpValue[B]				*/
 OP_GETUPVAL,/*	A B	R[A] := UpValue[B]				*/
 OP_SETUPVAL,/*	A B	UpValue[B] := R[A]				*/
 OP_SETUPVAL,/*	A B	UpValue[B] := R[A]				*/
 
 
-OP_GETTABUP,/*	A B C	R[A] := UpValue[B][K[C]:string]			*/
+OP_GETTABUP,/*	A B C	R[A] := UpValue[B][K[C]:shortstring]		*/
 OP_GETTABLE,/*	A B C	R[A] := R[B][R[C]]				*/
 OP_GETTABLE,/*	A B C	R[A] := R[B][R[C]]				*/
 OP_GETI,/*	A B C	R[A] := R[B][C]					*/
 OP_GETI,/*	A B C	R[A] := R[B][C]					*/
-OP_GETFIELD,/*	A B C	R[A] := R[B][K[C]:string]			*/
+OP_GETFIELD,/*	A B C	R[A] := R[B][K[C]:shortstring]			*/
 
 
-OP_SETTABUP,/*	A B C	UpValue[A][K[B]:string] := RK(C)		*/
+OP_SETTABUP,/*	A B C	UpValue[A][K[B]:shortstring] := RK(C)		*/
 OP_SETTABLE,/*	A B C	R[A][R[B]] := RK(C)				*/
 OP_SETTABLE,/*	A B C	R[A][R[B]] := RK(C)				*/
 OP_SETI,/*	A B C	R[A][B] := RK(C)				*/
 OP_SETI,/*	A B C	R[A][B] := RK(C)				*/
-OP_SETFIELD,/*	A B C	R[A][K[B]:string] := RK(C)			*/
+OP_SETFIELD,/*	A B C	R[A][K[B]:shortstring] := RK(C)			*/
 
 
 OP_NEWTABLE,/*	A B C k	R[A] := {}					*/
 OP_NEWTABLE,/*	A B C k	R[A] := {}					*/
 
 

+ 6 - 15
loslib.c

@@ -30,23 +30,14 @@
 */
 */
 #if !defined(LUA_STRFTIMEOPTIONS)	/* { */
 #if !defined(LUA_STRFTIMEOPTIONS)	/* { */
 
 
-/* options for ANSI C 89 (only 1-char options) */
-#define L_STRFTIMEC89		"aAbBcdHIjmMpSUwWxXyYZ%"
-
-/* options for ISO C 99 and POSIX */
-#define L_STRFTIMEC99 "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
-    "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy"  /* two-char options */
-
-/* options for Windows */
-#define L_STRFTIMEWIN "aAbBcdHIjmMpSUwWxXyYzZ%" \
-    "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"  /* two-char options */
-
 #if defined(LUA_USE_WINDOWS)
 #if defined(LUA_USE_WINDOWS)
-#define LUA_STRFTIMEOPTIONS	L_STRFTIMEWIN
-#elif defined(LUA_USE_C89)
-#define LUA_STRFTIMEOPTIONS	L_STRFTIMEC89
+#define LUA_STRFTIMEOPTIONS  "aAbBcdHIjmMpSUwWxXyYzZ%" \
+    "||" "#c#x#d#H#I#j#m#M#S#U#w#W#y#Y"  /* two-char options */
+#elif defined(LUA_USE_C89)  /* ANSI C 89 (only 1-char options) */
+#define LUA_STRFTIMEOPTIONS  "aAbBcdHIjmMpSUwWxXyYZ%"
 #else  /* C99 specification */
 #else  /* C99 specification */
-#define LUA_STRFTIMEOPTIONS	L_STRFTIMEC99
+#define LUA_STRFTIMEOPTIONS  "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%" \
+    "||" "EcECExEXEyEY" "OdOeOHOIOmOMOSOuOUOVOwOWOy"  /* two-char options */
 #endif
 #endif
 
 
 #endif					/* } */
 #endif					/* } */

+ 4 - 4
lparser.c

@@ -529,12 +529,12 @@ static l_noret jumpscopeerror (LexState *ls, Labeldesc *gt) {
 
 
 /*
 /*
 ** Solves the goto at index 'g' to given 'label' and removes it
 ** Solves the goto at index 'g' to given 'label' and removes it
-** from the list of pending goto's.
+** from the list of pending gotos.
 ** If it jumps into the scope of some variable, raises an error.
 ** If it jumps into the scope of some variable, raises an error.
 */
 */
 static void solvegoto (LexState *ls, int g, Labeldesc *label) {
 static void solvegoto (LexState *ls, int g, Labeldesc *label) {
   int i;
   int i;
-  Labellist *gl = &ls->dyd->gt;  /* list of goto's */
+  Labellist *gl = &ls->dyd->gt;  /* list of gotos */
   Labeldesc *gt = &gl->arr[g];  /* goto to be resolved */
   Labeldesc *gt = &gl->arr[g];  /* goto to be resolved */
   lua_assert(eqstr(gt->name, label->name));
   lua_assert(eqstr(gt->name, label->name));
   if (l_unlikely(gt->nactvar < label->nactvar))  /* enter some scope? */
   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) {
 /*
 /*
 ** Solves forward jumps. Check whether new label 'lb' matches any
 ** Solves forward jumps. Check whether new label 'lb' matches any
 ** pending gotos in current block and solves them. Return true
 ** pending gotos in current block and solves them. Return true
-** if any of the goto's need to close upvalues.
+** if any of the gotos need to close upvalues.
 */
 */
 static int solvegotos (LexState *ls, Labeldesc *lb) {
 static int solvegotos (LexState *ls, Labeldesc *lb) {
   Labellist *gl = &ls->dyd->gt;
   Labellist *gl = &ls->dyd->gt;
@@ -609,7 +609,7 @@ static int solvegotos (LexState *ls, Labeldesc *lb) {
 /*
 /*
 ** Create a new label with the given 'name' at the given 'line'.
 ** Create a new label with the given 'name' at the given 'line'.
 ** 'last' tells whether label is the last non-op statement in its
 ** 'last' tells whether label is the last non-op statement in its
-** block. Solves all pending goto's to this new label and adds
+** block. Solves all pending gotos to this new label and adds
 ** a close instruction if necessary.
 ** a close instruction if necessary.
 ** Returns true iff it added a close instruction.
 ** Returns true iff it added a close instruction.
 */
 */

+ 3 - 3
lstate.c

@@ -88,7 +88,7 @@ CallInfo *luaE_extendCI (lua_State *L) {
 /*
 /*
 ** free all CallInfo structures not in use by a thread
 ** free all CallInfo structures not in use by a thread
 */
 */
-void luaE_freeCI (lua_State *L) {
+static void freeCI (lua_State *L) {
   CallInfo *ci = L->ci;
   CallInfo *ci = L->ci;
   CallInfo *next = ci->next;
   CallInfo *next = ci->next;
   ci->next = NULL;
   ci->next = NULL;
@@ -173,7 +173,7 @@ static void freestack (lua_State *L) {
   if (L->stack.p == NULL)
   if (L->stack.p == NULL)
     return;  /* stack not completely built yet */
     return;  /* stack not completely built yet */
   L->ci = &L->base_ci;  /* free the entire 'ci' list */
   L->ci = &L->base_ci;  /* free the entire 'ci' list */
-  luaE_freeCI(L);
+  freeCI(L);
   lua_assert(L->nci == 0);
   lua_assert(L->nci == 0);
   luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK);  /* free stack */
   luaM_freearray(L, L->stack.p, stacksize(L) + EXTRA_STACK);  /* free stack */
 }
 }
@@ -309,7 +309,7 @@ int luaE_resetthread (lua_State *L, int status) {
 }
 }
 
 
 
 
-LUA_API int lua_resetthread (lua_State *L, lua_State *from) {
+LUA_API int lua_closethread (lua_State *L, lua_State *from) {
   int status;
   int status;
   lua_lock(L);
   lua_lock(L);
   L->nCcalls = (from) ? getCcalls(from) : 0;
   L->nCcalls = (from) ? getCcalls(from) : 0;

+ 0 - 1
lstate.h

@@ -399,7 +399,6 @@ union GCUnion {
 LUAI_FUNC void luaE_setdebt (global_State *g, l_obj debt);
 LUAI_FUNC void luaE_setdebt (global_State *g, l_obj debt);
 LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
 LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
 LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
 LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
-LUAI_FUNC void luaE_freeCI (lua_State *L);
 LUAI_FUNC void luaE_shrinkCI (lua_State *L);
 LUAI_FUNC void luaE_shrinkCI (lua_State *L);
 LUAI_FUNC void luaE_checkcstack (lua_State *L);
 LUAI_FUNC void luaE_checkcstack (lua_State *L);
 LUAI_FUNC void luaE_incCstack (lua_State *L);
 LUAI_FUNC void luaE_incCstack (lua_State *L);

+ 1 - 1
lstrlib.c

@@ -571,7 +571,7 @@ static const char *match_capture (MatchState *ms, const char *s, int l) {
 static const char *match (MatchState *ms, const char *s, const char *p) {
 static const char *match (MatchState *ms, const char *s, const char *p) {
   if (l_unlikely(ms->matchdepth-- == 0))
   if (l_unlikely(ms->matchdepth-- == 0))
     luaL_error(ms->L, "pattern too complex");
     luaL_error(ms->L, "pattern too complex");
-  init: /* using goto's to optimize tail recursion */
+  init: /* using goto to optimize tail recursion */
   if (p != ms->p_end) {  /* end of pattern? */
   if (p != ms->p_end) {  /* end of pattern? */
     switch (*p) {
     switch (*p) {
       case '(': {  /* start capture */
       case '(': {  /* start capture */

+ 4 - 1
ltable.c

@@ -278,9 +278,11 @@ LUAI_FUNC unsigned int luaH_realasize (const Table *t) {
     size |= (size >> 2);
     size |= (size >> 2);
     size |= (size >> 4);
     size |= (size >> 4);
     size |= (size >> 8);
     size |= (size >> 8);
+#if (UINT_MAX >> 14) > 3  /* unsigned int has more than 16 bits */
     size |= (size >> 16);
     size |= (size >> 16);
 #if (UINT_MAX >> 30) > 3
 #if (UINT_MAX >> 30) > 3
     size |= (size >> 32);  /* unsigned int has more than 32 bits */
     size |= (size >> 32);  /* unsigned int has more than 32 bits */
+#endif
 #endif
 #endif
     size++;
     size++;
     lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size);
     lua_assert(ispow2(size) && size/2 < t->alimit && t->alimit < size);
@@ -710,7 +712,8 @@ static Node *getfreepos (Table *t) {
 ** put new key in its main position; otherwise (colliding node is in its main
 ** put new key in its main position; otherwise (colliding node is in its main
 ** position), new key goes to an empty position.
 ** position), new key goes to an empty position.
 */
 */
-void luaH_newkey (lua_State *L, Table *t, const TValue *key, TValue *value) {
+static void luaH_newkey (lua_State *L, Table *t, const TValue *key,
+                                                 TValue *value) {
   Node *mp;
   Node *mp;
   TValue aux;
   TValue aux;
   if (l_unlikely(ttisnil(key)))
   if (l_unlikely(ttisnil(key)))

+ 0 - 2
ltable.h

@@ -51,8 +51,6 @@ LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
 LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
 LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
 LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
 LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
 LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
 LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
-LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key,
-                                                    TValue *value);
 LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key,
 LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key,
                                                  TValue *value);
                                                  TValue *value);
 LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key,
 LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key,

+ 1 - 1
ltests.c

@@ -1526,7 +1526,7 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
       lua_newthread(L1);
       lua_newthread(L1);
     }
     }
     else if EQ("resetthread") {
     else if EQ("resetthread") {
-      lua_pushinteger(L1, lua_resetthread(L1, L));
+      lua_pushinteger(L1, lua_resetthread(L1));  /* deprecated */
     }
     }
     else if EQ("newuserdata") {
     else if EQ("newuserdata") {
       lua_newuserdata(L1, getnum);
       lua_newuserdata(L1, getnum);

+ 2 - 3
ltm.h

@@ -9,7 +9,6 @@
 
 
 
 
 #include "lobject.h"
 #include "lobject.h"
-#include "lstate.h"
 
 
 
 
 /*
 /*
@@ -96,8 +95,8 @@ LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2,
                                  int inv, int isfloat, TMS event);
                                  int inv, int isfloat, TMS event);
 
 
 LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams,
 LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams,
-                                   CallInfo *ci, const Proto *p);
-LUAI_FUNC void luaT_getvarargs (lua_State *L, CallInfo *ci,
+                                   struct CallInfo *ci, const Proto *p);
+LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci,
                                               StkId where, int wanted);
                                               StkId where, int wanted);
 
 
 
 

+ 11 - 3
lua.c

@@ -210,12 +210,17 @@ static int dostring (lua_State *L, const char *s, const char *name) {
 
 
 /*
 /*
 ** Receives 'globname[=modname]' and runs 'globname = require(modname)'.
 ** Receives 'globname[=modname]' and runs 'globname = require(modname)'.
+** If there is no explicit modname and globname contains a '-', cut
+** the sufix after '-' (the "version") to make the global name.
 */
 */
 static int dolibrary (lua_State *L, char *globname) {
 static int dolibrary (lua_State *L, char *globname) {
   int status;
   int status;
+  char *suffix = NULL;
   char *modname = strchr(globname, '=');
   char *modname = strchr(globname, '=');
-  if (modname == NULL)  /* no explicit name? */
+  if (modname == NULL) {  /* no explicit name? */
     modname = globname;  /* module name is equal to global name */
     modname = globname;  /* module name is equal to global name */
+    suffix = strchr(modname, *LUA_IGMARK);  /* look for a suffix mark */
+  }
   else {
   else {
     *modname = '\0';  /* global name ends here */
     *modname = '\0';  /* global name ends here */
     modname++;  /* module name starts after the '=' */
     modname++;  /* module name starts after the '=' */
@@ -223,8 +228,11 @@ static int dolibrary (lua_State *L, char *globname) {
   lua_getglobal(L, "require");
   lua_getglobal(L, "require");
   lua_pushstring(L, modname);
   lua_pushstring(L, modname);
   status = docall(L, 1, 1);  /* call 'require(modname)' */
   status = docall(L, 1, 1);  /* call 'require(modname)' */
-  if (status == LUA_OK)
+  if (status == LUA_OK) {
+    if (suffix != NULL)  /* is there a suffix mark? */
+      *suffix = '\0';  /* remove sufix from global name */
     lua_setglobal(L, globname);  /* globname = require(modname) */
     lua_setglobal(L, globname);  /* globname = require(modname) */
+  }
   return report(L, status);
   return report(L, status);
 }
 }
 
 
@@ -670,7 +678,7 @@ int main (int argc, char **argv) {
     l_message(argv[0], "cannot create state: not enough memory");
     l_message(argv[0], "cannot create state: not enough memory");
     return EXIT_FAILURE;
     return EXIT_FAILURE;
   }
   }
-  lua_gc(L, LUA_GCSTOP);  /* stop GC while buidling state */
+  lua_gc(L, LUA_GCSTOP);  /* stop GC while building state */
   lua_pushcfunction(L, &pmain);  /* to call 'pmain' in protected mode */
   lua_pushcfunction(L, &pmain);  /* to call 'pmain' in protected mode */
   lua_pushinteger(L, argc);  /* 1st argument */
   lua_pushinteger(L, argc);  /* 1st argument */
   lua_pushlightuserdata(L, argv); /* 2nd argument */
   lua_pushlightuserdata(L, argv); /* 2nd argument */

+ 25 - 13
lua.h

@@ -1,7 +1,7 @@
 /*
 /*
 ** $Id: lua.h $
 ** $Id: lua.h $
 ** Lua - A Scripting Language
 ** Lua - A Scripting Language
-** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
+** Lua.org, PUC-Rio, Brazil (www.lua.org)
 ** See Copyright Notice at the end of this file
 ** See Copyright Notice at the end of this file
 */
 */
 
 
@@ -13,20 +13,19 @@
 #include <stddef.h>
 #include <stddef.h>
 
 
 
 
-#include "luaconf.h"
+#define LUA_COPYRIGHT	LUA_RELEASE "  Copyright (C) 1994-2023 Lua.org, PUC-Rio"
+#define LUA_AUTHORS	"R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
 
 
 
 
-#define LUA_VERSION_MAJOR	"5"
-#define LUA_VERSION_MINOR	"5"
-#define LUA_VERSION_RELEASE	"0"
+#define LUA_VERSION_MAJOR_N	5
+#define LUA_VERSION_MINOR_N	5
+#define LUA_VERSION_RELEASE_N	0
 
 
-#define LUA_VERSION_NUM			505
-#define LUA_VERSION_RELEASE_NUM		(LUA_VERSION_NUM * 100 + 0)
+#define LUA_VERSION_NUM  (LUA_VERSION_MAJOR_N * 100 + LUA_VERSION_MINOR_N)
+#define LUA_VERSION_RELEASE_NUM  (LUA_VERSION_NUM * 100 + LUA_VERSION_RELEASE_N)
 
 
-#define LUA_VERSION	"Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
-#define LUA_RELEASE	LUA_VERSION "." LUA_VERSION_RELEASE
-#define LUA_COPYRIGHT	LUA_RELEASE "  Copyright (C) 1994-2022 Lua.org, PUC-Rio"
-#define LUA_AUTHORS	"R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
+
+#include "luaconf.h"
 
 
 
 
 /* mark for precompiled code ('<esc>Lua') */
 /* mark for precompiled code ('<esc>Lua') */
@@ -164,7 +163,7 @@ LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud,
                                    unsigned int seed);
                                    unsigned int seed);
 LUA_API void       (lua_close) (lua_State *L);
 LUA_API void       (lua_close) (lua_State *L);
 LUA_API lua_State *(lua_newthread) (lua_State *L);
 LUA_API lua_State *(lua_newthread) (lua_State *L);
-LUA_API int        (lua_resetthread) (lua_State *L, lua_State *from);
+LUA_API int        (lua_closethread) (lua_State *L, lua_State *from);
 
 
 LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
 LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
 
 
@@ -426,6 +425,8 @@ LUA_API void (lua_closeslot) (lua_State *L, int idx);
 
 
 #define LUA_NUMTAGS		LUA_NUMTYPES
 #define LUA_NUMTAGS		LUA_NUMTYPES
 
 
+#define lua_resetthread(L)	lua_closethread(L,NULL)
+
 /* }============================================================== */
 /* }============================================================== */
 
 
 /*
 /*
@@ -496,8 +497,19 @@ struct lua_Debug {
 /* }====================================================================== */
 /* }====================================================================== */
 
 
 
 
+#define LUAI_TOSTRAUX(x)	#x
+#define LUAI_TOSTR(x)		LUAI_TOSTRAUX(x)
+
+#define LUA_VERSION_MAJOR	LUAI_TOSTR(LUA_VERSION_MAJOR_N)
+#define LUA_VERSION_MINOR	LUAI_TOSTR(LUA_VERSION_MINOR_N)
+#define LUA_VERSION_RELEASE	LUAI_TOSTR(LUA_VERSION_RELEASE_N)
+
+#define LUA_VERSION	"Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#define LUA_RELEASE	LUA_VERSION "." LUA_VERSION_RELEASE
+
+
 /******************************************************************************
 /******************************************************************************
-* Copyright (C) 1994-2022 Lua.org, PUC-Rio.
+* Copyright (C) 1994-2023 Lua.org, PUC-Rio.
 *
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * a copy of this software and associated documentation files (the

+ 9 - 0
luaconf.h

@@ -257,6 +257,15 @@
 
 
 #endif
 #endif
 
 
+
+/*
+** LUA_IGMARK is a mark to ignore all after it when building the
+** module name (e.g., used to build the luaopen_ function name).
+** Typically, the sufix after the mark is the module version,
+** as in "mod-v1.2.so".
+*/
+#define LUA_IGMARK		"-"
+
 /* }================================================================== */
 /* }================================================================== */
 
 
 
 

+ 2 - 0
lundump.c

@@ -261,6 +261,8 @@ static void loadDebug (LoadState *S, Proto *f) {
     f->locvars[i].endpc = loadInt(S);
     f->locvars[i].endpc = loadInt(S);
   }
   }
   n = loadInt(S);
   n = loadInt(S);
+  if (n != 0)  /* does it have debug information? */
+    n = f->sizeupvalues;  /* must be this many */
   for (i = 0; i < n; i++)
   for (i = 0; i < n; i++)
     f->upvalues[i].name = loadStringN(S, f);
     f->upvalues[i].name = loadStringN(S, f);
 }
 }

+ 28 - 22
lvm.c

@@ -367,30 +367,32 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
 
 
 
 
 /*
 /*
-** Compare two strings 'ls' x 'rs', returning an integer less-equal-
-** -greater than zero if 'ls' is less-equal-greater than 'rs'.
+** Compare two strings 'ts1' x 'ts2', returning an integer less-equal-
+** -greater than zero if 'ts1' is less-equal-greater than 'ts2'.
 ** The code is a little tricky because it allows '\0' in the strings
 ** The code is a little tricky because it allows '\0' in the strings
-** and it uses 'strcoll' (to respect locales) for each segments
-** of the strings.
+** and it uses 'strcoll' (to respect locales) for each segment
+** of the strings. Note that segments can compare equal but still
+** have different lengths.
 */
 */
-static int l_strcmp (const TString *ls, const TString *rs) {
-  const char *l = getstr(ls);
-  size_t ll = tsslen(ls);
-  const char *r = getstr(rs);
-  size_t lr = tsslen(rs);
+static int l_strcmp (const TString *ts1, const TString *ts2) {
+  const char *s1 = getstr(ts1);
+  size_t rl1 = tsslen(ts1);  /* real length */
+  const char *s2 = getstr(ts2);
+  size_t rl2 = tsslen(ts2);
   for (;;) {  /* for each segment */
   for (;;) {  /* for each segment */
-    int temp = strcoll(l, r);
+    int temp = strcoll(s1, s2);
     if (temp != 0)  /* not equal? */
     if (temp != 0)  /* not equal? */
       return temp;  /* done */
       return temp;  /* done */
     else {  /* strings are equal up to a '\0' */
     else {  /* strings are equal up to a '\0' */
-      size_t len = strlen(l);  /* index of first '\0' in both strings */
-      if (len == lr)  /* 'rs' is finished? */
-        return (len == ll) ? 0 : 1;  /* check 'ls' */
-      else if (len == ll)  /* 'ls' is finished? */
-        return -1;  /* 'ls' is less than 'rs' ('rs' is not finished) */
-      /* both strings longer than 'len'; go on comparing after the '\0' */
-      len++;
-      l += len; ll -= len; r += len; lr -= len;
+      size_t zl1 = strlen(s1);  /* index of first '\0' in 's1' */
+      size_t zl2 = strlen(s2);  /* index of first '\0' in 's2' */
+      if (zl2 == rl2)  /* 's2' is finished? */
+        return (zl1 == rl1) ? 0 : 1;  /* check 's1' */
+      else if (zl1 == rl1)  /* 's1' is finished? */
+        return -1;  /* 's1' is less than 's2' ('s2' is not finished) */
+      /* both strings longer than 'zl'; go on comparing after the '\0' */
+      zl1++; zl2++;
+      s1 += zl1; rl1 -= zl1; s2 += zl2; rl2 -= zl2;
     }
     }
   }
   }
 }
 }
@@ -1254,7 +1256,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         const TValue *slot;
         const TValue *slot;
         TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
         TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
         TValue *rc = KC(i);
         TValue *rc = KC(i);
-        TString *key = tsvalue(rc);  /* key must be a string */
+        TString *key = tsvalue(rc);  /* key must be a short string */
         if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
         if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
           setobj2s(L, ra, slot);
           setobj2s(L, ra, slot);
         }
         }
@@ -1297,7 +1299,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         const TValue *slot;
         const TValue *slot;
         TValue *rb = vRB(i);
         TValue *rb = vRB(i);
         TValue *rc = KC(i);
         TValue *rc = KC(i);
-        TString *key = tsvalue(rc);  /* key must be a string */
+        TString *key = tsvalue(rc);  /* key must be a short string */
         if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) {
         if (luaV_fastget(L, rb, key, slot, luaH_getshortstr)) {
           setobj2s(L, ra, slot);
           setobj2s(L, ra, slot);
         }
         }
@@ -1310,7 +1312,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
         TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
         TValue *rb = KB(i);
         TValue *rb = KB(i);
         TValue *rc = RKC(i);
         TValue *rc = RKC(i);
-        TString *key = tsvalue(rb);  /* key must be a string */
+        TString *key = tsvalue(rb);  /* key must be a short string */
         if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
         if (luaV_fastget(L, upval, key, slot, luaH_getshortstr)) {
           luaV_finishfastset(L, upval, slot, rc);
           luaV_finishfastset(L, upval, slot, rc);
         }
         }
@@ -1353,7 +1355,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         const TValue *slot;
         const TValue *slot;
         TValue *rb = KB(i);
         TValue *rb = KB(i);
         TValue *rc = RKC(i);
         TValue *rc = RKC(i);
-        TString *key = tsvalue(rb);  /* key must be a string */
+        TString *key = tsvalue(rb);  /* key must be a short string */
         if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) {
         if (luaV_fastget(L, s2v(ra), key, slot, luaH_getshortstr)) {
           luaV_finishfastset(L, s2v(ra), slot, rc);
           luaV_finishfastset(L, s2v(ra), slot, rc);
         }
         }
@@ -1411,6 +1413,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         vmbreak;
         vmbreak;
       }
       }
       vmcase(OP_MODK) {
       vmcase(OP_MODK) {
+        savestate(L, ci);  /* in case of division by 0 */
         op_arithK(L, luaV_mod, luaV_modf);
         op_arithK(L, luaV_mod, luaV_modf);
         vmbreak;
         vmbreak;
       }
       }
@@ -1423,6 +1426,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         vmbreak;
         vmbreak;
       }
       }
       vmcase(OP_IDIVK) {
       vmcase(OP_IDIVK) {
+        savestate(L, ci);  /* in case of division by 0 */
         op_arithK(L, luaV_idiv, luai_numidiv);
         op_arithK(L, luaV_idiv, luai_numidiv);
         vmbreak;
         vmbreak;
       }
       }
@@ -1471,6 +1475,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         vmbreak;
         vmbreak;
       }
       }
       vmcase(OP_MOD) {
       vmcase(OP_MOD) {
+        savestate(L, ci);  /* in case of division by 0 */
         op_arith(L, luaV_mod, luaV_modf);
         op_arith(L, luaV_mod, luaV_modf);
         vmbreak;
         vmbreak;
       }
       }
@@ -1483,6 +1488,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
         vmbreak;
         vmbreak;
       }
       }
       vmcase(OP_IDIV) {  /* floor division */
       vmcase(OP_IDIV) {  /* floor division */
+        savestate(L, ci);  /* in case of division by 0 */
         op_arith(L, luaV_idiv, luai_numidiv);
         op_arith(L, luaV_idiv, luai_numidiv);
         vmbreak;
         vmbreak;
       }
       }

+ 1 - 2
makefile

@@ -8,7 +8,6 @@ CWARNSCPP= \
 	-Wfatal-errors \
 	-Wfatal-errors \
 	-Wextra \
 	-Wextra \
 	-Wshadow \
 	-Wshadow \
-	-Wsign-compare \
 	-Wundef \
 	-Wundef \
 	-Wwrite-strings \
 	-Wwrite-strings \
 	-Wredundant-decls \
 	-Wredundant-decls \
@@ -60,7 +59,7 @@ CWARNS= $(CWARNSCPP) $(CWARNSC) $(CWARNGCC)
 
 
 # The following options help detect "undefined behavior"s that seldom
 # The following options help detect "undefined behavior"s that seldom
 # create problems; some are only available in newer gcc versions. To
 # create problems; some are only available in newer gcc versions. To
-# use some of them, we also have to define an enrivonment variable
+# use some of them, we also have to define an environment variable
 # ASAN_OPTIONS="detect_invalid_pointer_pairs=2".
 # ASAN_OPTIONS="detect_invalid_pointer_pairs=2".
 # -fsanitize=undefined
 # -fsanitize=undefined
 # -fsanitize=pointer-subtract -fsanitize=address -fsanitize=pointer-compare
 # -fsanitize=pointer-subtract -fsanitize=address -fsanitize=pointer-compare

+ 1 - 1
manual/2html

@@ -30,7 +30,7 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
 <p>
 <p>
 <small>
 <small>
 <a href="http://www.lua.org/copyright.html">Copyright</a>
 <a href="http://www.lua.org/copyright.html">Copyright</a>
-&copy; 2022 Lua.org, PUC-Rio.  All rights reserved.
+&copy; 2023 Lua.org, PUC-Rio.  All rights reserved.
 </small>
 </small>
 <hr>
 <hr>
 
 

+ 31 - 21
manual/manual.of

@@ -20,7 +20,7 @@ making it ideal for configuration, scripting,
 and rapid prototyping.
 and rapid prototyping.
 
 
 Lua is implemented as a library, written in @emphx{clean C},
 Lua is implemented as a library, written in @emphx{clean C},
-the common subset of C and C++.
+the common subset of @N{standard C} and C++.
 The Lua distribution includes a host program called @id{lua},
 The Lua distribution includes a host program called @id{lua},
 which uses the Lua library to offer a complete,
 which uses the Lua library to offer a complete,
 standalone Lua interpreter,
 standalone Lua interpreter,
@@ -3161,6 +3161,27 @@ when called through this function.
 
 
 }
 }
 
 
+@APIEntry{int lua_closethread (lua_State *L, lua_State *from);|
+@apii{0,?,-}
+
+Resets a thread, cleaning its call stack and closing all pending
+to-be-closed variables.
+Returns a status code:
+@Lid{LUA_OK} for no errors in the thread
+(either the original error that stopped the thread or
+errors in closing methods),
+or an error status otherwise.
+In case of error,
+leaves the error object on the top of the stack.
+
+The parameter @id{from} represents the coroutine that is resetting @id{L}.
+If there is no such coroutine,
+this parameter can be @id{NULL}.
+
+(This function was introduced in @N{release 5.4.6}.)
+
+}
+
 @APIEntry{int lua_compare (lua_State *L, int index1, int index2, int op);|
 @APIEntry{int lua_compare (lua_State *L, int index1, int index2, int op);|
 @apii{0,0,e}
 @apii{0,0,e}
 
 
@@ -4157,23 +4178,12 @@ and then pops the top element.
 
 
 }
 }
 
 
-@APIEntry{int lua_resetthread (lua_State *L, lua_State *from);|
+@APIEntry{int lua_resetthread (lua_State *L);|
 @apii{0,?,-}
 @apii{0,?,-}
 
 
-Resets a thread, cleaning its call stack and closing all pending
-to-be-closed variables.
-Returns a status code:
-@Lid{LUA_OK} for no errors in the thread
-(either the original error that stopped the thread or
-errors in closing methods),
-or an error status otherwise.
-In case of error,
-leaves the error object on the top of the stack.
-
-The parameter @id{from} represents the coroutine that is resetting @id{L}.
-If there is no such coroutine,
-this parameter can be @id{NULL}.
-(This parameter was introduced in @N{release 5.4.5}.)
+This function is deprecated;
+it is equivalent to @Lid{lua_closethread} with
+@id{from} being @id{NULL}.
 
 
 }
 }
 
 
@@ -5787,7 +5797,7 @@ with @id{tname} in the registry.
 
 
 Creates a new Lua state.
 Creates a new Lua state.
 It calls @Lid{lua_newstate} with an
 It calls @Lid{lua_newstate} with an
-allocator based on the @N{standard C} allocation functions
+allocator based on the @N{ISO C} allocation functions
 and then sets a warning function and a panic function @see{C-error}
 and then sets a warning function and a panic function @see{C-error}
 that print messages to the standard error output.
 that print messages to the standard error output.
 
 
@@ -6905,10 +6915,10 @@ including if necessary a path and an extension.
 @id{funcname} must be the exact name exported by the @N{C library}
 @id{funcname} must be the exact name exported by the @N{C library}
 (which may depend on the @N{C compiler} and linker used).
 (which may depend on the @N{C compiler} and linker used).
 
 
-This function is not supported by @N{ISO C}.
-As such, it is only available on some platforms
-(Windows, Linux, Mac OS X, Solaris, BSD,
-plus other Unix systems that support the @id{dlfcn} standard).
+This functionality is not supported by @N{ISO C}.
+As such, @id{loadlib} is only available on some platforms:
+Linux, Windows, Mac OS X, Solaris, BSD,
+plus other Unix systems that support the @id{dlfcn} standard.
 
 
 This function is inherently insecure,
 This function is inherently insecure,
 as it allows Lua to call any function in any readable dynamic
 as it allows Lua to call any function in any readable dynamic

+ 17 - 3
onelua.c

@@ -1,5 +1,14 @@
 /*
 /*
-* one.c -- Lua core, libraries, and interpreter in a single file
+** Lua core, libraries, and interpreter in a single file.
+** Compiling just this file generates a complete Lua stand-alone
+** program:
+**
+** $ gcc -O2 -std=c99 -o lua onelua.c -lm
+**
+** or
+**
+** $ gcc -O2 -std=c89 -DLUA_USE_C89 -o lua onelua.c -lm
+**
 */
 */
 
 
 /* default is to build the full interpreter */
 /* default is to build the full interpreter */
@@ -11,8 +20,12 @@
 #endif
 #endif
 #endif
 #endif
 
 
-/* choose suitable platform-specific features */
-/* some of these may need extra libraries such as -ldl -lreadline -lncurses */
+
+/*
+** Choose suitable platform-specific features. Default is no
+** platform-specific features. Some of these options may need extra
+** libraries such as -ldl -lreadline -lncurses
+*/
 #if 0
 #if 0
 #define LUA_USE_LINUX
 #define LUA_USE_LINUX
 #define LUA_USE_MACOSX
 #define LUA_USE_MACOSX
@@ -20,6 +33,7 @@
 #define LUA_ANSI
 #define LUA_ANSI
 #endif
 #endif
 
 
+
 /* no need to change anything below this line ----------------------------- */
 /* no need to change anything below this line ----------------------------- */
 
 
 #include "lprefix.h"
 #include "lprefix.h"

+ 14 - 0
testes/calls.lua

@@ -342,6 +342,20 @@ do   -- another bug (in 5.4.0)
 end
 end
 
 
 
 
+do   -- another bug (since 5.2)
+  -- corrupted binary dump: list of upvalue names is larger than number
+  -- of upvalues, overflowing the array of upvalues.
+  local code =
+   "\x1b\x4c\x75\x61\x55\x00\x19\x93\x0d\x0a\x1a\x0a\x04\x08\x08\x78\x56\z
+    \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x77\x40\x00\x86\x40\z
+    \x74\x65\x6d\x70\x81\x81\x01\x00\x02\x82\x48\x00\x02\x00\xc7\x00\x01\z
+    \x00\x80\x80\x80\x82\x00\x00\x80\x81\x82\x78\x80\x82\x81\x86\x40\x74\z
+    \x65\x6d\x70"
+
+  assert(load(code))   -- segfaults in previous versions
+end
+
+
 x = string.dump(load("x = 1; return x"))
 x = string.dump(load("x = 1; return x"))
 a = assert(load(read1(x), nil, "b"))
 a = assert(load(read1(x), nil, "b"))
 assert(a() == 1 and _G.x == 1)
 assert(a() == 1 and _G.x == 1)

+ 1 - 1
testes/db.lua

@@ -928,7 +928,7 @@ do
     local cl = countlines(rest)
     local cl = countlines(rest)
     -- at most 10 lines in first part, 11 in second, plus '...'
     -- at most 10 lines in first part, 11 in second, plus '...'
     assert(cl <= 10 + 11 + 1)
     assert(cl <= 10 + 11 + 1)
-    local brk = string.find(rest, "%.%.%.")
+    local brk = string.find(rest, "%.%.%.\t%(skip")
     if brk then   -- does message have '...'?
     if brk then   -- does message have '...'?
       local rest1 = string.sub(rest, 1, brk)
       local rest1 = string.sub(rest, 1, brk)
       local rest2 = string.sub(rest, brk, #rest)
       local rest2 = string.sub(rest, brk, #rest)

+ 8 - 0
testes/errors.lua

@@ -444,6 +444,14 @@ if not b then
   end
   end
 end]], 5)
 end]], 5)
 
 
+
+-- bug in 5.4.0
+lineerror([[
+  local a = 0
+  local b = 1
+  local c = b % a
+]], 3)
+
 do
 do
   -- Force a negative estimate for base line. Error in instruction 2
   -- Force a negative estimate for base line. Error in instruction 2
   -- (after VARARGPREP, GETGLOBAL), with first absolute line information
   -- (after VARARGPREP, GETGLOBAL), with first absolute line information

+ 30 - 20
testes/main.lua

@@ -27,17 +27,19 @@ do
 end
 end
 print("progname: "..progname)
 print("progname: "..progname)
 
 
-local prepfile = function (s, p)
-  p = p or prog
-  io.output(p)
-  io.write(s)
-  assert(io.close())
+
+local prepfile = function (s, mod, p)
+  mod = mod and "wb" or "w"    -- mod true means binary files
+  p = p or prog                -- file to write the program
+  local f = io.open(p, mod)
+  f:write(s)
+  assert(f:close())
 end
 end
 
 
 local function getoutput ()
 local function getoutput ()
-  io.input(out)
-  local t = io.read("a")
-  io.input():close()
+  local f = io.open(out)
+  local t = f:read("a")
+  f:close()
   assert(os.remove(out))
   assert(os.remove(out))
   return t
   return t
 end
 end
@@ -65,10 +67,11 @@ local function RUN (p, ...)
   assert(os.execute(s))
   assert(os.execute(s))
 end
 end
 
 
+
 local function NoRun (msg, p, ...)
 local function NoRun (msg, p, ...)
   p = string.gsub(p, "lua", '"'..progname..'"', 1)
   p = string.gsub(p, "lua", '"'..progname..'"', 1)
   local s = string.format(p, ...)
   local s = string.format(p, ...)
-  s = string.format("%s 2> %s", s, out)  -- will send error to 'out'
+  s = string.format("%s >%s 2>&1", s, out)  -- send output and error to 'out'
   assert(not os.execute(s))
   assert(not os.execute(s))
   assert(string.find(getoutput(), msg, 1, true))  -- check error message
   assert(string.find(getoutput(), msg, 1, true))  -- check error message
 end
 end
@@ -108,17 +111,17 @@ RUN('lua %s > %s', prog, out)
 checkout("3\n")
 checkout("3\n")
 
 
 -- bad BOMs
 -- bad BOMs
-prepfile("\xEF")
-NoRun("unexpected symbol", 'lua %s > %s', prog, out)
+prepfile("\xEF", true)
+NoRun("unexpected symbol", 'lua %s', prog)
 
 
-prepfile("\xEF\xBB")
-NoRun("unexpected symbol", 'lua %s > %s', prog, out)
+prepfile("\xEF\xBB", true)
+NoRun("unexpected symbol", 'lua %s', prog)
 
 
-prepfile("\xEFprint(3)")
-NoRun("unexpected symbol", 'lua %s > %s', prog, out)
+prepfile("\xEFprint(3)", true)
+NoRun("unexpected symbol", 'lua %s', prog)
 
 
-prepfile("\xEF\xBBprint(3)")
-NoRun("unexpected symbol", 'lua %s > %s', prog, out)
+prepfile("\xEF\xBBprint(3)", true)
+NoRun("unexpected symbol", 'lua %s', prog)
 
 
 
 
 -- test option '-'
 -- test option '-'
@@ -213,7 +216,7 @@ convert("a;b;;c")
 
 
 -- test -l over multiple libraries
 -- test -l over multiple libraries
 prepfile("print(1); a=2; return {x=15}")
 prepfile("print(1); a=2; return {x=15}")
-prepfile(("print(a); print(_G['%s'].x)"):format(prog), otherprog)
+prepfile(("print(a); print(_G['%s'].x)"):format(prog), false, otherprog)
 RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out)
 RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out)
 checkout("1\n2\n15\n2\n15\n")
 checkout("1\n2\n15\n2\n15\n")
 
 
@@ -222,6 +225,13 @@ prepfile("print(str.upper'alo alo', m.max(10, 20))")
 RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out)
 RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out)
 checkout("0.0\nALO ALO\t20\n")
 checkout("0.0\nALO ALO\t20\n")
 
 
+
+-- test module names with version sufix ("libs/lib2-v2")
+RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s",
+    out)
+checkout("true\n")
+
+
 -- test 'arg' table
 -- test 'arg' table
 local a = [[
 local a = [[
   assert(#arg == 3 and arg[1] == 'a' and
   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
 
 
 -- test 'arg' availability in libraries
 -- test 'arg' availability in libraries
 prepfile"assert(arg)"
 prepfile"assert(arg)"
-prepfile("assert(arg)", otherprog)
+prepfile("assert(arg)", false, otherprog)
 RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog)
 RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog)
 
 
 -- test messing up the 'arg' table
 -- test messing up the 'arg' table
@@ -413,7 +423,7 @@ prepfile[[#comment in 1st line without \n at the end]]
 RUN('lua %s', prog)
 RUN('lua %s', prog)
 
 
 -- first-line comment with binary file
 -- first-line comment with binary file
-prepfile("#comment\n" .. string.dump(load("print(3)")))
+prepfile("#comment\n" .. string.dump(load("print(3)")), true)
 RUN('lua %s > %s', prog, out)
 RUN('lua %s > %s', prog, out)
 checkout('3\n')
 checkout('3\n')