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.c416
1 files changed, 258 insertions, 158 deletions
diff --git a/src/lj_api.c b/src/lj_api.c
index a99a81af..6369c17d 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}
@@ -87,7 +104,12 @@ LUA_API int lua_checkstack(lua_State *L, int size)
87 if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) { 104 if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) {
88 return 0; /* Stack overflow. */ 105 return 0; /* Stack overflow. */
89 } else if (size > 0) { 106 } else if (size > 0) {
90 lj_state_checkstack(L, (MSize)size); 107 int avail = (int)(mref(L->maxstack, TValue) - L->top);
108 if (size > avail &&
109 lj_state_cpgrowstack(L, (MSize)(size - avail)) != LUA_OK) {
110 L->top--;
111 return 0; /* Out of memory. */
112 }
91 } 113 }
92 return 1; 114 return 1;
93} 115}
@@ -98,17 +120,24 @@ LUALIB_API void luaL_checkstack(lua_State *L, int size, const char *msg)
98 lj_err_callerv(L, LJ_ERR_STKOVM, msg); 120 lj_err_callerv(L, LJ_ERR_STKOVM, msg);
99} 121}
100 122
101LUA_API void lua_xmove(lua_State *from, lua_State *to, int n) 123LUA_API void lua_xmove(lua_State *L, lua_State *to, int n)
102{ 124{
103 TValue *f, *t; 125 TValue *f, *t;
104 if (from == to) return; 126 if (L == to) return;
105 api_checknelems(from, n); 127 lj_checkapi_slot(n);
106 api_check(from, G(from) == G(to)); 128 lj_checkapi(G(L) == G(to), "move across global states");
107 lj_state_checkstack(to, (MSize)n); 129 lj_state_checkstack(to, (MSize)n);
108 f = from->top; 130 f = L->top;
109 t = to->top = to->top + n; 131 t = to->top = to->top + n;
110 while (--n >= 0) copyTV(to, --t, --f); 132 while (--n >= 0) copyTV(to, --t, --f);
111 from->top = f; 133 L->top = f;
134}
135
136LUA_API const lua_Number *lua_version(lua_State *L)
137{
138 static const lua_Number version = LUA_VERSION_NUM;
139 UNUSED(L);
140 return &version;
112} 141}
113 142
114/* -- Stack manipulation -------------------------------------------------- */ 143/* -- Stack manipulation -------------------------------------------------- */
@@ -121,7 +150,7 @@ LUA_API int lua_gettop(lua_State *L)
121LUA_API void lua_settop(lua_State *L, int idx) 150LUA_API void lua_settop(lua_State *L, int idx)
122{ 151{
123 if (idx >= 0) { 152 if (idx >= 0) {
124 api_check(L, idx <= tvref(L->maxstack) - L->base); 153 lj_checkapi(idx <= tvref(L->maxstack) - L->base, "bad stack slot %d", idx);
125 if (L->base + idx > L->top) { 154 if (L->base + idx > L->top) {
126 if (L->base + idx >= tvref(L->maxstack)) 155 if (L->base + idx >= tvref(L->maxstack))
127 lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base)); 156 lj_state_growstack(L, (MSize)idx - (MSize)(L->top - L->base));
@@ -130,51 +159,58 @@ LUA_API void lua_settop(lua_State *L, int idx)
130 L->top = L->base + idx; 159 L->top = L->base + idx;
131 } 160 }
132 } else { 161 } else {
133 api_check(L, -(idx+1) <= (L->top - L->base)); 162 lj_checkapi(-(idx+1) <= (L->top - L->base), "bad stack slot %d", idx);
134 L->top += idx+1; /* Shrinks top (idx < 0). */ 163 L->top += idx+1; /* Shrinks top (idx < 0). */
135 } 164 }
136} 165}
137 166
138LUA_API void lua_remove(lua_State *L, int idx) 167LUA_API void lua_remove(lua_State *L, int idx)
139{ 168{
140 TValue *p = stkindex2adr(L, idx); 169 TValue *p = index2adr_stack(L, idx);
141 api_checkvalidindex(L, p);
142 while (++p < L->top) copyTV(L, p-1, p); 170 while (++p < L->top) copyTV(L, p-1, p);
143 L->top--; 171 L->top--;
144} 172}
145 173
146LUA_API void lua_insert(lua_State *L, int idx) 174LUA_API void lua_insert(lua_State *L, int idx)
147{ 175{
148 TValue *q, *p = stkindex2adr(L, idx); 176 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); 177 for (q = L->top; q > p; q--) copyTV(L, q, q-1);
151 copyTV(L, p, L->top); 178 copyTV(L, p, L->top);
152} 179}
153 180
154LUA_API void lua_replace(lua_State *L, int idx) 181static void copy_slot(lua_State *L, TValue *f, int idx)
155{ 182{
156 api_checknelems(L, 1);
157 if (idx == LUA_GLOBALSINDEX) { 183 if (idx == LUA_GLOBALSINDEX) {
158 api_check(L, tvistab(L->top-1)); 184 lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
159 /* NOBARRIER: A thread (i.e. L) is never black. */ 185 /* NOBARRIER: A thread (i.e. L) is never black. */
160 setgcref(L->env, obj2gco(tabV(L->top-1))); 186 setgcref(L->env, obj2gco(tabV(f)));
161 } else if (idx == LUA_ENVIRONINDEX) { 187 } else if (idx == LUA_ENVIRONINDEX) {
162 GCfunc *fn = curr_func(L); 188 GCfunc *fn = curr_func(L);
163 if (fn->c.gct != ~LJ_TFUNC) 189 if (fn->c.gct != ~LJ_TFUNC)
164 lj_err_msg(L, LJ_ERR_NOENV); 190 lj_err_msg(L, LJ_ERR_NOENV);
165 api_check(L, tvistab(L->top-1)); 191 lj_checkapi(tvistab(f), "stack slot %d is not a table", idx);
166 setgcref(fn->c.env, obj2gco(tabV(L->top-1))); 192 setgcref(fn->c.env, obj2gco(tabV(f)));
167 lj_gc_barrier(L, fn, L->top-1); 193 lj_gc_barrier(L, fn, f);
168 } else { 194 } else {
169 TValue *o = index2adr(L, idx); 195 TValue *o = index2adr_check(L, idx);
170 api_checkvalidindex(L, o); 196 copyTV(L, o, f);
171 copyTV(L, o, L->top-1);
172 if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */ 197 if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */
173 lj_gc_barrier(L, curr_func(L), L->top-1); 198 lj_gc_barrier(L, curr_func(L), f);
174 } 199 }
200}
201
202LUA_API void lua_replace(lua_State *L, int idx)
203{
204 lj_checkapi_slot(1);
205 copy_slot(L, L->top - 1, idx);
175 L->top--; 206 L->top--;
176} 207}
177 208
209LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
210{
211 copy_slot(L, index2adr(L, fromidx), toidx);
212}
213
178LUA_API void lua_pushvalue(lua_State *L, int idx) 214LUA_API void lua_pushvalue(lua_State *L, int idx)
179{ 215{
180 copyTV(L, L->top, index2adr(L, idx)); 216 copyTV(L, L->top, index2adr(L, idx));
@@ -188,7 +224,7 @@ LUA_API int lua_type(lua_State *L, int idx)
188 cTValue *o = index2adr(L, idx); 224 cTValue *o = index2adr(L, idx);
189 if (tvisnumber(o)) { 225 if (tvisnumber(o)) {
190 return LUA_TNUMBER; 226 return LUA_TNUMBER;
191#if LJ_64 227#if LJ_64 && !LJ_GC64
192 } else if (tvislightud(o)) { 228 } else if (tvislightud(o)) {
193 return LUA_TLIGHTUSERDATA; 229 return LUA_TLIGHTUSERDATA;
194#endif 230#endif
@@ -201,7 +237,7 @@ LUA_API int lua_type(lua_State *L, int idx)
201#else 237#else
202 int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u); 238 int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
203#endif 239#endif
204 lua_assert(tt != LUA_TNIL || tvisnil(o)); 240 lj_assertL(tt != LUA_TNIL || tvisnil(o), "bad tag conversion");
205 return tt; 241 return tt;
206 } 242 }
207} 243}
@@ -268,7 +304,7 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
268 return 0; 304 return 0;
269 } else if (tvispri(o1)) { 305 } else if (tvispri(o1)) {
270 return o1 != niltv(L) && o2 != niltv(L); 306 return o1 != niltv(L) && o2 != niltv(L);
271#if LJ_64 307#if LJ_64 && !LJ_GC64
272 } else if (tvislightud(o1)) { 308 } else if (tvislightud(o1)) {
273 return o1->u64 == o2->u64; 309 return o1->u64 == o2->u64;
274#endif 310#endif
@@ -283,8 +319,8 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
283 } else { 319 } else {
284 L->top = base+2; 320 L->top = base+2;
285 lj_vm_call(L, base, 1+1); 321 lj_vm_call(L, base, 1+1);
286 L->top -= 2; 322 L->top -= 2+LJ_FR2;
287 return tvistruecond(L->top+1); 323 return tvistruecond(L->top+1+LJ_FR2);
288 } 324 }
289 } 325 }
290} 326}
@@ -306,8 +342,8 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
306 } else { 342 } else {
307 L->top = base+2; 343 L->top = base+2;
308 lj_vm_call(L, base, 1+1); 344 lj_vm_call(L, base, 1+1);
309 L->top -= 2; 345 L->top -= 2+LJ_FR2;
310 return tvistruecond(L->top+1); 346 return tvistruecond(L->top+1+LJ_FR2);
311 } 347 }
312 } 348 }
313} 349}
@@ -324,6 +360,22 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
324 return 0; 360 return 0;
325} 361}
326 362
363LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok)
364{
365 cTValue *o = index2adr(L, idx);
366 TValue tmp;
367 if (LJ_LIKELY(tvisnumber(o))) {
368 if (ok) *ok = 1;
369 return numberVnum(o);
370 } else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) {
371 if (ok) *ok = 1;
372 return numV(&tmp);
373 } else {
374 if (ok) *ok = 0;
375 return 0;
376 }
377}
378
327LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx) 379LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
328{ 380{
329 cTValue *o = index2adr(L, idx); 381 cTValue *o = index2adr(L, idx);
@@ -361,14 +413,35 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
361 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) 413 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
362 return 0; 414 return 0;
363 if (tvisint(&tmp)) 415 if (tvisint(&tmp))
364 return (lua_Integer)intV(&tmp); 416 return intV(&tmp);
365 n = numV(&tmp); 417 n = numV(&tmp);
366 } 418 }
367#if LJ_64 419 return lj_num2int_type(n, lua_Integer);
368 return (lua_Integer)n; 420}
369#else 421
370 return lj_num2int(n); 422LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok)
371#endif 423{
424 cTValue *o = index2adr(L, idx);
425 TValue tmp;
426 lua_Number n;
427 if (LJ_LIKELY(tvisint(o))) {
428 if (ok) *ok = 1;
429 return intV(o);
430 } else if (LJ_LIKELY(tvisnum(o))) {
431 n = numV(o);
432 } else {
433 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) {
434 if (ok) *ok = 0;
435 return 0;
436 }
437 if (tvisint(&tmp)) {
438 if (ok) *ok = 1;
439 return intV(&tmp);
440 }
441 n = numV(&tmp);
442 }
443 if (ok) *ok = 1;
444 return lj_num2int_type(n, lua_Integer);
372} 445}
373 446
374LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx) 447LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
@@ -387,11 +460,7 @@ LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int idx)
387 return (lua_Integer)intV(&tmp); 460 return (lua_Integer)intV(&tmp);
388 n = numV(&tmp); 461 n = numV(&tmp);
389 } 462 }
390#if LJ_64 463 return lj_num2int_type(n, lua_Integer);
391 return (lua_Integer)n;
392#else
393 return lj_num2int(n);
394#endif
395} 464}
396 465
397LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def) 466LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
@@ -412,11 +481,7 @@ LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int idx, lua_Integer def)
412 return (lua_Integer)intV(&tmp); 481 return (lua_Integer)intV(&tmp);
413 n = numV(&tmp); 482 n = numV(&tmp);
414 } 483 }
415#if LJ_64 484 return lj_num2int_type(n, lua_Integer);
416 return (lua_Integer)n;
417#else
418 return lj_num2int(n);
419#endif
420} 485}
421 486
422LUA_API int lua_toboolean(lua_State *L, int idx) 487LUA_API int lua_toboolean(lua_State *L, int idx)
@@ -434,7 +499,7 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
434 } else if (tvisnumber(o)) { 499 } else if (tvisnumber(o)) {
435 lj_gc_check(L); 500 lj_gc_check(L);
436 o = index2adr(L, idx); /* GC may move the stack. */ 501 o = index2adr(L, idx); /* GC may move the stack. */
437 s = lj_str_fromnumber(L, o); 502 s = lj_strfmt_number(L, o);
438 setstrV(L, o, s); 503 setstrV(L, o, s);
439 } else { 504 } else {
440 if (len != NULL) *len = 0; 505 if (len != NULL) *len = 0;
@@ -453,7 +518,7 @@ LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
453 } else if (tvisnumber(o)) { 518 } else if (tvisnumber(o)) {
454 lj_gc_check(L); 519 lj_gc_check(L);
455 o = index2adr(L, idx); /* GC may move the stack. */ 520 o = index2adr(L, idx); /* GC may move the stack. */
456 s = lj_str_fromnumber(L, o); 521 s = lj_strfmt_number(L, o);
457 setstrV(L, o, s); 522 setstrV(L, o, s);
458 } else { 523 } else {
459 lj_err_argt(L, idx, LUA_TSTRING); 524 lj_err_argt(L, idx, LUA_TSTRING);
@@ -475,7 +540,7 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
475 } else if (tvisnumber(o)) { 540 } else if (tvisnumber(o)) {
476 lj_gc_check(L); 541 lj_gc_check(L);
477 o = index2adr(L, idx); /* GC may move the stack. */ 542 o = index2adr(L, idx); /* GC may move the stack. */
478 s = lj_str_fromnumber(L, o); 543 s = lj_strfmt_number(L, o);
479 setstrV(L, o, s); 544 setstrV(L, o, s);
480 } else { 545 } else {
481 lj_err_argt(L, idx, LUA_TSTRING); 546 lj_err_argt(L, idx, LUA_TSTRING);
@@ -507,7 +572,7 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
507 } else if (tvisudata(o)) { 572 } else if (tvisudata(o)) {
508 return udataV(o)->len; 573 return udataV(o)->len;
509 } else if (tvisnumber(o)) { 574 } else if (tvisnumber(o)) {
510 GCstr *s = lj_str_fromnumber(L, o); 575 GCstr *s = lj_strfmt_number(L, o);
511 setstrV(L, o, s); 576 setstrV(L, o, s);
512 return s->len; 577 return s->len;
513 } else { 578 } else {
@@ -532,7 +597,7 @@ LUA_API void *lua_touserdata(lua_State *L, int idx)
532 if (tvisudata(o)) 597 if (tvisudata(o))
533 return uddata(udataV(o)); 598 return uddata(udataV(o));
534 else if (tvislightud(o)) 599 else if (tvislightud(o))
535 return lightudV(o); 600 return lightudV(G(L), o);
536 else 601 else
537 return NULL; 602 return NULL;
538} 603}
@@ -545,17 +610,7 @@ LUA_API lua_State *lua_tothread(lua_State *L, int idx)
545 610
546LUA_API const void *lua_topointer(lua_State *L, int idx) 611LUA_API const void *lua_topointer(lua_State *L, int idx)
547{ 612{
548 cTValue *o = index2adr(L, idx); 613 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} 614}
560 615
561/* -- Stack setters (object creation) ------------------------------------- */ 616/* -- Stack setters (object creation) ------------------------------------- */
@@ -606,7 +661,7 @@ LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
606 va_list argp) 661 va_list argp)
607{ 662{
608 lj_gc_check(L); 663 lj_gc_check(L);
609 return lj_str_pushvf(L, fmt, argp); 664 return lj_strfmt_pushvf(L, fmt, argp);
610} 665}
611 666
612LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...) 667LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
@@ -615,7 +670,7 @@ LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
615 va_list argp; 670 va_list argp;
616 lj_gc_check(L); 671 lj_gc_check(L);
617 va_start(argp, fmt); 672 va_start(argp, fmt);
618 ret = lj_str_pushvf(L, fmt, argp); 673 ret = lj_strfmt_pushvf(L, fmt, argp);
619 va_end(argp); 674 va_end(argp);
620 return ret; 675 return ret;
621} 676}
@@ -624,14 +679,14 @@ LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction f, int n)
624{ 679{
625 GCfunc *fn; 680 GCfunc *fn;
626 lj_gc_check(L); 681 lj_gc_check(L);
627 api_checknelems(L, n); 682 lj_checkapi_slot(n);
628 fn = lj_func_newC(L, (MSize)n, getcurrenv(L)); 683 fn = lj_func_newC(L, (MSize)n, getcurrenv(L));
629 fn->c.f = f; 684 fn->c.f = f;
630 L->top -= n; 685 L->top -= n;
631 while (n--) 686 while (n--)
632 copyTV(L, &fn->c.upvalue[n], L->top+n); 687 copyTV(L, &fn->c.upvalue[n], L->top+n);
633 setfuncV(L, L->top, fn); 688 setfuncV(L, L->top, fn);
634 lua_assert(iswhite(obj2gco(fn))); 689 lj_assertL(iswhite(obj2gco(fn)), "new GC object is not white");
635 incr_top(L); 690 incr_top(L);
636} 691}
637 692
@@ -643,16 +698,17 @@ LUA_API void lua_pushboolean(lua_State *L, int b)
643 698
644LUA_API void lua_pushlightuserdata(lua_State *L, void *p) 699LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
645{ 700{
646 setlightudV(L->top, checklightudptr(L, p)); 701#if LJ_64
702 p = lj_lightud_intern(L, p);
703#endif
704 setrawlightudV(L->top, p);
647 incr_top(L); 705 incr_top(L);
648} 706}
649 707
650LUA_API void lua_createtable(lua_State *L, int narray, int nrec) 708LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
651{ 709{
652 GCtab *t;
653 lj_gc_check(L); 710 lj_gc_check(L);
654 t = lj_tab_new(L, (uint32_t)(narray > 0 ? narray+1 : 0), hsize2hbits(nrec)); 711 settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
655 settabV(L, L->top, t);
656 incr_top(L); 712 incr_top(L);
657} 713}
658 714
@@ -703,7 +759,7 @@ LUA_API void *lua_newuserdata(lua_State *L, size_t size)
703 759
704LUA_API void lua_concat(lua_State *L, int n) 760LUA_API void lua_concat(lua_State *L, int n)
705{ 761{
706 api_checknelems(L, n); 762 lj_checkapi_slot(n);
707 if (n >= 2) { 763 if (n >= 2) {
708 n--; 764 n--;
709 do { 765 do {
@@ -712,11 +768,11 @@ LUA_API void lua_concat(lua_State *L, int n)
712 L->top -= n; 768 L->top -= n;
713 break; 769 break;
714 } 770 }
715 n -= (int)(L->top - top); 771 n -= (int)(L->top - (top - 2*LJ_FR2));
716 L->top = top+2; 772 L->top = top+2;
717 lj_vm_call(L, top, 1+1); 773 lj_vm_call(L, top, 1+1);
718 L->top--; 774 L->top -= 1+LJ_FR2;
719 copyTV(L, L->top-1, L->top); 775 copyTV(L, L->top-1, L->top+LJ_FR2);
720 } while (--n > 0); 776 } while (--n > 0);
721 } else if (n == 0) { /* Push empty string. */ 777 } else if (n == 0) { /* Push empty string. */
722 setstrV(L, L->top, &G(L)->strempty); 778 setstrV(L, L->top, &G(L)->strempty);
@@ -729,30 +785,28 @@ LUA_API void lua_concat(lua_State *L, int n)
729 785
730LUA_API void lua_gettable(lua_State *L, int idx) 786LUA_API void lua_gettable(lua_State *L, int idx)
731{ 787{
732 cTValue *v, *t = index2adr(L, idx); 788 cTValue *t = index2adr_check(L, idx);
733 api_checkvalidindex(L, t); 789 cTValue *v = lj_meta_tget(L, t, L->top-1);
734 v = lj_meta_tget(L, t, L->top-1);
735 if (v == NULL) { 790 if (v == NULL) {
736 L->top += 2; 791 L->top += 2;
737 lj_vm_call(L, L->top-2, 1+1); 792 lj_vm_call(L, L->top-2, 1+1);
738 L->top -= 2; 793 L->top -= 2+LJ_FR2;
739 v = L->top+1; 794 v = L->top+1+LJ_FR2;
740 } 795 }
741 copyTV(L, L->top-1, v); 796 copyTV(L, L->top-1, v);
742} 797}
743 798
744LUA_API void lua_getfield(lua_State *L, int idx, const char *k) 799LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
745{ 800{
746 cTValue *v, *t = index2adr(L, idx); 801 cTValue *v, *t = index2adr_check(L, idx);
747 TValue key; 802 TValue key;
748 api_checkvalidindex(L, t);
749 setstrV(L, &key, lj_str_newz(L, k)); 803 setstrV(L, &key, lj_str_newz(L, k));
750 v = lj_meta_tget(L, t, &key); 804 v = lj_meta_tget(L, t, &key);
751 if (v == NULL) { 805 if (v == NULL) {
752 L->top += 2; 806 L->top += 2;
753 lj_vm_call(L, L->top-2, 1+1); 807 lj_vm_call(L, L->top-2, 1+1);
754 L->top -= 2; 808 L->top -= 2+LJ_FR2;
755 v = L->top+1; 809 v = L->top+1+LJ_FR2;
756 } 810 }
757 copyTV(L, L->top, v); 811 copyTV(L, L->top, v);
758 incr_top(L); 812 incr_top(L);
@@ -761,14 +815,14 @@ LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
761LUA_API void lua_rawget(lua_State *L, int idx) 815LUA_API void lua_rawget(lua_State *L, int idx)
762{ 816{
763 cTValue *t = index2adr(L, idx); 817 cTValue *t = index2adr(L, idx);
764 api_check(L, tvistab(t)); 818 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)); 819 copyTV(L, L->top-1, lj_tab_get(L, tabV(t), L->top-1));
766} 820}
767 821
768LUA_API void lua_rawgeti(lua_State *L, int idx, int n) 822LUA_API void lua_rawgeti(lua_State *L, int idx, int n)
769{ 823{
770 cTValue *v, *t = index2adr(L, idx); 824 cTValue *v, *t = index2adr(L, idx);
771 api_check(L, tvistab(t)); 825 lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
772 v = lj_tab_getint(tabV(t), n); 826 v = lj_tab_getint(tabV(t), n);
773 if (v) { 827 if (v) {
774 copyTV(L, L->top, v); 828 copyTV(L, L->top, v);
@@ -810,8 +864,7 @@ LUALIB_API int luaL_getmetafield(lua_State *L, int idx, const char *field)
810 864
811LUA_API void lua_getfenv(lua_State *L, int idx) 865LUA_API void lua_getfenv(lua_State *L, int idx)
812{ 866{
813 cTValue *o = index2adr(L, idx); 867 cTValue *o = index2adr_check(L, idx);
814 api_checkvalidindex(L, o);
815 if (tvisfunc(o)) { 868 if (tvisfunc(o)) {
816 settabV(L, L->top, tabref(funcV(o)->c.env)); 869 settabV(L, L->top, tabref(funcV(o)->c.env));
817 } else if (tvisudata(o)) { 870 } else if (tvisudata(o)) {
@@ -828,12 +881,14 @@ LUA_API int lua_next(lua_State *L, int idx)
828{ 881{
829 cTValue *t = index2adr(L, idx); 882 cTValue *t = index2adr(L, idx);
830 int more; 883 int more;
831 api_check(L, tvistab(t)); 884 lj_checkapi(tvistab(t), "stack slot %d is not a table", idx);
832 more = lj_tab_next(L, tabV(t), L->top-1); 885 more = lj_tab_next(tabV(t), L->top-1, L->top-1);
833 if (more) { 886 if (more > 0) {
834 incr_top(L); /* Return new key and value slot. */ 887 incr_top(L); /* Return new key and value slot. */
835 } else { /* End of traversal. */ 888 } else if (!more) { /* End of traversal. */
836 L->top--; /* Remove key slot. */ 889 L->top--; /* Remove key slot. */
890 } else {
891 lj_err_msg(L, LJ_ERR_NEXTIDX);
837 } 892 }
838 return more; 893 return more;
839} 894}
@@ -854,7 +909,7 @@ LUA_API void *lua_upvalueid(lua_State *L, int idx, int n)
854{ 909{
855 GCfunc *fn = funcV(index2adr(L, idx)); 910 GCfunc *fn = funcV(index2adr(L, idx));
856 n--; 911 n--;
857 api_check(L, (uint32_t)n < fn->l.nupvalues); 912 lj_checkapi((uint32_t)n < fn->l.nupvalues, "bad upvalue %d", n);
858 return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) : 913 return isluafunc(fn) ? (void *)gcref(fn->l.uvptr[n]) :
859 (void *)&fn->c.upvalue[n]; 914 (void *)&fn->c.upvalue[n];
860} 915}
@@ -864,13 +919,15 @@ LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
864 GCfunc *fn1 = funcV(index2adr(L, idx1)); 919 GCfunc *fn1 = funcV(index2adr(L, idx1));
865 GCfunc *fn2 = funcV(index2adr(L, idx2)); 920 GCfunc *fn2 = funcV(index2adr(L, idx2));
866 n1--; n2--; 921 n1--; n2--;
867 api_check(L, isluafunc(fn1) && (uint32_t)n1 < fn1->l.nupvalues); 922 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); 923 lj_checkapi(isluafunc(fn2), "stack slot %d is not a Lua function", idx2);
924 lj_checkapi((uint32_t)n1 < fn1->l.nupvalues, "bad upvalue %d", n1+1);
925 lj_checkapi((uint32_t)n2 < fn2->l.nupvalues, "bad upvalue %d", n2+1);
869 setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]); 926 setgcrefr(fn1->l.uvptr[n1], fn2->l.uvptr[n2]);
870 lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1])); 927 lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
871} 928}
872 929
873LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname) 930LUALIB_API void *luaL_testudata(lua_State *L, int idx, const char *tname)
874{ 931{
875 cTValue *o = index2adr(L, idx); 932 cTValue *o = index2adr(L, idx);
876 if (tvisudata(o)) { 933 if (tvisudata(o)) {
@@ -879,8 +936,14 @@ LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
879 if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable)) 936 if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
880 return uddata(ud); 937 return uddata(ud);
881 } 938 }
882 lj_err_argtype(L, idx, tname); 939 return NULL; /* value is not a userdata with a metatable */
883 return NULL; /* unreachable */ 940}
941
942LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
943{
944 void *p = luaL_testudata(L, idx, tname);
945 if (!p) lj_err_argtype(L, idx, tname);
946 return p;
884} 947}
885 948
886/* -- Object setters ------------------------------------------------------ */ 949/* -- Object setters ------------------------------------------------------ */
@@ -888,19 +951,19 @@ LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
888LUA_API void lua_settable(lua_State *L, int idx) 951LUA_API void lua_settable(lua_State *L, int idx)
889{ 952{
890 TValue *o; 953 TValue *o;
891 cTValue *t = index2adr(L, idx); 954 cTValue *t = index2adr_check(L, idx);
892 api_checknelems(L, 2); 955 lj_checkapi_slot(2);
893 api_checkvalidindex(L, t);
894 o = lj_meta_tset(L, t, L->top-2); 956 o = lj_meta_tset(L, t, L->top-2);
895 if (o) { 957 if (o) {
896 /* NOBARRIER: lj_meta_tset ensures the table is not black. */ 958 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
897 copyTV(L, o, L->top-1);
898 L->top -= 2; 959 L->top -= 2;
960 copyTV(L, o, L->top+1);
899 } else { 961 } else {
900 L->top += 3; 962 TValue *base = L->top;
901 copyTV(L, L->top-1, L->top-6); 963 copyTV(L, base+2, base-3-2*LJ_FR2);
902 lj_vm_call(L, L->top-3, 0+1); 964 L->top = base+3;
903 L->top -= 3; 965 lj_vm_call(L, base, 0+1);
966 L->top -= 3+LJ_FR2;
904 } 967 }
905} 968}
906 969
@@ -908,20 +971,19 @@ LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
908{ 971{
909 TValue *o; 972 TValue *o;
910 TValue key; 973 TValue key;
911 cTValue *t = index2adr(L, idx); 974 cTValue *t = index2adr_check(L, idx);
912 api_checknelems(L, 1); 975 lj_checkapi_slot(1);
913 api_checkvalidindex(L, t);
914 setstrV(L, &key, lj_str_newz(L, k)); 976 setstrV(L, &key, lj_str_newz(L, k));
915 o = lj_meta_tset(L, t, &key); 977 o = lj_meta_tset(L, t, &key);
916 if (o) { 978 if (o) {
917 L->top--;
918 /* NOBARRIER: lj_meta_tset ensures the table is not black. */ 979 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
919 copyTV(L, o, L->top); 980 copyTV(L, o, --L->top);
920 } else { 981 } else {
921 L->top += 3; 982 TValue *base = L->top;
922 copyTV(L, L->top-1, L->top-6); 983 copyTV(L, base+2, base-3-2*LJ_FR2);
923 lj_vm_call(L, L->top-3, 0+1); 984 L->top = base+3;
924 L->top -= 2; 985 lj_vm_call(L, base, 0+1);
986 L->top -= 2+LJ_FR2;
925 } 987 }
926} 988}
927 989
@@ -929,7 +991,7 @@ LUA_API void lua_rawset(lua_State *L, int idx)
929{ 991{
930 GCtab *t = tabV(index2adr(L, idx)); 992 GCtab *t = tabV(index2adr(L, idx));
931 TValue *dst, *key; 993 TValue *dst, *key;
932 api_checknelems(L, 2); 994 lj_checkapi_slot(2);
933 key = L->top-2; 995 key = L->top-2;
934 dst = lj_tab_set(L, t, key); 996 dst = lj_tab_set(L, t, key);
935 copyTV(L, dst, key+1); 997 copyTV(L, dst, key+1);
@@ -941,7 +1003,7 @@ LUA_API void lua_rawseti(lua_State *L, int idx, int n)
941{ 1003{
942 GCtab *t = tabV(index2adr(L, idx)); 1004 GCtab *t = tabV(index2adr(L, idx));
943 TValue *dst, *src; 1005 TValue *dst, *src;
944 api_checknelems(L, 1); 1006 lj_checkapi_slot(1);
945 dst = lj_tab_setint(L, t, n); 1007 dst = lj_tab_setint(L, t, n);
946 src = L->top-1; 1008 src = L->top-1;
947 copyTV(L, dst, src); 1009 copyTV(L, dst, src);
@@ -953,13 +1015,12 @@ LUA_API int lua_setmetatable(lua_State *L, int idx)
953{ 1015{
954 global_State *g; 1016 global_State *g;
955 GCtab *mt; 1017 GCtab *mt;
956 cTValue *o = index2adr(L, idx); 1018 cTValue *o = index2adr_check(L, idx);
957 api_checknelems(L, 1); 1019 lj_checkapi_slot(1);
958 api_checkvalidindex(L, o);
959 if (tvisnil(L->top-1)) { 1020 if (tvisnil(L->top-1)) {
960 mt = NULL; 1021 mt = NULL;
961 } else { 1022 } else {
962 api_check(L, tvistab(L->top-1)); 1023 lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
963 mt = tabV(L->top-1); 1024 mt = tabV(L->top-1);
964 } 1025 }
965 g = G(L); 1026 g = G(L);
@@ -989,13 +1050,18 @@ LUA_API int lua_setmetatable(lua_State *L, int idx)
989 return 1; 1050 return 1;
990} 1051}
991 1052
1053LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
1054{
1055 lua_getfield(L, LUA_REGISTRYINDEX, tname);
1056 lua_setmetatable(L, -2);
1057}
1058
992LUA_API int lua_setfenv(lua_State *L, int idx) 1059LUA_API int lua_setfenv(lua_State *L, int idx)
993{ 1060{
994 cTValue *o = index2adr(L, idx); 1061 cTValue *o = index2adr_check(L, idx);
995 GCtab *t; 1062 GCtab *t;
996 api_checknelems(L, 1); 1063 lj_checkapi_slot(1);
997 api_checkvalidindex(L, o); 1064 lj_checkapi(tvistab(L->top-1), "top stack slot is not a table");
998 api_check(L, tvistab(L->top-1));
999 t = tabV(L->top-1); 1065 t = tabV(L->top-1);
1000 if (tvisfunc(o)) { 1066 if (tvisfunc(o)) {
1001 setgcref(funcV(o)->c.env, obj2gco(t)); 1067 setgcref(funcV(o)->c.env, obj2gco(t));
@@ -1018,7 +1084,7 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1018 TValue *val; 1084 TValue *val;
1019 GCobj *o; 1085 GCobj *o;
1020 const char *name; 1086 const char *name;
1021 api_checknelems(L, 1); 1087 lj_checkapi_slot(1);
1022 name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o); 1088 name = lj_debug_uvnamev(f, (uint32_t)(n-1), &val, &o);
1023 if (name) { 1089 if (name) {
1024 L->top--; 1090 L->top--;
@@ -1030,11 +1096,25 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1030 1096
1031/* -- Calls --------------------------------------------------------------- */ 1097/* -- Calls --------------------------------------------------------------- */
1032 1098
1099#if LJ_FR2
1100static TValue *api_call_base(lua_State *L, int nargs)
1101{
1102 TValue *o = L->top, *base = o - nargs;
1103 L->top = o+1;
1104 for (; o > base; o--) copyTV(L, o, o-1);
1105 setnilV(o);
1106 return o+1;
1107}
1108#else
1109#define api_call_base(L, nargs) (L->top - (nargs))
1110#endif
1111
1033LUA_API void lua_call(lua_State *L, int nargs, int nresults) 1112LUA_API void lua_call(lua_State *L, int nargs, int nresults)
1034{ 1113{
1035 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1114 lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1036 api_checknelems(L, nargs+1); 1115 "thread called in wrong state %d", L->status);
1037 lj_vm_call(L, L->top - nargs, nresults+1); 1116 lj_checkapi_slot(nargs+1);
1117 lj_vm_call(L, api_call_base(L, nargs), nresults+1);
1038} 1118}
1039 1119
1040LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) 1120LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
@@ -1043,16 +1123,16 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1043 uint8_t oldh = hook_save(g); 1123 uint8_t oldh = hook_save(g);
1044 ptrdiff_t ef; 1124 ptrdiff_t ef;
1045 int status; 1125 int status;
1046 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1126 lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1047 api_checknelems(L, nargs+1); 1127 "thread called in wrong state %d", L->status);
1128 lj_checkapi_slot(nargs+1);
1048 if (errfunc == 0) { 1129 if (errfunc == 0) {
1049 ef = 0; 1130 ef = 0;
1050 } else { 1131 } else {
1051 cTValue *o = stkindex2adr(L, errfunc); 1132 cTValue *o = index2adr_stack(L, errfunc);
1052 api_checkvalidindex(L, o);
1053 ef = savestack(L, o); 1133 ef = savestack(L, o);
1054 } 1134 }
1055 status = lj_vm_pcall(L, L->top - nargs, nresults+1, ef); 1135 status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
1056 if (status) hook_restore(g, oldh); 1136 if (status) hook_restore(g, oldh);
1057 return status; 1137 return status;
1058} 1138}
@@ -1060,12 +1140,17 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1060static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud) 1140static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
1061{ 1141{
1062 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L)); 1142 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
1143 TValue *top = L->top;
1063 fn->c.f = func; 1144 fn->c.f = func;
1064 setfuncV(L, L->top, fn); 1145 setfuncV(L, top++, fn);
1065 setlightudV(L->top+1, checklightudptr(L, ud)); 1146 if (LJ_FR2) setnilV(top++);
1147#if LJ_64
1148 ud = lj_lightud_intern(L, ud);
1149#endif
1150 setrawlightudV(top++, ud);
1066 cframe_nres(L->cframe) = 1+0; /* Zero results. */ 1151 cframe_nres(L->cframe) = 1+0; /* Zero results. */
1067 L->top += 2; 1152 L->top = top;
1068 return L->top-1; /* Now call the newly allocated C function. */ 1153 return top-1; /* Now call the newly allocated C function. */
1069} 1154}
1070 1155
1071LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud) 1156LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
@@ -1073,7 +1158,8 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1073 global_State *g = G(L); 1158 global_State *g = G(L);
1074 uint8_t oldh = hook_save(g); 1159 uint8_t oldh = hook_save(g);
1075 int status; 1160 int status;
1076 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1161 lj_checkapi(L->status == LUA_OK || L->status == LUA_ERRERR,
1162 "thread called in wrong state %d", L->status);
1077 status = lj_vm_cpcall(L, func, ud, cpcall); 1163 status = lj_vm_cpcall(L, func, ud, cpcall);
1078 if (status) hook_restore(g, oldh); 1164 if (status) hook_restore(g, oldh);
1079 return status; 1165 return status;
@@ -1082,10 +1168,11 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1082LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field) 1168LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1083{ 1169{
1084 if (luaL_getmetafield(L, idx, field)) { 1170 if (luaL_getmetafield(L, idx, field)) {
1085 TValue *base = L->top--; 1171 TValue *top = L->top--;
1086 copyTV(L, base, index2adr(L, idx)); 1172 if (LJ_FR2) setnilV(top++);
1087 L->top = base+1; 1173 copyTV(L, top++, index2adr(L, idx));
1088 lj_vm_call(L, base, 1+1); 1174 L->top = top;
1175 lj_vm_call(L, top-1, 1+1);
1089 return 1; 1176 return 1;
1090 } 1177 }
1091 return 0; 1178 return 0;
@@ -1093,6 +1180,11 @@ LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1093 1180
1094/* -- Coroutine yield and resume ------------------------------------------ */ 1181/* -- Coroutine yield and resume ------------------------------------------ */
1095 1182
1183LUA_API int lua_isyieldable(lua_State *L)
1184{
1185 return cframe_canyield(L->cframe);
1186}
1187
1096LUA_API int lua_yield(lua_State *L, int nresults) 1188LUA_API int lua_yield(lua_State *L, int nresults)
1097{ 1189{
1098 void *cf = L->cframe; 1190 void *cf = L->cframe;
@@ -1112,13 +1204,16 @@ LUA_API int lua_yield(lua_State *L, int nresults)
1112 } else { /* Yield from hook: add a pseudo-frame. */ 1204 } else { /* Yield from hook: add a pseudo-frame. */
1113 TValue *top = L->top; 1205 TValue *top = L->top;
1114 hook_leave(g); 1206 hook_leave(g);
1115 top->u64 = cframe_multres(cf); 1207 (top++)->u64 = cframe_multres(cf);
1116 setcont(top+1, lj_cont_hook); 1208 setcont(top, lj_cont_hook);
1117 setframe_pc(top+1, cframe_pc(cf)-1); 1209 if (LJ_FR2) top++;
1118 setframe_gc(top+2, obj2gco(L)); 1210 setframe_pc(top, cframe_pc(cf)-1);
1119 setframe_ftsz(top+2, (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT); 1211 top++;
1120 L->top = L->base = top+3; 1212 setframe_gc(top, obj2gco(L), LJ_TTHREAD);
1121#if LJ_TARGET_X64 1213 if (LJ_FR2) top++;
1214 setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
1215 L->top = L->base = top+1;
1216#if ((defined(__GNUC__) || defined(__clang__)) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL)) && !LJ_NO_UNWIND) || LJ_TARGET_WINDOWS
1122 lj_err_throw(L, LUA_YIELD); 1217 lj_err_throw(L, LUA_YIELD);
1123#else 1218#else
1124 L->cframe = NULL; 1219 L->cframe = NULL;
@@ -1134,7 +1229,9 @@ LUA_API int lua_yield(lua_State *L, int nresults)
1134LUA_API int lua_resume(lua_State *L, int nargs) 1229LUA_API int lua_resume(lua_State *L, int nargs)
1135{ 1230{
1136 if (L->cframe == NULL && L->status <= LUA_YIELD) 1231 if (L->cframe == NULL && L->status <= LUA_YIELD)
1137 return lj_vm_resume(L, L->top - nargs, 0, 0); 1232 return lj_vm_resume(L,
1233 L->status == LUA_OK ? api_call_base(L, nargs) : L->top - nargs,
1234 0, 0);
1138 L->top = L->base; 1235 L->top = L->base;
1139 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP)); 1236 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
1140 incr_top(L); 1237 incr_top(L);
@@ -1164,7 +1261,7 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
1164 res = (int)(g->gc.total & 0x3ff); 1261 res = (int)(g->gc.total & 0x3ff);
1165 break; 1262 break;
1166 case LUA_GCSTEP: { 1263 case LUA_GCSTEP: {
1167 MSize a = (MSize)data << 10; 1264 GCSize a = (GCSize)data << 10;
1168 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0; 1265 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
1169 while (g->gc.total >= g->gc.threshold) 1266 while (g->gc.total >= g->gc.threshold)
1170 if (lj_gc_step(L) > 0) { 1267 if (lj_gc_step(L) > 0) {
@@ -1181,6 +1278,9 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
1181 res = (int)(g->gc.stepmul); 1278 res = (int)(g->gc.stepmul);
1182 g->gc.stepmul = (MSize)data; 1279 g->gc.stepmul = (MSize)data;
1183 break; 1280 break;
1281 case LUA_GCISRUNNING:
1282 res = (g->gc.threshold != LJ_MAX_MEM);
1283 break;
1184 default: 1284 default:
1185 res = -1; /* Invalid option. */ 1285 res = -1; /* Invalid option. */
1186 } 1286 }