aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2020-07-18 16:45:50 +0800
committerLi Jin <dragon-fly@qq.com>2020-07-18 16:45:50 +0800
commit8c596dc1efa8a1267c222b168a4de9c8ba254760 (patch)
tree699c748e101a48ae267b5f7b19adbfea15f3934e /src
parent8ab0038c09a79fa8401bb10b7a31d03ef5380417 (diff)
downloadyuescript-8c596dc1efa8a1267c222b168a4de9c8ba254760.tar.gz
yuescript-8c596dc1efa8a1267c222b168a4de9c8ba254760.tar.bz2
yuescript-8c596dc1efa8a1267c222b168a4de9c8ba254760.zip
fix issue for using return statement with export.
Diffstat (limited to 'src')
-rw-r--r--src/MoonP/moon_compiler.cpp30
-rw-r--r--src/lua/lapi.c43
-rw-r--r--src/lua/lauxlib.c6
-rw-r--r--src/lua/lcorolib.c9
-rw-r--r--src/lua/ldo.c23
-rw-r--r--src/lua/ldo.h6
-rw-r--r--src/lua/lgc.c10
-rw-r--r--src/lua/liolib.c7
-rw-r--r--src/lua/llimits.h10
-rw-r--r--src/lua/lmem.c2
-rw-r--r--src/lua/lobject.c49
-rw-r--r--src/lua/lstate.c6
-rw-r--r--src/lua/ltm.c4
-rw-r--r--src/lua/lundump.c9
-rw-r--r--src/lua/lvm.c18
15 files changed, 154 insertions, 78 deletions
diff --git a/src/MoonP/moon_compiler.cpp b/src/MoonP/moon_compiler.cpp
index 41d29df..1d9161b 100644
--- a/src/MoonP/moon_compiler.cpp
+++ b/src/MoonP/moon_compiler.cpp
@@ -49,7 +49,7 @@ inline std::string s(std::string_view sv) {
49} 49}
50 50
51const std::string_view version() { 51const std::string_view version() {
52 return "0.4.4"sv; 52 return "0.4.5"sv;
53} 53}
54 54
55// name of table stored in lua registry 55// name of table stored in lua registry
@@ -1498,6 +1498,7 @@ private:
1498 if (usage == ExpUsage::Closure) { 1498 if (usage == ExpUsage::Closure) {
1499 temp.push_back(s("(function()"sv) + nll(nodes.front())); 1499 temp.push_back(s("(function()"sv) + nll(nodes.front()));
1500 pushScope(); 1500 pushScope();
1501 _enableReturn.push(true);
1501 } 1502 }
1502 std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs; 1503 std::list<std::pair<IfCond_t*, Body_t*>> ifCondPairs;
1503 ifCondPairs.emplace_back(); 1504 ifCondPairs.emplace_back();
@@ -1613,6 +1614,7 @@ private:
1613 temp.push_back(indent() + s("end"sv) + nlr(nodes.front())); 1614 temp.push_back(indent() + s("end"sv) + nlr(nodes.front()));
1614 } 1615 }
1615 if (usage == ExpUsage::Closure) { 1616 if (usage == ExpUsage::Closure) {
1617 _enableReturn.pop();
1616 popScope(); 1618 popScope();
1617 temp.push_back(indent() + s("end)()"sv)); 1619 temp.push_back(indent() + s("end)()"sv));
1618 } 1620 }
@@ -2588,6 +2590,7 @@ private:
2588 if (usage == ExpUsage::Closure) { 2590 if (usage == ExpUsage::Closure) {
2589 temp.push_back(s("(function()"sv) + nll(x)); 2591 temp.push_back(s("(function()"sv) + nll(x));
2590 pushScope(); 2592 pushScope();
2593 _enableReturn.push(true);
2591 } 2594 }
2592 auto partOne = x->new_ptr<ChainValue_t>(); 2595 auto partOne = x->new_ptr<ChainValue_t>();
2593 for (auto it = chainList.begin();it != opIt;++it) { 2596 for (auto it = chainList.begin();it != opIt;++it) {
@@ -2718,6 +2721,7 @@ private:
2718 break; 2721 break;
2719 case ExpUsage::Closure: 2722 case ExpUsage::Closure:
2720 temp.push_back(indent() + s("return nil"sv) + nlr(x)); 2723 temp.push_back(indent() + s("return nil"sv) + nlr(x));
2724 _enableReturn.pop();
2721 popScope(); 2725 popScope();
2722 temp.push_back(indent() + s("end)()"sv)); 2726 temp.push_back(indent() + s("end)()"sv));
2723 break; 2727 break;
@@ -2742,6 +2746,7 @@ private:
2742 case ExpUsage::Closure: 2746 case ExpUsage::Closure:
2743 temp.push_back(s("(function()"sv) + nll(x)); 2747 temp.push_back(s("(function()"sv) + nll(x));
2744 pushScope(); 2748 pushScope();
2749 _enableReturn.push(true);
2745 break; 2750 break;
2746 default: 2751 default:
2747 break; 2752 break;
@@ -2813,6 +2818,7 @@ private:
2813 temp.push_back(indent() + s("end"sv) + nlr(x)); 2818 temp.push_back(indent() + s("end"sv) + nlr(x));
2814 break; 2819 break;
2815 case ExpUsage::Closure: 2820 case ExpUsage::Closure:
2821 _enableReturn.pop();
2816 popScope(); 2822 popScope();
2817 temp.push_back(indent() + s("end)()"sv)); 2823 temp.push_back(indent() + s("end)()"sv));
2818 break; 2824 break;
@@ -3359,6 +3365,9 @@ private:
3359 auto x = comp; 3365 auto x = comp;
3360 switch (usage) { 3366 switch (usage) {
3361 case ExpUsage::Closure: 3367 case ExpUsage::Closure:
3368 _enableReturn.push(true);
3369 pushScope();
3370 break;
3362 case ExpUsage::Assignment: 3371 case ExpUsage::Assignment:
3363 pushScope(); 3372 pushScope();
3364 break; 3373 break;
@@ -3413,6 +3422,7 @@ private:
3413 case ExpUsage::Common: 3422 case ExpUsage::Common:
3414 break; 3423 break;
3415 case ExpUsage::Closure: { 3424 case ExpUsage::Closure: {
3425 _enableReturn.pop();
3416 out.push_back(clearBuf()); 3426 out.push_back(clearBuf());
3417 out.back().append(indent() + s("return "sv) + accumVar + nlr(comp)); 3427 out.back().append(indent() + s("return "sv) + accumVar + nlr(comp));
3418 popScope(); 3428 popScope();
@@ -3697,8 +3707,10 @@ private:
3697 str_list temp; 3707 str_list temp;
3698 _buf << "(function()"sv << nll(forNode); 3708 _buf << "(function()"sv << nll(forNode);
3699 pushScope(); 3709 pushScope();
3710 _enableReturn.push(true);
3700 auto accum = transformForInner(forNode, temp); 3711 auto accum = transformForInner(forNode, temp);
3701 temp.push_back(indent() + s("return "sv) + accum + nlr(forNode)); 3712 temp.push_back(indent() + s("return "sv) + accum + nlr(forNode));
3713 _enableReturn.pop();
3702 popScope(); 3714 popScope();
3703 temp.push_back(indent() + s("end)()"sv)); 3715 temp.push_back(indent() + s("end)()"sv));
3704 out.push_back(join(temp)); 3716 out.push_back(join(temp));
@@ -3764,8 +3776,10 @@ private:
3764 str_list temp; 3776 str_list temp;
3765 _buf << "(function()"sv << nll(forEach); 3777 _buf << "(function()"sv << nll(forEach);
3766 pushScope(); 3778 pushScope();
3779 _enableReturn.push(true);
3767 auto accum = transformForEachInner(forEach, temp); 3780 auto accum = transformForEachInner(forEach, temp);
3768 temp.push_back(indent() + s("return "sv) + accum + nlr(forEach)); 3781 temp.push_back(indent() + s("return "sv) + accum + nlr(forEach));
3782 _enableReturn.pop();
3769 popScope(); 3783 popScope();
3770 temp.push_back(indent() + s("end)()"sv)); 3784 temp.push_back(indent() + s("end)()"sv));
3771 out.push_back(join(temp)); 3785 out.push_back(join(temp));
@@ -3918,7 +3932,9 @@ private:
3918 str_list temp; 3932 str_list temp;
3919 temp.push_back(s("(function()"sv) + nll(classDecl)); 3933 temp.push_back(s("(function()"sv) + nll(classDecl));
3920 pushScope(); 3934 pushScope();
3935 _enableReturn.push(true);
3921 transformClassDecl(classDecl, temp, ExpUsage::Return); 3936 transformClassDecl(classDecl, temp, ExpUsage::Return);
3937 _enableReturn.pop();
3922 popScope(); 3938 popScope();
3923 temp.push_back(s("end)()"sv)); 3939 temp.push_back(s("end)()"sv));
3924 out.push_back(join(temp)); 3940 out.push_back(join(temp));
@@ -4280,7 +4296,9 @@ private:
4280 str_list temp; 4296 str_list temp;
4281 temp.push_back(s("(function()"sv) + nll(with)); 4297 temp.push_back(s("(function()"sv) + nll(with));
4282 pushScope(); 4298 pushScope();
4299 _enableReturn.push(true);
4283 transformWith(with, temp, nullptr, true); 4300 transformWith(with, temp, nullptr, true);
4301 _enableReturn.pop();
4284 popScope(); 4302 popScope();
4285 temp.push_back(indent() + s("end)()"sv)); 4303 temp.push_back(indent() + s("end)()"sv));
4286 out.push_back(join(temp)); 4304 out.push_back(join(temp));
@@ -4605,6 +4623,9 @@ private:
4605 void transformTblComprehension(TblComprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) { 4623 void transformTblComprehension(TblComprehension_t* comp, str_list& out, ExpUsage usage, ExpList_t* assignList = nullptr) {
4606 switch (usage) { 4624 switch (usage) {
4607 case ExpUsage::Closure: 4625 case ExpUsage::Closure:
4626 pushScope();
4627 _enableReturn.push(true);
4628 break;
4608 case ExpUsage::Assignment: 4629 case ExpUsage::Assignment:
4609 pushScope(); 4630 pushScope();
4610 break; 4631 break;
@@ -4660,6 +4681,7 @@ private:
4660 case ExpUsage::Closure: 4681 case ExpUsage::Closure:
4661 out.push_back(clearBuf() + indent() + s("return "sv) + tbl + nlr(comp)); 4682 out.push_back(clearBuf() + indent() + s("return "sv) + tbl + nlr(comp));
4662 popScope(); 4683 popScope();
4684 _enableReturn.pop();
4663 out.back().insert(0, s("(function()"sv) + nll(comp)); 4685 out.back().insert(0, s("(function()"sv) + nll(comp));
4664 out.back().append(indent() + s("end)()"sv)); 4686 out.back().append(indent() + s("end)()"sv));
4665 break; 4687 break;
@@ -4713,6 +4735,7 @@ private:
4713 str_list temp; 4735 str_list temp;
4714 if (usage == ExpUsage::Closure) { 4736 if (usage == ExpUsage::Closure) {
4715 temp.push_back(s("(function()"sv) + nll(doNode)); 4737 temp.push_back(s("(function()"sv) + nll(doNode));
4738 _enableReturn.push(true);
4716 } else { 4739 } else {
4717 temp.push_back(indent() + s("do"sv) + nll(doNode)); 4740 temp.push_back(indent() + s("do"sv) + nll(doNode));
4718 } 4741 }
@@ -4720,6 +4743,7 @@ private:
4720 transformBody(doNode->body, temp, usage, assignList); 4743 transformBody(doNode->body, temp, usage, assignList);
4721 popScope(); 4744 popScope();
4722 if (usage == ExpUsage::Closure) { 4745 if (usage == ExpUsage::Closure) {
4746 _enableReturn.pop();
4723 temp.push_back(indent() + s("end)()"sv)); 4747 temp.push_back(indent() + s("end)()"sv));
4724 } else { 4748 } else {
4725 temp.push_back(indent() + s("end"sv) + nlr(doNode)); 4749 temp.push_back(indent() + s("end"sv) + nlr(doNode));
@@ -4990,6 +5014,7 @@ private:
4990 str_list temp; 5014 str_list temp;
4991 temp.push_back(s("(function() "sv) + nll(whileNode)); 5015 temp.push_back(s("(function() "sv) + nll(whileNode));
4992 pushScope(); 5016 pushScope();
5017 _enableReturn.push(true);
4993 auto accumVar = getUnusedName("_accum_"sv); 5018 auto accumVar = getUnusedName("_accum_"sv);
4994 addToScope(accumVar); 5019 addToScope(accumVar);
4995 auto lenVar = getUnusedName("_len_"sv); 5020 auto lenVar = getUnusedName("_len_"sv);
@@ -5005,6 +5030,7 @@ private:
5005 popScope(); 5030 popScope();
5006 temp.push_back(indent() + s("end"sv) + nlr(whileNode)); 5031 temp.push_back(indent() + s("end"sv) + nlr(whileNode));
5007 temp.push_back(indent() + s("return "sv) + accumVar + nlr(whileNode)); 5032 temp.push_back(indent() + s("return "sv) + accumVar + nlr(whileNode));
5033 _enableReturn.pop();
5008 popScope(); 5034 popScope();
5009 temp.push_back(indent() + s("end)()"sv)); 5035 temp.push_back(indent() + s("end)()"sv));
5010 out.push_back(join(temp)); 5036 out.push_back(join(temp));
@@ -5039,6 +5065,7 @@ private:
5039 if (usage == ExpUsage::Closure) { 5065 if (usage == ExpUsage::Closure) {
5040 temp.push_back(s("(function()"sv) + nll(switchNode)); 5066 temp.push_back(s("(function()"sv) + nll(switchNode));
5041 pushScope(); 5067 pushScope();
5068 _enableReturn.push(true);
5042 } 5069 }
5043 auto objVar = singleVariableFrom(switchNode->target); 5070 auto objVar = singleVariableFrom(switchNode->target);
5044 if (objVar.empty()) { 5071 if (objVar.empty()) {
@@ -5076,6 +5103,7 @@ private:
5076 } 5103 }
5077 temp.push_back(indent() + s("end"sv) + nlr(switchNode)); 5104 temp.push_back(indent() + s("end"sv) + nlr(switchNode));
5078 if (usage == ExpUsage::Closure) { 5105 if (usage == ExpUsage::Closure) {
5106 _enableReturn.pop();
5079 popScope(); 5107 popScope();
5080 temp.push_back(indent() + s("end)()"sv)); 5108 temp.push_back(indent() + s("end)()"sv));
5081 } 5109 }
diff --git a/src/lua/lapi.c b/src/lua/lapi.c
index 3e24781..9048245 100644
--- a/src/lua/lapi.c
+++ b/src/lua/lapi.c
@@ -97,8 +97,9 @@ static StkId index2stack (lua_State *L, int idx) {
97 97
98LUA_API int lua_checkstack (lua_State *L, int n) { 98LUA_API int lua_checkstack (lua_State *L, int n) {
99 int res; 99 int res;
100 CallInfo *ci = L->ci; 100 CallInfo *ci;
101 lua_lock(L); 101 lua_lock(L);
102 ci = L->ci;
102 api_check(L, n >= 0, "negative 'n'"); 103 api_check(L, n >= 0, "negative 'n'");
103 if (L->stack_last - L->top > n) /* stack large enough? */ 104 if (L->stack_last - L->top > n) /* stack large enough? */
104 res = 1; /* yes; check is OK */ 105 res = 1; /* yes; check is OK */
@@ -170,10 +171,12 @@ LUA_API int lua_gettop (lua_State *L) {
170 171
171 172
172LUA_API void lua_settop (lua_State *L, int idx) { 173LUA_API void lua_settop (lua_State *L, int idx) {
173 CallInfo *ci = L->ci; 174 CallInfo *ci;
174 StkId func = ci->func; 175 StkId func;
175 ptrdiff_t diff; /* difference for new top */ 176 ptrdiff_t diff; /* difference for new top */
176 lua_lock(L); 177 lua_lock(L);
178 ci = L->ci;
179 func = ci->func;
177 if (idx >= 0) { 180 if (idx >= 0) {
178 api_check(L, idx <= ci->top - (func + 1), "new top too large"); 181 api_check(L, idx <= ci->top - (func + 1), "new top too large");
179 diff = ((func + 1) + idx) - L->top; 182 diff = ((func + 1) + idx) - L->top;
@@ -376,20 +379,22 @@ LUA_API int lua_toboolean (lua_State *L, int idx) {
376 379
377 380
378LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { 381LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
379 TValue *o = index2value(L, idx); 382 TValue *o;
383 lua_lock(L);
384 o = index2value(L, idx);
380 if (!ttisstring(o)) { 385 if (!ttisstring(o)) {
381 if (!cvt2str(o)) { /* not convertible? */ 386 if (!cvt2str(o)) { /* not convertible? */
382 if (len != NULL) *len = 0; 387 if (len != NULL) *len = 0;
388 lua_unlock(L);
383 return NULL; 389 return NULL;
384 } 390 }
385 lua_lock(L); /* 'luaO_tostring' may create a new string */
386 luaO_tostring(L, o); 391 luaO_tostring(L, o);
387 luaC_checkGC(L); 392 luaC_checkGC(L);
388 o = index2value(L, idx); /* previous call may reallocate the stack */ 393 o = index2value(L, idx); /* previous call may reallocate the stack */
389 lua_unlock(L);
390 } 394 }
391 if (len != NULL) 395 if (len != NULL)
392 *len = vslen(o); 396 *len = vslen(o);
397 lua_unlock(L);
393 return svalue(o); 398 return svalue(o);
394} 399}
395 400
@@ -563,6 +568,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
563 while (n--) { 568 while (n--) {
564 setobj2n(L, &cl->upvalue[n], s2v(L->top + n)); 569 setobj2n(L, &cl->upvalue[n], s2v(L->top + n));
565 /* does not need barrier because closure is white */ 570 /* does not need barrier because closure is white */
571 lua_assert(iswhite(cl));
566 } 572 }
567 setclCvalue(L, s2v(L->top), cl); 573 setclCvalue(L, s2v(L->top), cl);
568 api_incr_top(L); 574 api_incr_top(L);
@@ -624,8 +630,9 @@ static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
624 630
625 631
626LUA_API int lua_getglobal (lua_State *L, const char *name) { 632LUA_API int lua_getglobal (lua_State *L, const char *name) {
627 Table *reg = hvalue(&G(L)->l_registry); 633 Table *reg;
628 lua_lock(L); 634 lua_lock(L);
635 reg = hvalue(&G(L)->l_registry);
629 return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); 636 return auxgetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
630} 637}
631 638
@@ -804,8 +811,9 @@ static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
804 811
805 812
806LUA_API void lua_setglobal (lua_State *L, const char *name) { 813LUA_API void lua_setglobal (lua_State *L, const char *name) {
807 Table *reg = hvalue(&G(L)->l_registry); 814 Table *reg;
808 lua_lock(L); /* unlock done in 'auxsetstr' */ 815 lua_lock(L); /* unlock done in 'auxsetstr' */
816 reg = hvalue(&G(L)->l_registry);
809 auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name); 817 auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
810} 818}
811 819
@@ -1093,8 +1101,9 @@ LUA_API int lua_status (lua_State *L) {
1093LUA_API int lua_gc (lua_State *L, int what, ...) { 1101LUA_API int lua_gc (lua_State *L, int what, ...) {
1094 va_list argp; 1102 va_list argp;
1095 int res = 0; 1103 int res = 0;
1096 global_State *g = G(L); 1104 global_State *g;
1097 lua_lock(L); 1105 lua_lock(L);
1106 g = G(L);
1098 va_start(argp, what); 1107 va_start(argp, what);
1099 switch (what) { 1108 switch (what) {
1100 case LUA_GCSTOP: { 1109 case LUA_GCSTOP: {
@@ -1194,9 +1203,15 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
1194 1203
1195 1204
1196LUA_API int lua_error (lua_State *L) { 1205LUA_API int lua_error (lua_State *L) {
1206 TValue *errobj;
1197 lua_lock(L); 1207 lua_lock(L);
1208 errobj = s2v(L->top - 1);
1198 api_checknelems(L, 1); 1209 api_checknelems(L, 1);
1199 luaG_errormsg(L); 1210 /* error object is the memory error message? */
1211 if (ttisshrstring(errobj) && eqshrstr(tsvalue(errobj), G(L)->memerrmsg))
1212 luaM_error(L); /* raise a memory error */
1213 else
1214 luaG_errormsg(L); /* raise a regular error */
1200 /* code unreachable; will unlock when control actually leaves the kernel */ 1215 /* code unreachable; will unlock when control actually leaves the kernel */
1201 return 0; /* to avoid warnings */ 1216 return 0; /* to avoid warnings */
1202} 1217}
@@ -1238,14 +1253,12 @@ LUA_API void lua_toclose (lua_State *L, int idx) {
1238LUA_API void lua_concat (lua_State *L, int n) { 1253LUA_API void lua_concat (lua_State *L, int n) {
1239 lua_lock(L); 1254 lua_lock(L);
1240 api_checknelems(L, n); 1255 api_checknelems(L, n);
1241 if (n >= 2) { 1256 if (n > 0)
1242 luaV_concat(L, n); 1257 luaV_concat(L, n);
1243 } 1258 else { /* nothing to concatenate */
1244 else if (n == 0) { /* push empty string */ 1259 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); /* push empty string */
1245 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
1246 api_incr_top(L); 1260 api_incr_top(L);
1247 } 1261 }
1248 /* else n == 1; nothing to do */
1249 luaC_checkGC(L); 1262 luaC_checkGC(L);
1250 lua_unlock(L); 1263 lua_unlock(L);
1251} 1264}
diff --git a/src/lua/lauxlib.c b/src/lua/lauxlib.c
index e3d9be3..cbe9ed3 100644
--- a/src/lua/lauxlib.c
+++ b/src/lua/lauxlib.c
@@ -475,8 +475,10 @@ static void *resizebox (lua_State *L, int idx, size_t newsize) {
475 lua_Alloc allocf = lua_getallocf(L, &ud); 475 lua_Alloc allocf = lua_getallocf(L, &ud);
476 UBox *box = (UBox *)lua_touserdata(L, idx); 476 UBox *box = (UBox *)lua_touserdata(L, idx);
477 void *temp = allocf(ud, box->box, box->bsize, newsize); 477 void *temp = allocf(ud, box->box, box->bsize, newsize);
478 if (temp == NULL && newsize > 0) /* allocation error? */ 478 if (temp == NULL && newsize > 0) { /* allocation error? */
479 luaL_error(L, "not enough memory"); 479 lua_pushliteral(L, "not enough memory");
480 lua_error(L); /* raise a memory error */
481 }
480 box->box = temp; 482 box->box = temp;
481 box->bsize = newsize; 483 box->bsize = newsize;
482 return temp; 484 return temp;
diff --git a/src/lua/lcorolib.c b/src/lua/lcorolib.c
index 7d6e585..c165031 100644
--- a/src/lua/lcorolib.c
+++ b/src/lua/lcorolib.c
@@ -73,11 +73,12 @@ static int luaB_coresume (lua_State *L) {
73static int luaB_auxwrap (lua_State *L) { 73static int luaB_auxwrap (lua_State *L) {
74 lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 74 lua_State *co = lua_tothread(L, lua_upvalueindex(1));
75 int r = auxresume(L, co, lua_gettop(L)); 75 int r = auxresume(L, co, lua_gettop(L));
76 if (r < 0) { 76 if (r < 0) { /* error? */
77 int stat = lua_status(co); 77 int stat = lua_status(co);
78 if (stat != LUA_OK && stat != LUA_YIELD) 78 if (stat != LUA_OK && stat != LUA_YIELD) /* error in the coroutine? */
79 lua_resetthread(co); /* close variables in case of errors */ 79 lua_resetthread(co); /* close its tbc variables */
80 if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */ 80 if (stat != LUA_ERRMEM && /* not a memory error and ... */
81 lua_type(L, -1) == LUA_TSTRING) { /* ... error object is a string? */
81 luaL_where(L, 1); /* add extra info, if available */ 82 luaL_where(L, 1); /* add extra info, if available */
82 lua_insert(L, -2); 83 lua_insert(L, -2);
83 lua_concat(L, 2); 84 lua_concat(L, 2);
diff --git a/src/lua/ldo.c b/src/lua/ldo.c
index c563b1d..4c976a1 100644
--- a/src/lua/ldo.c
+++ b/src/lua/ldo.c
@@ -245,13 +245,12 @@ static int stackinuse (lua_State *L) {
245 245
246void luaD_shrinkstack (lua_State *L) { 246void luaD_shrinkstack (lua_State *L) {
247 int inuse = stackinuse(L); 247 int inuse = stackinuse(L);
248 int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; 248 int goodsize = inuse + BASIC_STACK_SIZE;
249 if (goodsize > LUAI_MAXSTACK) 249 if (goodsize > LUAI_MAXSTACK)
250 goodsize = LUAI_MAXSTACK; /* respect stack limit */ 250 goodsize = LUAI_MAXSTACK; /* respect stack limit */
251 /* if thread is currently not handling a stack overflow and its 251 /* if thread is currently not handling a stack overflow and its
252 good size is smaller than current size, shrink its stack */ 252 good size is smaller than current size, shrink its stack */
253 if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && 253 if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && goodsize < L->stacksize)
254 goodsize < L->stacksize)
255 luaD_reallocstack(L, goodsize, 0); /* ok if that fails */ 254 luaD_reallocstack(L, goodsize, 0); /* ok if that fails */
256 else /* don't change stack */ 255 else /* don't change stack */
257 condmovestack(L,{},{}); /* (change only for debugging) */ 256 condmovestack(L,{},{}); /* (change only for debugging) */
@@ -466,13 +465,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
466 f = fvalue(s2v(func)); 465 f = fvalue(s2v(func));
467 Cfunc: { 466 Cfunc: {
468 int n; /* number of returns */ 467 int n; /* number of returns */
469 CallInfo *ci = next_ci(L); 468 CallInfo *ci;
470 checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ 469 checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
470 L->ci = ci = next_ci(L);
471 ci->nresults = nresults; 471 ci->nresults = nresults;
472 ci->callstatus = CIST_C; 472 ci->callstatus = CIST_C;
473 ci->top = L->top + LUA_MINSTACK; 473 ci->top = L->top + LUA_MINSTACK;
474 ci->func = func; 474 ci->func = func;
475 L->ci = ci;
476 lua_assert(ci->top <= L->stack_last); 475 lua_assert(ci->top <= L->stack_last);
477 if (L->hookmask & LUA_MASKCALL) { 476 if (L->hookmask & LUA_MASKCALL) {
478 int narg = cast_int(L->top - func) - 1; 477 int narg = cast_int(L->top - func) - 1;
@@ -486,12 +485,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
486 break; 485 break;
487 } 486 }
488 case LUA_VLCL: { /* Lua function */ 487 case LUA_VLCL: { /* Lua function */
489 CallInfo *ci = next_ci(L); 488 CallInfo *ci;
490 Proto *p = clLvalue(s2v(func))->p; 489 Proto *p = clLvalue(s2v(func))->p;
491 int narg = cast_int(L->top - func) - 1; /* number of real arguments */ 490 int narg = cast_int(L->top - func) - 1; /* number of real arguments */
492 int nfixparams = p->numparams; 491 int nfixparams = p->numparams;
493 int fsize = p->maxstacksize; /* frame size */ 492 int fsize = p->maxstacksize; /* frame size */
494 checkstackp(L, fsize, func); 493 checkstackGCp(L, fsize, func);
494 L->ci = ci = next_ci(L);
495 ci->nresults = nresults; 495 ci->nresults = nresults;
496 ci->u.l.savedpc = p->code; /* starting point */ 496 ci->u.l.savedpc = p->code; /* starting point */
497 ci->callstatus = 0; 497 ci->callstatus = 0;
@@ -505,7 +505,7 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
505 break; 505 break;
506 } 506 }
507 default: { /* not a function */ 507 default: { /* not a function */
508 checkstackp(L, 1, func); /* space for metamethod */ 508 checkstackGCp(L, 1, func); /* space for metamethod */
509 luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ 509 luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
510 goto retry; /* try again with metamethod */ 510 goto retry; /* try again with metamethod */
511 } 511 }
@@ -674,7 +674,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
674 if (from == NULL) 674 if (from == NULL)
675 L->nCcalls = CSTACKTHREAD; 675 L->nCcalls = CSTACKTHREAD;
676 else /* correct 'nCcalls' for this thread */ 676 else /* correct 'nCcalls' for this thread */
677 L->nCcalls = getCcalls(from) + from->nci - L->nci - CSTACKCF; 677 L->nCcalls = getCcalls(from) - L->nci - CSTACKCF;
678 if (L->nCcalls <= CSTACKERR) 678 if (L->nCcalls <= CSTACKERR)
679 return resume_error(L, "C stack overflow", nargs); 679 return resume_error(L, "C stack overflow", nargs);
680 luai_userstateresume(L, nargs); 680 luai_userstateresume(L, nargs);
@@ -706,9 +706,10 @@ LUA_API int lua_isyieldable (lua_State *L) {
706 706
707LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, 707LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
708 lua_KFunction k) { 708 lua_KFunction k) {
709 CallInfo *ci = L->ci; 709 CallInfo *ci;
710 luai_userstateyield(L, nresults); 710 luai_userstateyield(L, nresults);
711 lua_lock(L); 711 lua_lock(L);
712 ci = L->ci;
712 api_checknelems(L, nresults); 713 api_checknelems(L, nresults);
713 if (unlikely(!yieldable(L))) { 714 if (unlikely(!yieldable(L))) {
714 if (L != G(L)->mainthread) 715 if (L != G(L)->mainthread)
diff --git a/src/lua/ldo.h b/src/lua/ldo.h
index 7760f85..6c6cb28 100644
--- a/src/lua/ldo.h
+++ b/src/lua/ldo.h
@@ -17,6 +17,8 @@
17** Macro to check stack size and grow stack if needed. Parameters 17** Macro to check stack size and grow stack if needed. Parameters
18** 'pre'/'pos' allow the macro to preserve a pointer into the 18** 'pre'/'pos' allow the macro to preserve a pointer into the
19** stack across reallocations, doing the work only when needed. 19** stack across reallocations, doing the work only when needed.
20** It also allows the running of one GC step when the stack is
21** reallocated.
20** 'condmovestack' is used in heavy tests to force a stack reallocation 22** 'condmovestack' is used in heavy tests to force a stack reallocation
21** at every check. 23** at every check.
22*/ 24*/
@@ -35,7 +37,7 @@
35 37
36 38
37/* macro to check stack size, preserving 'p' */ 39/* macro to check stack size, preserving 'p' */
38#define checkstackp(L,n,p) \ 40#define checkstackGCp(L,n,p) \
39 luaD_checkstackaux(L, n, \ 41 luaD_checkstackaux(L, n, \
40 ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ 42 ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
41 luaC_checkGC(L), /* stack grow uses memory */ \ 43 luaC_checkGC(L), /* stack grow uses memory */ \
@@ -44,7 +46,7 @@
44 46
45/* macro to check stack size and GC */ 47/* macro to check stack size and GC */
46#define checkstackGC(L,fsize) \ 48#define checkstackGC(L,fsize) \
47 luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L)) 49 luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0)
48 50
49 51
50/* type of protected functions, to be ran by 'runprotected' */ 52/* type of protected functions, to be ran by 'runprotected' */
diff --git a/src/lua/lgc.c b/src/lua/lgc.c
index f26c921..f7fd7a5 100644
--- a/src/lua/lgc.c
+++ b/src/lua/lgc.c
@@ -1131,16 +1131,14 @@ static void finishgencycle (lua_State *L, global_State *g) {
1131 1131
1132 1132
1133/* 1133/*
1134** Does a young collection. First, mark 'OLD1' objects. (Only survival 1134** Does a young collection. First, mark 'OLD1' objects. Then does the
1135** and "recent old" lists can contain 'OLD1' objects. New lists cannot 1135** atomic step. Then, sweep all lists and advance pointers. Finally,
1136** contain 'OLD1' objects, at most 'OLD0' objects that were already 1136** finish the collection.
1137** visited when marked old.) Then does the atomic step. Then,
1138** sweep all lists and advance pointers. Finally, finish the collection.
1139*/ 1137*/
1140static void youngcollection (lua_State *L, global_State *g) { 1138static void youngcollection (lua_State *L, global_State *g) {
1141 GCObject **psurvival; /* to point to first non-dead survival object */ 1139 GCObject **psurvival; /* to point to first non-dead survival object */
1142 lua_assert(g->gcstate == GCSpropagate); 1140 lua_assert(g->gcstate == GCSpropagate);
1143 markold(g, g->survival, g->reallyold); 1141 markold(g, g->allgc, g->reallyold);
1144 markold(g, g->finobj, g->finobjrold); 1142 markold(g, g->finobj, g->finobjrold);
1145 atomic(L); 1143 atomic(L);
1146 1144
diff --git a/src/lua/liolib.c b/src/lua/liolib.c
index 7ac3444..60ab1bf 100644
--- a/src/lua/liolib.c
+++ b/src/lua/liolib.c
@@ -52,6 +52,12 @@ static int l_checkmode (const char *mode) {
52** ======================================================= 52** =======================================================
53*/ 53*/
54 54
55#if !defined(l_checkmodep)
56/* By default, Lua accepts only "r" or "w" as mode */
57#define l_checkmodep(m) ((m[0] == 'r' || m[0] == 'w') && m[1] == '\0')
58#endif
59
60
55#if !defined(l_popen) /* { */ 61#if !defined(l_popen) /* { */
56 62
57#if defined(LUA_USE_POSIX) /* { */ 63#if defined(LUA_USE_POSIX) /* { */
@@ -279,6 +285,7 @@ static int io_popen (lua_State *L) {
279 const char *filename = luaL_checkstring(L, 1); 285 const char *filename = luaL_checkstring(L, 1);
280 const char *mode = luaL_optstring(L, 2, "r"); 286 const char *mode = luaL_optstring(L, 2, "r");
281 LStream *p = newprefile(L); 287 LStream *p = newprefile(L);
288 luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode");
282 p->f = l_popen(L, filename, mode); 289 p->f = l_popen(L, filename, mode);
283 p->closef = &io_pclose; 290 p->closef = &io_pclose;
284 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; 291 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
diff --git a/src/lua/llimits.h b/src/lua/llimits.h
index b86d345..48c97f9 100644
--- a/src/lua/llimits.h
+++ b/src/lua/llimits.h
@@ -84,7 +84,15 @@ typedef LUAI_UACNUMBER l_uacNumber;
84typedef LUAI_UACINT l_uacInt; 84typedef LUAI_UACINT l_uacInt;
85 85
86 86
87/* internal assertions for in-house debugging */ 87/*
88** Internal assertions for in-house debugging
89*/
90#if defined LUAI_ASSERT
91#undef NDEBUG
92#include <assert.h>
93#define lua_assert(c) assert(c)
94#endif
95
88#if defined(lua_assert) 96#if defined(lua_assert)
89#define check_exp(c,e) (lua_assert(c), (e)) 97#define check_exp(c,e) (lua_assert(c), (e))
90/* to avoid problems with conditions too long */ 98/* to avoid problems with conditions too long */
diff --git a/src/lua/lmem.c b/src/lua/lmem.c
index 65bfa52..43739bf 100644
--- a/src/lua/lmem.c
+++ b/src/lua/lmem.c
@@ -22,7 +22,7 @@
22#include "lstate.h" 22#include "lstate.h"
23 23
24 24
25#if defined(HARDMEMTESTS) 25#if defined(EMERGENCYGCTESTS)
26/* 26/*
27** First allocation will fail whenever not building initial state 27** First allocation will fail whenever not building initial state
28** and not shrinking a block. (This fail will trigger 'tryagain' and 28** and not shrinking a block. (This fail will trigger 'tryagain' and
diff --git a/src/lua/lobject.c b/src/lua/lobject.c
index b4efae4..f8ea917 100644
--- a/src/lua/lobject.c
+++ b/src/lua/lobject.c
@@ -215,37 +215,42 @@ static lua_Number lua_strx2number (const char *s, char **endptr) {
215/* }====================================================== */ 215/* }====================================================== */
216 216
217 217
218/* maximum length of a numeral */ 218/* maximum length of a numeral to be converted to a number */
219#if !defined (L_MAXLENNUM) 219#if !defined (L_MAXLENNUM)
220#define L_MAXLENNUM 200 220#define L_MAXLENNUM 200
221#endif 221#endif
222 222
223/*
224** Convert string 's' to a Lua number (put in 'result'). Return NULL on
225** fail or the address of the ending '\0' on success. ('mode' == 'x')
226** means a hexadecimal numeral.
227*/
223static const char *l_str2dloc (const char *s, lua_Number *result, int mode) { 228static const char *l_str2dloc (const char *s, lua_Number *result, int mode) {
224 char *endptr; 229 char *endptr;
225 *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */ 230 *result = (mode == 'x') ? lua_strx2number(s, &endptr) /* try to convert */
226 : lua_str2number(s, &endptr); 231 : lua_str2number(s, &endptr);
227 if (endptr == s) return NULL; /* nothing recognized? */ 232 if (endptr == s) return NULL; /* nothing recognized? */
228 while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */ 233 while (lisspace(cast_uchar(*endptr))) endptr++; /* skip trailing spaces */
229 return (*endptr == '\0') ? endptr : NULL; /* OK if no trailing characters */ 234 return (*endptr == '\0') ? endptr : NULL; /* OK iff no trailing chars */
230} 235}
231 236
232 237
233/* 238/*
234** Convert string 's' to a Lua number (put in 'result'). Return NULL 239** Convert string 's' to a Lua number (put in 'result') handling the
235** on fail or the address of the ending '\0' on success. 240** current locale.
236** 'pmode' points to (and 'mode' contains) special things in the string:
237** - 'x'/'X' means a hexadecimal numeral
238** - 'n'/'N' means 'inf' or 'nan' (which should be rejected)
239** - '.' just optimizes the search for the common case (nothing special)
240** This function accepts both the current locale or a dot as the radix 241** This function accepts both the current locale or a dot as the radix
241** mark. If the conversion fails, it may mean number has a dot but 242** mark. If the conversion fails, it may mean number has a dot but
242** locale accepts something else. In that case, the code copies 's' 243** locale accepts something else. In that case, the code copies 's'
243** to a buffer (because 's' is read-only), changes the dot to the 244** to a buffer (because 's' is read-only), changes the dot to the
244** current locale radix mark, and tries to convert again. 245** current locale radix mark, and tries to convert again.
246** The variable 'mode' checks for special characters in the string:
247** - 'n' means 'inf' or 'nan' (which should be rejected)
248** - 'x' means a hexadecimal numeral
249** - '.' just optimizes the search for the common case (no special chars)
245*/ 250*/
246static const char *l_str2d (const char *s, lua_Number *result) { 251static const char *l_str2d (const char *s, lua_Number *result) {
247 const char *endptr; 252 const char *endptr;
248 const char *pmode = strpbrk(s, ".xXnN"); 253 const char *pmode = strpbrk(s, ".xXnN"); /* look for special chars */
249 int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0; 254 int mode = pmode ? ltolower(cast_uchar(*pmode)) : 0;
250 if (mode == 'n') /* reject 'inf' and 'nan' */ 255 if (mode == 'n') /* reject 'inf' and 'nan' */
251 return NULL; 256 return NULL;
@@ -333,8 +338,15 @@ int luaO_utf8esc (char *buff, unsigned long x) {
333} 338}
334 339
335 340
336/* maximum length of the conversion of a number to a string */ 341/*
337#define MAXNUMBER2STR 50 342** Maximum length of the conversion of a number to a string. Must be
343** enough to accommodate both LUA_INTEGER_FMT and LUA_NUMBER_FMT.
344** (For a long long int, this is 19 digits plus a sign and a final '\0',
345** adding to 21. For a long double, it can go to a sign, 33 digits,
346** the dot, an exponent letter, an exponent sign, 5 exponent digits,
347** and a final '\0', adding to 43.)
348*/
349#define MAXNUMBER2STR 44
338 350
339 351
340/* 352/*
@@ -375,7 +387,7 @@ void luaO_tostring (lua_State *L, TValue *obj) {
375*/ 387*/
376 388
377/* size for buffer space used by 'luaO_pushvfstring' */ 389/* size for buffer space used by 'luaO_pushvfstring' */
378#define BUFVFS 400 390#define BUFVFS 200
379 391
380/* buffer used by 'luaO_pushvfstring' */ 392/* buffer used by 'luaO_pushvfstring' */
381typedef struct BuffFS { 393typedef struct BuffFS {
@@ -387,18 +399,16 @@ typedef struct BuffFS {
387 399
388 400
389/* 401/*
390** Push given string to the stack, as part of the buffer. If the stack 402** Push given string to the stack, as part of the buffer, and
391** is almost full, join all partial strings in the stack into one. 403** join the partial strings in the stack into one.
392*/ 404*/
393static void pushstr (BuffFS *buff, const char *str, size_t l) { 405static void pushstr (BuffFS *buff, const char *str, size_t l) {
394 lua_State *L = buff->L; 406 lua_State *L = buff->L;
395 setsvalue2s(L, L->top, luaS_newlstr(L, str, l)); 407 setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
396 L->top++; /* may use one extra slot */ 408 L->top++; /* may use one extra slot */
397 buff->pushed++; 409 buff->pushed++;
398 if (buff->pushed > 1 && L->top + 1 >= L->stack_last) { 410 luaV_concat(L, buff->pushed); /* join partial results into one */
399 luaV_concat(L, buff->pushed); /* join all partial results into one */ 411 buff->pushed = 1;
400 buff->pushed = 1;
401 }
402} 412}
403 413
404 414
@@ -521,8 +531,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
521 } 531 }
522 addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */ 532 addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
523 clearbuff(&buff); /* empty buffer into the stack */ 533 clearbuff(&buff); /* empty buffer into the stack */
524 if (buff.pushed > 1) 534 lua_assert(buff.pushed == 1);
525 luaV_concat(L, buff.pushed); /* join all partial results */
526 return svalue(s2v(L->top - 1)); 535 return svalue(s2v(L->top - 1));
527} 536}
528 537
diff --git a/src/lua/lstate.c b/src/lua/lstate.c
index 4434211..28853dc 100644
--- a/src/lua/lstate.c
+++ b/src/lua/lstate.c
@@ -318,9 +318,10 @@ static void close_state (lua_State *L) {
318 318
319 319
320LUA_API lua_State *lua_newthread (lua_State *L) { 320LUA_API lua_State *lua_newthread (lua_State *L) {
321 global_State *g = G(L); 321 global_State *g;
322 lua_State *L1; 322 lua_State *L1;
323 lua_lock(L); 323 lua_lock(L);
324 g = G(L);
324 luaC_checkGC(L); 325 luaC_checkGC(L);
325 /* create new thread */ 326 /* create new thread */
326 L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; 327 L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
@@ -395,6 +396,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
395 g->allgc = obj2gco(L); /* by now, only object is the main thread */ 396 g->allgc = obj2gco(L); /* by now, only object is the main thread */
396 L->next = NULL; 397 L->next = NULL;
397 g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR; 398 g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR;
399 incnny(L); /* main thread is always non yieldable */
398 g->frealloc = f; 400 g->frealloc = f;
399 g->ud = ud; 401 g->ud = ud;
400 g->warnf = NULL; 402 g->warnf = NULL;
@@ -436,8 +438,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
436 438
437 439
438LUA_API void lua_close (lua_State *L) { 440LUA_API void lua_close (lua_State *L) {
439 L = G(L)->mainthread; /* only the main thread can be closed */
440 lua_lock(L); 441 lua_lock(L);
442 L = G(L)->mainthread; /* only the main thread can be closed */
441 close_state(L); 443 close_state(L);
442} 444}
443 445
diff --git a/src/lua/ltm.c b/src/lua/ltm.c
index ae60983..4770f96 100644
--- a/src/lua/ltm.c
+++ b/src/lua/ltm.c
@@ -240,7 +240,7 @@ void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci,
240 int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */ 240 int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */
241 int nextra = actual - nfixparams; /* number of extra arguments */ 241 int nextra = actual - nfixparams; /* number of extra arguments */
242 ci->u.l.nextraargs = nextra; 242 ci->u.l.nextraargs = nextra;
243 checkstackGC(L, p->maxstacksize + 1); 243 luaD_checkstack(L, p->maxstacksize + 1);
244 /* copy function to the top of the stack */ 244 /* copy function to the top of the stack */
245 setobjs2s(L, L->top++, ci->func); 245 setobjs2s(L, L->top++, ci->func);
246 /* move fixed parameters to the top of the stack */ 246 /* move fixed parameters to the top of the stack */
@@ -259,7 +259,7 @@ void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) {
259 int nextra = ci->u.l.nextraargs; 259 int nextra = ci->u.l.nextraargs;
260 if (wanted < 0) { 260 if (wanted < 0) {
261 wanted = nextra; /* get all extra arguments available */ 261 wanted = nextra; /* get all extra arguments available */
262 checkstackp(L, nextra, where); /* ensure stack space */ 262 checkstackGCp(L, nextra, where); /* ensure stack space */
263 L->top = where + nextra; /* next instruction will need top */ 263 L->top = where + nextra; /* next instruction will need top */
264 } 264 }
265 for (i = 0; i < wanted && i < nextra; i++) 265 for (i = 0; i < wanted && i < nextra; i++)
diff --git a/src/lua/lundump.c b/src/lua/lundump.c
index 4243678..cb124d6 100644
--- a/src/lua/lundump.c
+++ b/src/lua/lundump.c
@@ -200,13 +200,20 @@ static void loadProtos (LoadState *S, Proto *f) {
200} 200}
201 201
202 202
203/*
204** Load the upvalues for a function. The names must be filled first,
205** because the filling of the other fields can raise read errors and
206** the creation of the error message can call an emergency collection;
207** in that case all prototypes must be consistent for the GC.
208*/
203static void loadUpvalues (LoadState *S, Proto *f) { 209static void loadUpvalues (LoadState *S, Proto *f) {
204 int i, n; 210 int i, n;
205 n = loadInt(S); 211 n = loadInt(S);
206 f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc); 212 f->upvalues = luaM_newvectorchecked(S->L, n, Upvaldesc);
207 f->sizeupvalues = n; 213 f->sizeupvalues = n;
208 for (i = 0; i < n; i++) { 214 for (i = 0; i < n; i++) /* make array valid for GC */
209 f->upvalues[i].name = NULL; 215 f->upvalues[i].name = NULL;
216 for (i = 0; i < n; i++) { /* following calls can raise errors */
210 f->upvalues[i].instack = loadByte(S); 217 f->upvalues[i].instack = loadByte(S);
211 f->upvalues[i].idx = loadByte(S); 218 f->upvalues[i].idx = loadByte(S);
212 f->upvalues[i].kind = loadByte(S); 219 f->upvalues[i].kind = loadByte(S);
diff --git a/src/lua/lvm.c b/src/lua/lvm.c
index e7781db..66d451b 100644
--- a/src/lua/lvm.c
+++ b/src/lua/lvm.c
@@ -634,7 +634,8 @@ static void copy2buff (StkId top, int n, char *buff) {
634** from 'L->top - total' up to 'L->top - 1'. 634** from 'L->top - total' up to 'L->top - 1'.
635*/ 635*/
636void luaV_concat (lua_State *L, int total) { 636void luaV_concat (lua_State *L, int total) {
637 lua_assert(total >= 2); 637 if (total == 1)
638 return; /* "all" values already concatenated */
638 do { 639 do {
639 StkId top = L->top; 640 StkId top = L->top;
640 int n = 2; /* number of elements handled in this pass (at least 2) */ 641 int n = 2; /* number of elements handled in this pass (at least 2) */
@@ -840,10 +841,8 @@ void luaV_finishOp (lua_State *L) {
840 int a = GETARG_A(inst); /* first element to concatenate */ 841 int a = GETARG_A(inst); /* first element to concatenate */
841 int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */ 842 int total = cast_int(top - 1 - (base + a)); /* yet to concatenate */
842 setobjs2s(L, top - 2, top); /* put TM result in proper position */ 843 setobjs2s(L, top - 2, top); /* put TM result in proper position */
843 if (total > 1) { /* are there elements to concat? */ 844 L->top = top - 1; /* top is one after last element (at top-2) */
844 L->top = top - 1; /* top is one after last element (at top-2) */ 845 luaV_concat(L, total); /* concat them (may yield again) */
845 luaV_concat(L, total); /* concat them (may yield again) */
846 }
847 break; 846 break;
848 } 847 }
849 default: { 848 default: {
@@ -1102,9 +1101,9 @@ void luaV_finishOp (lua_State *L) {
1102/* idem, but without changing the stack */ 1101/* idem, but without changing the stack */
1103#define halfProtectNT(exp) (savepc(L), (exp)) 1102#define halfProtectNT(exp) (savepc(L), (exp))
1104 1103
1105 1104/* 'c' is the limit of live values in the stack */
1106#define checkGC(L,c) \ 1105#define checkGC(L,c) \
1107 { luaC_condGC(L, L->top = (c), /* limit of live values */ \ 1106 { luaC_condGC(L, (savepc(L), L->top = (c)), \
1108 updatetrap(ci)); \ 1107 updatetrap(ci)); \
1109 luai_threadyield(L); } 1108 luai_threadyield(L); }
1110 1109
@@ -1635,7 +1634,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1635 while (!ttisfunction(s2v(ra))) { /* not a function? */ 1634 while (!ttisfunction(s2v(ra))) { /* not a function? */
1636 luaD_tryfuncTM(L, ra); /* try '__call' metamethod */ 1635 luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
1637 b++; /* there is now one extra argument */ 1636 b++; /* there is now one extra argument */
1638 checkstackp(L, 1, ra); 1637 checkstackGCp(L, 1, ra);
1639 } 1638 }
1640 if (!ttisLclosure(s2v(ra))) { /* C function? */ 1639 if (!ttisLclosure(s2v(ra))) { /* C function? */
1641 luaD_call(L, ra, LUA_MULTRET); /* call it */ 1640 luaD_call(L, ra, LUA_MULTRET); /* call it */
@@ -1792,8 +1791,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1792 vmbreak; 1791 vmbreak;
1793 } 1792 }
1794 vmcase(OP_VARARGPREP) { 1793 vmcase(OP_VARARGPREP) {
1795 luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p); 1794 ProtectNT(luaT_adjustvarargs(L, GETARG_A(i), ci, cl->p));
1796 updatetrap(ci);
1797 if (trap) { 1795 if (trap) {
1798 luaD_hookcall(L, ci); 1796 luaD_hookcall(L, ci);
1799 L->oldpc = pc + 1; /* next opcode will be seen as a "new" line */ 1797 L->oldpc = pc + 1; /* next opcode will be seen as a "new" line */