aboutsummaryrefslogtreecommitdiff
path: root/src/lj_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_api.c')
-rw-r--r--src/lj_api.c393
1 files changed, 252 insertions, 141 deletions
diff --git a/src/lj_api.c b/src/lj_api.c
index 04a41792..d869ebf8 100644
--- a/src/lj_api.c
+++ b/src/lj_api.c
@@ -24,11 +24,12 @@
24#include "lj_trace.h" 24#include "lj_trace.h"
25#include "lj_vm.h" 25#include "lj_vm.h"
26#include "lj_strscan.h" 26#include "lj_strscan.h"
27#include "lj_strfmt.h"
27 28
28/* -- Common helper functions --------------------------------------------- */ 29/* -- Common helper functions --------------------------------------------- */
29 30
30#define api_checknelems(L, n) api_check(L, (n) <= (L->top - L->base)) 31#define lj_checkapi_slot(idx) \
31#define api_checkvalidindex(L, i) api_check(L, (i) != niltv(L)) 32 lj_checkapi((idx) <= (L->top - L->base), "stack slot %d out of range", (idx))
32 33
33static TValue *index2adr(lua_State *L, int idx) 34static TValue *index2adr(lua_State *L, int idx)
34{ 35{
@@ -36,7 +37,8 @@ static TValue *index2adr(lua_State *L, int idx)
36 TValue *o = L->base + (idx - 1); 37 TValue *o = L->base + (idx - 1);
37 return o < L->top ? o : niltv(L); 38 return o < L->top ? o : niltv(L);
38 } else if (idx > LUA_REGISTRYINDEX) { 39 } else if (idx > LUA_REGISTRYINDEX) {
39 api_check(L, idx != 0 && -idx <= L->top - L->base); 40 lj_checkapi(idx != 0 && -idx <= L->top - L->base,
41 "bad stack slot %d", idx);
40 return L->top + idx; 42 return L->top + idx;
41 } else if (idx == LUA_GLOBALSINDEX) { 43 } else if (idx == LUA_GLOBALSINDEX) {
42 TValue *o = &G(L)->tmptv; 44 TValue *o = &G(L)->tmptv;
@@ -46,7 +48,8 @@ static TValue *index2adr(lua_State *L, int idx)
46 return registry(L); 48 return registry(L);
47 } else { 49 } else {
48 GCfunc *fn = curr_func(L); 50 GCfunc *fn = curr_func(L);
49 api_check(L, fn->c.gct == ~LJ_TFUNC && !isluafunc(fn)); 51 lj_checkapi(fn->c.gct == ~LJ_TFUNC && !isluafunc(fn),
52 "calling frame is not a C function");
50 if (idx == LUA_ENVIRONINDEX) { 53 if (idx == LUA_ENVIRONINDEX) {
51 TValue *o = &G(L)->tmptv; 54 TValue *o = &G(L)->tmptv;
52 settabV(L, o, tabref(fn->c.env)); 55 settabV(L, o, tabref(fn->c.env));
@@ -58,13 +61,27 @@ static TValue *index2adr(lua_State *L, int idx)
58 } 61 }
59} 62}
60 63
61static TValue *stkindex2adr(lua_State *L, int idx) 64static LJ_AINLINE TValue *index2adr_check(lua_State *L, int idx)
65{
66 TValue *o = index2adr(L, idx);
67 lj_checkapi(o != niltv(L), "invalid stack slot %d", idx);
68 return o;
69}
70
71static TValue *index2adr_stack(lua_State *L, int idx)
62{ 72{
63 if (idx > 0) { 73 if (idx > 0) {
64 TValue *o = L->base + (idx - 1); 74 TValue *o = L->base + (idx - 1);
75 if (o < L->top) {
76 return o;
77 } else {
78 lj_checkapi(0, "invalid stack slot %d", idx);
79 return niltv(L);
80 }
65 return o < L->top ? o : niltv(L); 81 return o < L->top ? o : niltv(L);
66 } else { 82 } else {
67 api_check(L, idx != 0 && -idx <= L->top - L->base); 83 lj_checkapi(idx != 0 && -idx <= L->top - L->base,
84 "invalid stack slot %d", idx);
68 return L->top + idx; 85 return L->top + idx;
69 } 86 }
70} 87}
@@ -98,17 +115,24 @@ LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
98 lj_err_callerv(L, LJ_ERR_STKOVM, msg); 115 lj_err_callerv(L, LJ_ERR_STKOVM, msg);
99} 116}
100 117
101LUA_API void lua_xmove(lua_State *from, lua_State *to, int n) 118LUA_API void lua_xmove(lua_State *L, lua_State *to, int n)
102{ 119{
103 TValue *f, *t; 120 TValue *f, *t;
104 if (from == to) return; 121 if (L == to) return;
105 api_checknelems(from, n); 122 lj_checkapi_slot(n);
106 api_check(from, G(from) == G(to)); 123 lj_checkapi(G(L) == G(to), "move across global states");
107 lj_state_checkstack(to, (MSize)n); 124 lj_state_checkstack(to, (MSize)n);
108 f = from->top; 125 f = L->top;
109 t = to->top = to->top + n; 126 t = to->top = to->top + n;
110 while (--n >= 0) copyTV(to, --t, --f); 127 while (--n >= 0) copyTV(to, --t, --f);
111 from->top = f; 128 L->top = f;
129}
130
131LUA_API const lua_Number *lua_version(lua_State *L)
132{
133 static const lua_Number version = LUA_VERSION_NUM;
134 UNUSED(L);
135 return &version;
112} 136}
113 137
114/* -- Stack manipulation -------------------------------------------------- */ 138/* -- Stack manipulation -------------------------------------------------- */
@@ -121,7 +145,7 @@ LUA_API int lua_gettop(lua_State *L)
121LUA_API void lua_settop(lua_State *L, int idx) 145LUA_API void lua_settop(lua_State *L, int idx)
122{ 146{
123 if (idx >= 0) { 147 if (idx >= 0) {
124 api_check(L, idx <= tvref(L->maxstack) - L->base); 148 lj_checkapi(idx <= tvref(L->maxstack) - L->base, "bad stack slot %d", idx);
125 if (L->base + idx > L->top) { 149 if (L->base + idx > L->top) {
126 if (L->base + idx >= tvref(L->maxstack)) 150 if (L->base + idx >= tvref(L->maxstack))
127 lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base)); 151 lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
@@ -130,51 +154,58 @@ LUA_API void lua_settop(lua_State *L, int idx)
130 L->top = L->base + idx; 154 L->top = L->base + idx;
131 } 155 }
132 } else { 156 } else {
133 api_check(L, -(idx+1) <= (L->top - L->base)); 157 lj_checkapi(-(idx+1) <= (L->top - L->base), "bad stack slot %d", idx);
134 L->top += idx+1; /* Shrinks top (idx < 0). */ 158 L->top += idx+1; /* Shrinks top (idx < 0). */
135 } 159 }
136} 160}
137 161
138LUA_API void lua_remove(lua_State *L, int idx) 162LUA_API void lua_remove(lua_State *L, int idx)
139{ 163{
140 TValue *p = stkindex2adr(L, idx); 164 TValue *p = index2adr_stack(L, idx);
141 api_checkvalidindex(L, p);
142 while (++p < L->top) copyTV(L, p-1, p); 165 while (++p < L->top) copyTV(L, p-1, p);
143 L->top--; 166 L->top--;
144} 167}
145 168
146LUA_API void lua_insert(lua_State *L, int idx) 169LUA_API void lua_insert(lua_State *L, int idx)
147{ 170{
148 TValue *q, *p = stkindex2adr(L, idx); 171 TValue *q, *p = index2adr_stack(L, idx);
149 api_checkvalidindex(L, p);
150 for (q = L->top; q > p; q--) copyTV(L, q, q-1); 172 for (q = L->top; q > p; q--) copyTV(L, q, q-1);
151 copyTV(L, p, L->top); 173 copyTV(L, p, L->top);
152} 174}
153 175
154LUA_API void lua_replace(lua_State *L, int idx) 176static void copy_slot(lua_State *L, TValue *f, int idx)
155{ 177{
156 api_checknelems(L, 1);
157 if (idx == LUA_GLOBALSINDEX) { 178 if (idx == LUA_GLOBALSINDEX) {
158 api_check(L, tvistab(L->top-1)); 179 lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
159 /* NOBARRIER: A thread (i.e. L) is never black. */ 180 /* NOBARRIER: A thread (i.e. L) is never black. */
160 setgcref(L->env, obj2gco(tabV(L->top-1))); 181 setgcref(L->env, obj2gco(tabV(f)));
161 } else if (idx == LUA_ENVIRONINDEX) { 182 } else if (idx == LUA_ENVIRONINDEX) {
162 GCfunc *fn = curr_func(L); 183 GCfunc *fn = curr_func(L);
163 if (fn->c.gct != ~LJ_TFUNC) 184 if (fn->c.gct != ~LJ_TFUNC)
164 lj_err_msg(L, LJ_ERR_NOENV); 185 lj_err_msg(L, LJ_ERR_NOENV);
165 api_check(L, tvistab(L->top-1)); 186 lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
166 setgcref(fn->c.env, obj2gco(tabV(L->top-1))); 187 setgcref(fn->c.env, obj2gco(tabV(f)));
167 lj_gc_barrier(L, fn, L->top-1); 188 lj_gc_barrier(L, fn, f);
168 } else { 189 } else {
169 TValue *o = index2adr(L, idx); 190 TValue *o = index2adr_check(L, idx);
170 api_checkvalidindex(L, o); 191 copyTV(L, o, f);
171 copyTV(L, o, L->top-1);
172 if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */ 192 if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */
173 lj_gc_barrier(L, curr_func(L), L->top-1); 193 lj_gc_barrier(L, curr_func(L), f);
174 } 194 }
195}
196
197LUA_API void lua_replace(lua_State *L, int idx)
198{
199 lj_checkapi_slot(1);
200 copy_slot(L, L->top - 1, idx);
175 L->top--; 201 L->top--;
176} 202}
177 203
204LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
205{
206 copy_slot(L, index2adr(L, fromidx), toidx);
207}
208
178LUA_API void lua_pushvalue(lua_State *L, int idx) 209LUA_API void lua_pushvalue(lua_State *L, int idx)
179{ 210{
180 copyTV(L, L->top, index2adr(L, idx)); 211 copyTV(L, L->top, index2adr(L, idx));
@@ -188,7 +219,7 @@ LUA_API int lua_type(lua_State *L, int idx)
188 cTValue *o = index2adr(L, idx); 219 cTValue *o = index2adr(L, idx);
189 if (tvisnumber(o)) { 220 if (tvisnumber(o)) {
190 return LUA_TNUMBER; 221 return LUA_TNUMBER;
191#if LJ_64 222#if LJ_64 && !LJ_GC64
192 } else if (tvislightud(o)) { 223 } else if (tvislightud(o)) {
193 return LUA_TLIGHTUSERDATA; 224 return LUA_TLIGHTUSERDATA;
194#endif 225#endif
@@ -201,7 +232,7 @@ LUA_API int lua_type(lua_State *L, int idx)
201#else 232#else
202 int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u); 233 int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
203#endif 234#endif
204 lua_assert(tt != LUA_TNIL || tvisnil(o)); 235 lj_assertL(tt != LUA_TNIL || tvisnil(o), "bad tag conversion");
205 return tt; 236 return tt;
206 } 237 }
207} 238}
@@ -268,7 +299,7 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
268 return 0; 299 return 0;
269 } else if (tvispri(o1)) { 300 } else if (tvispri(o1)) {
270 return o1 != niltv(L) && o2 != niltv(L); 301 return o1 != niltv(L) && o2 != niltv(L);
271#if LJ_64 302#if LJ_64 && !LJ_GC64
272 } else if (tvislightud(o1)) { 303 } else if (tvislightud(o1)) {
273 return o1->u64 == o2->u64; 304 return o1->u64 == o2->u64;
274#endif 305#endif
@@ -283,8 +314,8 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
283 } else { 314 } else {
284 L->top = base+2; 315 L->top = base+2;
285 lj_vm_call(L, base, 1+1); 316 lj_vm_call(L, base, 1+1);
286 L->top -= 2; 317 L->top -= 2+LJ_FR2;
287 return tvistruecond(L->top+1); 318 return tvistruecond(L->top+1+LJ_FR2);
288 } 319 }
289 } 320 }
290} 321}
@@ -306,8 +337,8 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
306 } else { 337 } else {
307 L->top = base+2; 338 L->top = base+2;
308 lj_vm_call(L, base, 1+1); 339 lj_vm_call(L, base, 1+1);
309 L->top -= 2; 340 L->top -= 2+LJ_FR2;
310 return tvistruecond(L->top+1); 341 return tvistruecond(L->top+1+LJ_FR2);
311 } 342 }
312 } 343 }
313} 344}
@@ -324,6 +355,22 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
324 return 0; 355 return 0;
325} 356}
326 357
358LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok)
359{
360 cTValue *o = index2adr(L, idx);
361 TValue tmp;
362 if (LJ_LIKELY(tvisnumber(o))) {
363 if (ok) *ok = 1;
364 return numberVnum(o);
365 } else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) {
366 if (ok) *ok = 1;
367 return numV(&tmp);
368 } else {
369 if (ok) *ok = 0;
370 return 0;
371 }
372}
373
327LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx) 374LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
328{ 375{
329 cTValue *o = index2adr(L, idx); 376 cTValue *o = index2adr(L, idx);
@@ -361,9 +408,38 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
361 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) 408 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
362 return 0; 409 return 0;
363 if (tvisint(&tmp)) 410 if (tvisint(&tmp))
364 return (lua_Integer)intV(&tmp); 411 return intV(&tmp);
412 n = numV(&tmp);
413 }
414#if LJ_64
415 return (lua_Integer)n;
416#else
417 return lj_num2int(n);
418#endif
419}
420
421LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok)
422{
423 cTValue *o = index2adr(L, idx);
424 TValue tmp;
425 lua_Number n;
426 if (LJ_LIKELY(tvisint(o))) {
427 if (ok) *ok = 1;
428 return intV(o);
429 } else if (LJ_LIKELY(tvisnum(o))) {
430 n = numV(o);
431 } else {
432 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) {
433 if (ok) *ok = 0;
434 return 0;
435 }
436 if (tvisint(&tmp)) {
437 if (ok) *ok = 1;
438 return intV(&tmp);
439 }
365 n = numV(&tmp); 440 n = numV(&tmp);
366 } 441 }
442 if (ok) *ok = 1;
367#if LJ_64 443#if LJ_64
368 return (lua_Integer)n; 444 return (lua_Integer)n;
369#else 445#else
@@ -434,7 +510,7 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
434 } else if (tvisnumber(o)) { 510 } else if (tvisnumber(o)) {
435 lj_gc_check(L); 511 lj_gc_check(L);
436 o = index2adr(L, idx); /* GC may move the stack. */ 512 o = index2adr(L, idx); /* GC may move the stack. */
437 s = lj_str_fromnumber(L, o); 513 s = lj_strfmt_number(L, o);
438 setstrV(L, o, s); 514 setstrV(L, o, s);
439 } else { 515 } else {
440 if (len != NULL) *len = 0; 516 if (len != NULL) *len = 0;
@@ -453,7 +529,7 @@ LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
453 } else if (tvisnumber(o)) { 529 } else if (tvisnumber(o)) {
454 lj_gc_check(L); 530 lj_gc_check(L);
455 o = index2adr(L, idx); /* GC may move the stack. */ 531 o = index2adr(L, idx); /* GC may move the stack. */
456 s = lj_str_fromnumber(L, o); 532 s = lj_strfmt_number(L, o);
457 setstrV(L, o, s); 533 setstrV(L, o, s);
458 } else { 534 } else {
459 lj_err_argt(L, idx, LUA_TSTRING); 535 lj_err_argt(L, idx, LUA_TSTRING);
@@ -475,7 +551,7 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
475 } else if (tvisnumber(o)) { 551 } else if (tvisnumber(o)) {
476 lj_gc_check(L); 552 lj_gc_check(L);
477 o = index2adr(L, idx); /* GC may move the stack. */ 553 o = index2adr(L, idx); /* GC may move the stack. */
478 s = lj_str_fromnumber(L, o); 554 s = lj_strfmt_number(L, o);
479 setstrV(L, o, s); 555 setstrV(L, o, s);
480 } else { 556 } else {
481 lj_err_argt(L, idx, LUA_TSTRING); 557 lj_err_argt(L, idx, LUA_TSTRING);
@@ -507,7 +583,7 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
507 } else if (tvisudata(o)) { 583 } else if (tvisudata(o)) {
508 return udataV(o)->len; 584 return udataV(o)->len;
509 } else if (tvisnumber(o)) { 585 } else if (tvisnumber(o)) {
510 GCstr *s = lj_str_fromnumber(L, o); 586 GCstr *s = lj_strfmt_number(L, o);
511 setstrV(L, o, s); 587 setstrV(L, o, s);
512 return s->len; 588 return s->len;
513 } else { 589 } else {
@@ -532,7 +608,7 @@ LUA_API void *lua_touserdata(lua_State *L, int idx)
532 if (tvisudata(o)) 608 if (tvisudata(o))
533 return uddata(udataV(o)); 609 return uddata(udataV(o));
534 else if (tvislightud(o)) 610 else if (tvislightud(o))
535 return lightudV(o); 611 return lightudV(G(L), o);
536 else 612 else
537 return NULL; 613 return NULL;
538} 614}
@@ -545,17 +621,7 @@ LUA_API lua_State *lua_tothread(lua_State *L, int idx)
545 621
546LUA_API const void *lua_topointer(lua_State *L, int idx) 622LUA_API const void *lua_topointer(lua_State *L, int idx)
547{ 623{
548 cTValue *o = index2adr(L, idx); 624 return lj_obj_ptr(G(L), index2adr(L, idx));
549 if (tvisudata(o))
550 return uddata(udataV(o));
551 else if (tvislightud(o))
552 return lightudV(o);
553 else if (tviscdata(o))
554 return cdataptr(cdataV(o));
555 else if (tvisgcv(o))
556 return gcV(o);
557 else
558 return NULL;
559} 625}
560 626
561/* -- Stack setters (object creation) ------------------------------------- */ 627/* -- Stack setters (object creation) ------------------------------------- */
@@ -606,7 +672,7 @@ LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
606 va_list argp) 672 va_list argp)
607{ 673{
608 lj_gc_check(L); 674 lj_gc_check(L);
609 return lj_str_pushvf(L, fmt, argp); 675 return lj_strfmt_pushvf(L, fmt, argp);
610} 676}
611 677
612LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...) 678LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
@@ -615,7 +681,7 @@ LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
615 va_list argp; 681 va_list argp;
616 lj_gc_check(L); 682 lj_gc_check(L);
617 va_start(argp, fmt); 683 va_start(argp, fmt);
618 ret = lj_str_pushvf(L, fmt, argp); 684 ret = lj_strfmt_pushvf(L, fmt, argp);
619 va_end(argp); 685 va_end(argp);
620 return ret; 686 return ret;
621} 687}
@@ -624,14 +690,14 @@ LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
624{ 690{
625 GCfunc *fn; 691 GCfunc *fn;
626 lj_gc_check(L); 692 lj_gc_check(L);
627 api_checknelems(L, n); 693 lj_checkapi_slot(n);
628 fn = lj_func_newC(L, (MSize)n, getcurrenv(L)); 694 fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
629 fn->c.f = f; 695 fn->c.f = f;
630 L->top -= n; 696 L->top -= n;
631 while (n--) 697 while (n--)
632 copyTV(L, &fn->c.upvalue[n], L->top+n); 698 copyTV(L, &fn->c.upvalue[n], L->top+n);
633 setfuncV(L, L->top, fn); 699 setfuncV(L, L->top, fn);
634 lua_assert(iswhite(obj2gco(fn))); 700 lj_assertL(iswhite(obj2gco(fn)), "new GC object is not white");
635 incr_top(L); 701 incr_top(L);
636} 702}
637 703
@@ -643,16 +709,17 @@ LUA_API void lua_pushboolean(lua_State *L, int b)
643 709
644LUA_API void lua_pushlightuserdata(lua_State *L, void *p) 710LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
645{ 711{
646 setlightudV(L->top, checklightudptr(L, p)); 712#if LJ_64
713 p = lj_lightud_intern(L, p);
714#endif
715 setrawlightudV(L->top, p);
647 incr_top(L); 716 incr_top(L);
648} 717}
649 718
650LUA_API void lua_createtable(lua_State *L, int narray, int nrec) 719LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
651{ 720{
652 GCtab *t;
653 lj_gc_check(L); 721 lj_gc_check(L);
654 t = lj_tab_new(L, (uint32_t)(narray > 0 ? narray+1 : 0), hsize2hbits(nrec)); 722 settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
655 settabV(L, L->top, t);
656 incr_top(L); 723 incr_top(L);
657} 724}
658 725
@@ -703,7 +770,7 @@ LUA_API void *lua_newuserdata(lua_State *L, size_t size)
703 770
704LUA_API void lua_concat(lua_State *L, int n) 771LUA_API void lua_concat(lua_State *L, int n)
705{ 772{
706 api_checknelems(L, n); 773 lj_checkapi_slot(n);
707 if (n >= 2) { 774 if (n >= 2) {
708 n--; 775 n--;
709 do { 776 do {
@@ -715,8 +782,8 @@ LUA_API void lua_concat(lua_State *L, int n)
715 n -= (int)(L->top - top); 782 n -= (int)(L->top - top);
716 L->top = top+2; 783 L->top = top+2;
717 lj_vm_call(L, top, 1+1); 784 lj_vm_call(L, top, 1+1);
718 L->top--; 785 L->top -= 1+LJ_FR2;
719 copyTV(L, L->top-1, L->top); 786 copyTV(L, L->top-1, L->top+LJ_FR2);
720 } while (--n > 0); 787 } while (--n > 0);
721 } else if (n == 0) { /* Push empty string. */ 788 } else if (n == 0) { /* Push empty string. */
722 setstrV(L, L->top, &G(L)->strempty); 789 setstrV(L, L->top, &G(L)->strempty);
@@ -729,30 +796,28 @@ LUA_API void lua_concat(lua_State *L, int n)
729 796
730LUA_API void lua_gettable(lua_State *L, int idx) 797LUA_API void lua_gettable(lua_State *L, int idx)
731{ 798{
732 cTValue *v, *t = index2adr(L, idx); 799 cTValue *t = index2adr_check(L, idx);
733 api_checkvalidindex(L, t); 800 cTValue *v = lj_meta_tget(L, t, L->top-1);
734 v = lj_meta_tget(L, t, L->top-1);
735 if (v == NULL) { 801 if (v == NULL) {
736 L->top += 2; 802 L->top += 2;
737 lj_vm_call(L, L->top-2, 1+1); 803 lj_vm_call(L, L->top-2, 1+1);
738 L->top -= 2; 804 L->top -= 2+LJ_FR2;
739 v = L->top+1; 805 v = L->top+1+LJ_FR2;
740 } 806 }
741 copyTV(L, L->top-1, v); 807 copyTV(L, L->top-1, v);
742} 808}
743 809
744LUA_API void lua_getfield(lua_State *L, int idx, const char *k) 810LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
745{ 811{
746 cTValue *v, *t = index2adr(L, idx); 812 cTValue *v, *t = index2adr_check(L, idx);
747 TValue key; 813 TValue key;
748 api_checkvalidindex(L, t);
749 setstrV(L, &key, lj_str_newz(L, k)); 814 setstrV(L, &key, lj_str_newz(L, k));
750 v = lj_meta_tget(L, t, &key); 815 v = lj_meta_tget(L, t, &key);
751 if (v == NULL) { 816 if (v == NULL) {
752 L->top += 2; 817 L->top += 2;
753 lj_vm_call(L, L->top-2, 1+1); 818 lj_vm_call(L, L->top-2, 1+1);
754 L->top -= 2; 819 L->top -= 2+LJ_FR2;
755 v = L->top+1; 820 v = L->top+1+LJ_FR2;
756 } 821 }
757 copyTV(L, L->top, v); 822 copyTV(L, L->top, v);
758 incr_top(L); 823 incr_top(L);
@@ -761,14 +826,14 @@ LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
761LUA_API void lua_rawget(lua_State *L, int idx) 826LUA_API void lua_rawget(lua_State *L, int idx)
762{ 827{
763 cTValue *t = index2adr(L, idx); 828 cTValue *t = index2adr(L, idx);
764 api_check(L, tvistab(t)); 829 lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
765 copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1)); 830 copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
766} 831}
767 832
768LUA_API void lua_rawgeti(lua_State *L, int idx, int n) 833LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
769{ 834{
770 cTValue *v, *t = index2adr(L, idx); 835 cTValue *v, *t = index2adr(L, idx);
771 api_check(L, tvistab(t)); 836 lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
772 v = lj_tab_getint(tabV(t), n); 837 v = lj_tab_getint(tabV(t), n);
773 if (v) { 838 if (v) {
774 copyTV(L, L->top, v); 839 copyTV(L, L->top, v);
@@ -810,8 +875,7 @@ LUALIB_API int luaL_getmetafield(lua_State *L, int idx, const char *field)
810 875
811LUA_API void lua_getfenv(lua_State *L, int idx) 876LUA_API void lua_getfenv(lua_State *L, int idx)
812{ 877{
813 cTValue *o = index2adr(L, idx); 878 cTValue *o = index2adr_check(L, idx);
814 api_checkvalidindex(L, o);
815 if (tvisfunc(o)) { 879 if (tvisfunc(o)) {
816 settabV(L, L->top, tabref(funcV(o)->c.env)); 880 settabV(L, L->top, tabref(funcV(o)->c.env));
817 } else if (tvisudata(o)) { 881 } else if (tvisudata(o)) {
@@ -828,12 +892,14 @@ LUA_API int lua_next(lua_State *L, int idx)
828{ 892{
829 cTValue *t = index2adr(L, idx); 893 cTValue *t = index2adr(L, idx);
830 int more; 894 int more;
831 api_check(L, tvistab(t)); 895 lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
832 more = lj_tab_next(L, tabV(t), L->top-1); 896 more = lj_tab_next(tabV(t), L->top-1, L->top-1);
833 if (more) { 897 if (more > 0) {
834 incr_top(L); /* Return new key and value slot. */ 898 incr_top(L); /* Return new key and value slot. */
835 } else { /* End of traversal. */ 899 } else if (!more) { /* End of traversal. */
836 L->top--; /* Remove key slot. */ 900 L->top--; /* Remove key slot. */
901 } else {
902 lj_err_msg(L, LJ_ERR_NEXTIDX);
837 } 903 }
838 return more; 904 return more;
839} 905}
@@ -854,7 +920,7 @@ LUA_API void *lua_upvalueid(lua_State *L, int idx, int n)
854{ 920{
855 GCfunc *fn = funcV(index2adr(L, idx)); 921 GCfunc *fn = funcV(index2adr(L, idx));
856 n--; 922 n--;
857 api_check(L, (uint32_t)n < fn->l.nupvalues); 923 lj_checkapi((uint32_t)n < fn->l.nupvalues, "bad upvalue %d", n);
858 return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) : 924 return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
859 (void *)&fn->c.upvalue[n]; 925 (void *)&fn->c.upvalue[n];
860} 926}
@@ -864,13 +930,15 @@ LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
864 GCfunc *fn1 = funcV(index2adr(L, idx1)); 930 GCfunc *fn1 = funcV(index2adr(L, idx1));
865 GCfunc *fn2 = funcV(index2adr(L, idx2)); 931 GCfunc *fn2 = funcV(index2adr(L, idx2));
866 n1--; n2--; 932 n1--; n2--;
867 api_check(L, isluafunc(fn1) && (uint32_t)n1 < fn1->l.nupvalues); 933 lj_checkapi(isluafunc(fn1), "stack slot %d is not a Lua function", idx1);
868 api_check(L, isluafunc(fn2) && (uint32_t)n2 < fn2->l.nupvalues); 934 lj_checkapi(isluafunc(fn2), "stack slot %d is not a Lua function", idx2);
935 lj_checkapi((uint32_t)n1 < fn1->l.nupvalues, "bad upvalue %d", n1+1);
936 lj_checkapi((uint32_t)n2 < fn2->l.nupvalues, "bad upvalue %d", n2+1);
869 setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]); 937 setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]);
870 lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1])); 938 lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
871} 939}
872 940
873LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname) 941LUALIB_API void *luaL_testudata(lua_State *L, int idx, const char *tname)
874{ 942{
875 cTValue *o = index2adr(L, idx); 943 cTValue *o = index2adr(L, idx);
876 if (tvisudata(o)) { 944 if (tvisudata(o)) {
@@ -879,8 +947,14 @@ LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
879 if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable)) 947 if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
880 return uddata(ud); 948 return uddata(ud);
881 } 949 }
882 lj_err_argtype(L, idx, tname); 950 return NULL; /* value is not a userdata with a metatable */
883 return NULL; /* unreachable */ 951}
952
953LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
954{
955 void *p = luaL_testudata(L, idx, tname);
956 if (!p) lj_err_argtype(L, idx, tname);
957 return p;
884} 958}
885 959
886/* -- Object setters ------------------------------------------------------ */ 960/* -- Object setters ------------------------------------------------------ */
@@ -888,19 +962,19 @@ LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
888LUA_API void lua_settable(lua_State *L, int idx) 962LUA_API void lua_settable(lua_State *L, int idx)
889{ 963{
890 TValue *o; 964 TValue *o;
891 cTValue *t = index2adr(L, idx); 965 cTValue *t = index2adr_check(L, idx);
892 api_checknelems(L, 2); 966 lj_checkapi_slot(2);
893 api_checkvalidindex(L, t);
894 o = lj_meta_tset(L, t, L->top-2); 967 o = lj_meta_tset(L, t, L->top-2);
895 if (o) { 968 if (o) {
896 /* NOBARRIER: lj_meta_tset ensures the table is not black. */ 969 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
897 copyTV(L, o, L->top-1);
898 L->top -= 2; 970 L->top -= 2;
971 copyTV(L, o, L->top+1);
899 } else { 972 } else {
900 L->top += 3; 973 TValue *base = L->top;
901 copyTV(L, L->top-1, L->top-6); 974 copyTV(L, base+2, base-3-2*LJ_FR2);
902 lj_vm_call(L, L->top-3, 0+1); 975 L->top = base+3;
903 L->top -= 3; 976 lj_vm_call(L, base, 0+1);
977 L->top -= 3+LJ_FR2;
904 } 978 }
905} 979}
906 980
@@ -908,20 +982,19 @@ LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
908{ 982{
909 TValue *o; 983 TValue *o;
910 TValue key; 984 TValue key;
911 cTValue *t = index2adr(L, idx); 985 cTValue *t = index2adr_check(L, idx);
912 api_checknelems(L, 1); 986 lj_checkapi_slot(1);
913 api_checkvalidindex(L, t);
914 setstrV(L, &key, lj_str_newz(L, k)); 987 setstrV(L, &key, lj_str_newz(L, k));
915 o = lj_meta_tset(L, t, &key); 988 o = lj_meta_tset(L, t, &key);
916 if (o) { 989 if (o) {
917 L->top--;
918 /* NOBARRIER: lj_meta_tset ensures the table is not black. */ 990 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
919 copyTV(L, o, L->top); 991 copyTV(L, o, --L->top);
920 } else { 992 } else {
921 L->top += 3; 993 TValue *base = L->top;
922 copyTV(L, L->top-1, L->top-6); 994 copyTV(L, base+2, base-3-2*LJ_FR2);
923 lj_vm_call(L, L->top-3, 0+1); 995 L->top = base+3;
924 L->top -= 2; 996 lj_vm_call(L, base, 0+1);
997 L->top -= 2+LJ_FR2;
925 } 998 }
926} 999}
927 1000
@@ -929,7 +1002,7 @@ LUA_API void lua_rawset(lua_State *L, int idx)
929{ 1002{
930 GCtab *t = tabV(index2adr(L, idx)); 1003 GCtab *t = tabV(index2adr(L, idx));
931 TValue *dst, *key; 1004 TValue *dst, *key;
932 api_checknelems(L, 2); 1005 lj_checkapi_slot(2);
933 key = L->top-2; 1006 key = L->top-2;
934 dst = lj_tab_set(L, t, key); 1007 dst = lj_tab_set(L, t, key);
935 copyTV(L, dst, key+1); 1008 copyTV(L, dst, key+1);
@@ -941,7 +1014,7 @@ LUA_API void lua_rawseti(lua_State *L, int idx, int n)
941{ 1014{
942 GCtab *t = tabV(index2adr(L, idx)); 1015 GCtab *t = tabV(index2adr(L, idx));
943 TValue *dst, *src; 1016 TValue *dst, *src;
944 api_checknelems(L, 1); 1017 lj_checkapi_slot(1);
945 dst = lj_tab_setint(L, t, n); 1018 dst = lj_tab_setint(L, t, n);
946 src = L->top-1; 1019 src = L->top-1;
947 copyTV(L, dst, src); 1020 copyTV(L, dst, src);
@@ -953,13 +1026,12 @@ LUA_API int lua_setmetatable(lua_State *L, int idx)
953{ 1026{
954 global_State *g; 1027 global_State *g;
955 GCtab *mt; 1028 GCtab *mt;
956 cTValue *o = index2adr(L, idx); 1029 cTValue *o = index2adr_check(L, idx);
957 api_checknelems(L, 1); 1030 lj_checkapi_slot(1);
958 api_checkvalidindex(L, o);
959 if (tvisnil(L->top-1)) { 1031 if (tvisnil(L->top-1)) {
960 mt = NULL; 1032 mt = NULL;
961 } else { 1033 } else {
962 api_check(L, tvistab(L->top-1)); 1034 lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
963 mt = tabV(L->top-1); 1035 mt = tabV(L->top-1);
964 } 1036 }
965 g = G(L); 1037 g = G(L);
@@ -988,13 +1060,18 @@ LUA_API int lua_setmetatable(lua_State *L, int idx)
988 return 1; 1060 return 1;
989} 1061}
990 1062
1063LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
1064{
1065 lua_getfield(L, LUA_REGISTRYINDEX, tname);
1066 lua_setmetatable(L, -2);
1067}
1068
991LUA_API int lua_setfenv(lua_State *L, int idx) 1069LUA_API int lua_setfenv(lua_State *L, int idx)
992{ 1070{
993 cTValue *o = index2adr(L, idx); 1071 cTValue *o = index2adr_check(L, idx);
994 GCtab *t; 1072 GCtab *t;
995 api_checknelems(L, 1); 1073 lj_checkapi_slot(1);
996 api_checkvalidindex(L, o); 1074 lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
997 api_check(L, tvistab(L->top-1));
998 t = tabV(L->top-1); 1075 t = tabV(L->top-1);
999 if (tvisfunc(o)) { 1076 if (tvisfunc(o)) {
1000 setgcref(funcV(o)->c.env, obj2gco(t)); 1077 setgcref(funcV(o)->c.env, obj2gco(t));
@@ -1017,7 +1094,7 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1017 TValue *val; 1094 TValue *val;
1018 GCobj *o; 1095 GCobj *o;
1019 const char *name; 1096 const char *name;
1020 api_checknelems(L, 1); 1097 lj_checkapi_slot(1);
1021 name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o); 1098 name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o);
1022 if (name) { 1099 if (name) {
1023 L->top--; 1100 L->top--;
@@ -1029,11 +1106,25 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1029 1106
1030/* -- Calls --------------------------------------------------------------- */ 1107/* -- Calls --------------------------------------------------------------- */
1031 1108
1109#if LJ_FR2
1110static TValue *api_call_base(lua_State *L, int nargs)
1111{
1112 TValue *o = L->top, *base = o - nargs;
1113 L->top = o+1;
1114 for (; o > base; o--) copyTV(L, o, o-1);
1115 setnilV(o);
1116 return o+1;
1117}
1118#else
1119#define api_call_base(L, nargs) (L->top - (nargs))
1120#endif
1121
1032LUA_API void lua_call(lua_State *L, int nargs, int nresults) 1122LUA_API void lua_call(lua_State *L, int nargs, int nresults)
1033{ 1123{
1034 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1124 lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1035 api_checknelems(L, nargs+1); 1125 "thread called in wrong state %d", L->status);
1036 lj_vm_call(L, L->top - nargs, nresults+1); 1126 lj_checkapi_slot(nargs+1);
1127 lj_vm_call(L, api_call_base(L, nargs), nresults+1);
1037} 1128}
1038 1129
1039LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) 1130LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
@@ -1042,16 +1133,16 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1042 uint8_t oldh = hook_save(g); 1133 uint8_t oldh = hook_save(g);
1043 ptrdiff_t ef; 1134 ptrdiff_t ef;
1044 int status; 1135 int status;
1045 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1136 lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1046 api_checknelems(L, nargs+1); 1137 "thread called in wrong state %d", L->status);
1138 lj_checkapi_slot(nargs+1);
1047 if (errfunc == 0) { 1139 if (errfunc == 0) {
1048 ef = 0; 1140 ef = 0;
1049 } else { 1141 } else {
1050 cTValue *o = stkindex2adr(L, errfunc); 1142 cTValue *o = index2adr_stack(L, errfunc);
1051 api_checkvalidindex(L, o);
1052 ef = savestack(L, o); 1143 ef = savestack(L, o);
1053 } 1144 }
1054 status = lj_vm_pcall(L, L->top - nargs, nresults+1, ef); 1145 status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
1055 if (status) hook_restore(g, oldh); 1146 if (status) hook_restore(g, oldh);
1056 return status; 1147 return status;
1057} 1148}
@@ -1059,12 +1150,17 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1059static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud) 1150static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
1060{ 1151{
1061 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L)); 1152 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
1153 TValue *top = L->top;
1062 fn->c.f = func; 1154 fn->c.f = func;
1063 setfuncV(L, L->top, fn); 1155 setfuncV(L, top++, fn);
1064 setlightudV(L->top+1, checklightudptr(L, ud)); 1156 if (LJ_FR2) setnilV(top++);
1157#if LJ_64
1158 ud = lj_lightud_intern(L, ud);
1159#endif
1160 setrawlightudV(top++, ud);
1065 cframe_nres(L->cframe) = 1+0; /* Zero results. */ 1161 cframe_nres(L->cframe) = 1+0; /* Zero results. */
1066 L->top += 2; 1162 L->top = top;
1067 return L->top-1; /* Now call the newly allocated C function. */ 1163 return top-1; /* Now call the newly allocated C function. */
1068} 1164}
1069 1165
1070LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud) 1166LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
@@ -1072,7 +1168,8 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1072 global_State *g = G(L); 1168 global_State *g = G(L);
1073 uint8_t oldh = hook_save(g); 1169 uint8_t oldh = hook_save(g);
1074 int status; 1170 int status;
1075 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1171 lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1172 "thread called in wrong state %d", L->status);
1076 status = lj_vm_cpcall(L, func, ud, cpcall); 1173 status = lj_vm_cpcall(L, func, ud, cpcall);
1077 if (status) hook_restore(g, oldh); 1174 if (status) hook_restore(g, oldh);
1078 return status; 1175 return status;
@@ -1081,10 +1178,11 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1081LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field) 1178LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1082{ 1179{
1083 if (luaL_getmetafield(L, idx, field)) { 1180 if (luaL_getmetafield(L, idx, field)) {
1084 TValue *base = L->top--; 1181 TValue *top = L->top--;
1085 copyTV(L, base, index2adr(L, idx)); 1182 if (LJ_FR2) setnilV(top++);
1086 L->top = base+1; 1183 copyTV(L, top++, index2adr(L, idx));
1087 lj_vm_call(L, base, 1+1); 1184 L->top = top;
1185 lj_vm_call(L, top-1, 1+1);
1088 return 1; 1186 return 1;
1089 } 1187 }
1090 return 0; 1188 return 0;
@@ -1092,6 +1190,11 @@ LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1092 1190
1093/* -- Coroutine yield and resume ------------------------------------------ */ 1191/* -- Coroutine yield and resume ------------------------------------------ */
1094 1192
1193LUA_API int lua_isyieldable(lua_State *L)
1194{
1195 return cframe_canyield(L->cframe);
1196}
1197
1095LUA_API int lua_yield(lua_State *L, int nresults) 1198LUA_API int lua_yield(lua_State *L, int nresults)
1096{ 1199{
1097 void *cf = L->cframe; 1200 void *cf = L->cframe;
@@ -1111,13 +1214,16 @@ LUA_API int lua_yield(lua_State *L, int nresults)
1111 } else { /* Yield from hook: add a pseudo-frame. */ 1214 } else { /* Yield from hook: add a pseudo-frame. */
1112 TValue *top = L->top; 1215 TValue *top = L->top;
1113 hook_leave(g); 1216 hook_leave(g);
1114 top->u64 = cframe_multres(cf); 1217 (top++)->u64 = cframe_multres(cf);
1115 setcont(top+1, lj_cont_hook); 1218 setcont(top, lj_cont_hook);
1116 setframe_pc(top+1, cframe_pc(cf)-1); 1219 if (LJ_FR2) top++;
1117 setframe_gc(top+2, obj2gco(L)); 1220 setframe_pc(top, cframe_pc(cf)-1);
1118 setframe_ftsz(top+2, (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT); 1221 top++;
1119 L->top = L->base = top+3; 1222 setframe_gc(top, obj2gco(L), LJ_TTHREAD);
1120#if LJ_TARGET_X64 1223 if (LJ_FR2) top++;
1224 setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
1225 L->top = L->base = top+1;
1226#if ((defined(__GNUC__) || defined(__clang__)) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND) || LJ_TARGET_WINDOWS
1121 lj_err_throw(L, LUA_YIELD); 1227 lj_err_throw(L, LUA_YIELD);
1122#else 1228#else
1123 L->cframe = NULL; 1229 L->cframe = NULL;
@@ -1133,7 +1239,9 @@ LUA_API int lua_yield(lua_State *L, int nresults)
1133LUA_API int lua_resume(lua_State *L, int nargs) 1239LUA_API int lua_resume(lua_State *L, int nargs)
1134{ 1240{
1135 if (L->cframe == NULL && L->status <= LUA_YIELD) 1241 if (L->cframe == NULL && L->status <= LUA_YIELD)
1136 return lj_vm_resume(L, L->top - nargs, 0, 0); 1242 return lj_vm_resume(L,
1243 L->status == LUA_OK ? api_call_base(L, nargs) : L->top - nargs,
1244 0, 0);
1137 L->top = L->base; 1245 L->top = L->base;
1138 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP)); 1246 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
1139 incr_top(L); 1247 incr_top(L);
@@ -1163,7 +1271,7 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
1163 res = (int)(g->gc.total & 0x3ff); 1271 res = (int)(g->gc.total & 0x3ff);
1164 break; 1272 break;
1165 case LUA_GCSTEP: { 1273 case LUA_GCSTEP: {
1166 MSize a = (MSize)data << 10; 1274 GCSize a = (GCSize)data << 10;
1167 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0; 1275 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
1168 while (g->gc.total >= g->gc.threshold) 1276 while (g->gc.total >= g->gc.threshold)
1169 if (lj_gc_step(L) > 0) { 1277 if (lj_gc_step(L) > 0) {
@@ -1180,6 +1288,9 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
1180 res = (int)(g->gc.stepmul); 1288 res = (int)(g->gc.stepmul);
1181 g->gc.stepmul = (MSize)data; 1289 g->gc.stepmul = (MSize)data;
1182 break; 1290 break;
1291 case LUA_GCISRUNNING:
1292 res = (g->gc.threshold != LJ_MAX_MEM);
1293 break;
1183 default: 1294 default:
1184 res = -1; /* Invalid option. */ 1295 res = -1; /* Invalid option. */
1185 } 1296 }