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.c246
1 files changed, 169 insertions, 77 deletions
diff --git a/src/lj_api.c b/src/lj_api.c
index e2d7e533..974b5643 100644
--- a/src/lj_api.c
+++ b/src/lj_api.c
@@ -24,6 +24,7 @@
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
@@ -111,6 +112,13 @@ LUA_API void lua_xmove(lua_State *from, lua_State *to, int n)
111 from->top = f; 112 from->top = f;
112} 113}
113 114
115LUA_API const lua_Number *lua_version(lua_State *L)
116{
117 static const lua_Number version = LUA_VERSION_NUM;
118 UNUSED(L);
119 return &version;
120}
121
114/* -- Stack manipulation -------------------------------------------------- */ 122/* -- Stack manipulation -------------------------------------------------- */
115 123
116LUA_API int lua_gettop(lua_State *L) 124LUA_API int lua_gettop(lua_State *L)
@@ -151,30 +159,40 @@ LUA_API void lua_insert(lua_State *L, int idx)
151 copyTV(L, p, L->top); 159 copyTV(L, p, L->top);
152} 160}
153 161
154LUA_API void lua_replace(lua_State *L, int idx) 162static void copy_slot(lua_State *L, TValue *f, int idx)
155{ 163{
156 api_checknelems(L, 1);
157 if (idx == LUA_GLOBALSINDEX) { 164 if (idx == LUA_GLOBALSINDEX) {
158 api_check(L, tvistab(L->top-1)); 165 api_check(L, tvistab(f));
159 /* NOBARRIER: A thread (i.e. L) is never black. */ 166 /* NOBARRIER: A thread (i.e. L) is never black. */
160 setgcref(L->env, obj2gco(tabV(L->top-1))); 167 setgcref(L->env, obj2gco(tabV(f)));
161 } else if (idx == LUA_ENVIRONINDEX) { 168 } else if (idx == LUA_ENVIRONINDEX) {
162 GCfunc *fn = curr_func(L); 169 GCfunc *fn = curr_func(L);
163 if (fn->c.gct != ~LJ_TFUNC) 170 if (fn->c.gct != ~LJ_TFUNC)
164 lj_err_msg(L, LJ_ERR_NOENV); 171 lj_err_msg(L, LJ_ERR_NOENV);
165 api_check(L, tvistab(L->top-1)); 172 api_check(L, tvistab(f));
166 setgcref(fn->c.env, obj2gco(tabV(L->top-1))); 173 setgcref(fn->c.env, obj2gco(tabV(f)));
167 lj_gc_barrier(L, fn, L->top-1); 174 lj_gc_barrier(L, fn, f);
168 } else { 175 } else {
169 TValue *o = index2adr(L, idx); 176 TValue *o = index2adr(L, idx);
170 api_checkvalidindex(L, o); 177 api_checkvalidindex(L, o);
171 copyTV(L, o, L->top-1); 178 copyTV(L, o, f);
172 if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */ 179 if (idx < LUA_GLOBALSINDEX) /* Need a barrier for upvalues. */
173 lj_gc_barrier(L, curr_func(L), L->top-1); 180 lj_gc_barrier(L, curr_func(L), f);
174 } 181 }
182}
183
184LUA_API void lua_replace(lua_State *L, int idx)
185{
186 api_checknelems(L, 1);
187 copy_slot(L, L->top - 1, idx);
175 L->top--; 188 L->top--;
176} 189}
177 190
191LUA_API void lua_copy(lua_State *L, int fromidx, int toidx)
192{
193 copy_slot(L, index2adr(L, fromidx), toidx);
194}
195
178LUA_API void lua_pushvalue(lua_State *L, int idx) 196LUA_API void lua_pushvalue(lua_State *L, int idx)
179{ 197{
180 copyTV(L, L->top, index2adr(L, idx)); 198 copyTV(L, L->top, index2adr(L, idx));
@@ -188,7 +206,7 @@ LUA_API int lua_type(lua_State *L, int idx)
188 cTValue *o = index2adr(L, idx); 206 cTValue *o = index2adr(L, idx);
189 if (tvisnumber(o)) { 207 if (tvisnumber(o)) {
190 return LUA_TNUMBER; 208 return LUA_TNUMBER;
191#if LJ_64 209#if LJ_64 && !LJ_GC64
192 } else if (tvislightud(o)) { 210 } else if (tvislightud(o)) {
193 return LUA_TLIGHTUSERDATA; 211 return LUA_TLIGHTUSERDATA;
194#endif 212#endif
@@ -268,7 +286,7 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
268 return 0; 286 return 0;
269 } else if (tvispri(o1)) { 287 } else if (tvispri(o1)) {
270 return o1 != niltv(L) && o2 != niltv(L); 288 return o1 != niltv(L) && o2 != niltv(L);
271#if LJ_64 289#if LJ_64 && !LJ_GC64
272 } else if (tvislightud(o1)) { 290 } else if (tvislightud(o1)) {
273 return o1->u64 == o2->u64; 291 return o1->u64 == o2->u64;
274#endif 292#endif
@@ -283,8 +301,8 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
283 } else { 301 } else {
284 L->top = base+2; 302 L->top = base+2;
285 lj_vm_call(L, base, 1+1); 303 lj_vm_call(L, base, 1+1);
286 L->top -= 2; 304 L->top -= 2+LJ_FR2;
287 return tvistruecond(L->top+1); 305 return tvistruecond(L->top+1+LJ_FR2);
288 } 306 }
289 } 307 }
290} 308}
@@ -306,8 +324,8 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
306 } else { 324 } else {
307 L->top = base+2; 325 L->top = base+2;
308 lj_vm_call(L, base, 1+1); 326 lj_vm_call(L, base, 1+1);
309 L->top -= 2; 327 L->top -= 2+LJ_FR2;
310 return tvistruecond(L->top+1); 328 return tvistruecond(L->top+1+LJ_FR2);
311 } 329 }
312 } 330 }
313} 331}
@@ -324,6 +342,22 @@ LUA_API lua_Number lua_tonumber(lua_State *L, int idx)
324 return 0; 342 return 0;
325} 343}
326 344
345LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *ok)
346{
347 cTValue *o = index2adr(L, idx);
348 TValue tmp;
349 if (LJ_LIKELY(tvisnumber(o))) {
350 if (ok) *ok = 1;
351 return numberVnum(o);
352 } else if (tvisstr(o) && lj_strscan_num(strV(o), &tmp)) {
353 if (ok) *ok = 1;
354 return numV(&tmp);
355 } else {
356 if (ok) *ok = 0;
357 return 0;
358 }
359}
360
327LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx) 361LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx)
328{ 362{
329 cTValue *o = index2adr(L, idx); 363 cTValue *o = index2adr(L, idx);
@@ -361,9 +395,38 @@ LUA_API lua_Integer lua_tointeger(lua_State *L, int idx)
361 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) 395 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp)))
362 return 0; 396 return 0;
363 if (tvisint(&tmp)) 397 if (tvisint(&tmp))
364 return (lua_Integer)intV(&tmp); 398 return intV(&tmp);
399 n = numV(&tmp);
400 }
401#if LJ_64
402 return (lua_Integer)n;
403#else
404 return lj_num2int(n);
405#endif
406}
407
408LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *ok)
409{
410 cTValue *o = index2adr(L, idx);
411 TValue tmp;
412 lua_Number n;
413 if (LJ_LIKELY(tvisint(o))) {
414 if (ok) *ok = 1;
415 return intV(o);
416 } else if (LJ_LIKELY(tvisnum(o))) {
417 n = numV(o);
418 } else {
419 if (!(tvisstr(o) && lj_strscan_number(strV(o), &tmp))) {
420 if (ok) *ok = 0;
421 return 0;
422 }
423 if (tvisint(&tmp)) {
424 if (ok) *ok = 1;
425 return intV(&tmp);
426 }
365 n = numV(&tmp); 427 n = numV(&tmp);
366 } 428 }
429 if (ok) *ok = 1;
367#if LJ_64 430#if LJ_64
368 return (lua_Integer)n; 431 return (lua_Integer)n;
369#else 432#else
@@ -434,7 +497,7 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
434 } else if (tvisnumber(o)) { 497 } else if (tvisnumber(o)) {
435 lj_gc_check(L); 498 lj_gc_check(L);
436 o = index2adr(L, idx); /* GC may move the stack. */ 499 o = index2adr(L, idx); /* GC may move the stack. */
437 s = lj_str_fromnumber(L, o); 500 s = lj_strfmt_number(L, o);
438 setstrV(L, o, s); 501 setstrV(L, o, s);
439 } else { 502 } else {
440 if (len != NULL) *len = 0; 503 if (len != NULL) *len = 0;
@@ -453,7 +516,7 @@ LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
453 } else if (tvisnumber(o)) { 516 } else if (tvisnumber(o)) {
454 lj_gc_check(L); 517 lj_gc_check(L);
455 o = index2adr(L, idx); /* GC may move the stack. */ 518 o = index2adr(L, idx); /* GC may move the stack. */
456 s = lj_str_fromnumber(L, o); 519 s = lj_strfmt_number(L, o);
457 setstrV(L, o, s); 520 setstrV(L, o, s);
458 } else { 521 } else {
459 lj_err_argt(L, idx, LUA_TSTRING); 522 lj_err_argt(L, idx, LUA_TSTRING);
@@ -475,7 +538,7 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
475 } else if (tvisnumber(o)) { 538 } else if (tvisnumber(o)) {
476 lj_gc_check(L); 539 lj_gc_check(L);
477 o = index2adr(L, idx); /* GC may move the stack. */ 540 o = index2adr(L, idx); /* GC may move the stack. */
478 s = lj_str_fromnumber(L, o); 541 s = lj_strfmt_number(L, o);
479 setstrV(L, o, s); 542 setstrV(L, o, s);
480 } else { 543 } else {
481 lj_err_argt(L, idx, LUA_TSTRING); 544 lj_err_argt(L, idx, LUA_TSTRING);
@@ -507,7 +570,7 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
507 } else if (tvisudata(o)) { 570 } else if (tvisudata(o)) {
508 return udataV(o)->len; 571 return udataV(o)->len;
509 } else if (tvisnumber(o)) { 572 } else if (tvisnumber(o)) {
510 GCstr *s = lj_str_fromnumber(L, o); 573 GCstr *s = lj_strfmt_number(L, o);
511 setstrV(L, o, s); 574 setstrV(L, o, s);
512 return s->len; 575 return s->len;
513 } else { 576 } else {
@@ -545,17 +608,7 @@ LUA_API lua_State *lua_tothread(lua_State *L, int idx)
545 608
546LUA_API const void *lua_topointer(lua_State *L, int idx) 609LUA_API const void *lua_topointer(lua_State *L, int idx)
547{ 610{
548 cTValue *o = index2adr(L, idx); 611 return lj_obj_ptr(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} 612}
560 613
561/* -- Stack setters (object creation) ------------------------------------- */ 614/* -- Stack setters (object creation) ------------------------------------- */
@@ -606,7 +659,7 @@ LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
606 va_list argp) 659 va_list argp)
607{ 660{
608 lj_gc_check(L); 661 lj_gc_check(L);
609 return lj_str_pushvf(L, fmt, argp); 662 return lj_strfmt_pushvf(L, fmt, argp);
610} 663}
611 664
612LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...) 665LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
@@ -615,7 +668,7 @@ LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
615 va_list argp; 668 va_list argp;
616 lj_gc_check(L); 669 lj_gc_check(L);
617 va_start(argp, fmt); 670 va_start(argp, fmt);
618 ret = lj_str_pushvf(L, fmt, argp); 671 ret = lj_strfmt_pushvf(L, fmt, argp);
619 va_end(argp); 672 va_end(argp);
620 return ret; 673 return ret;
621} 674}
@@ -649,10 +702,8 @@ LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
649 702
650LUA_API void lua_createtable(lua_State *L, int narray, int nrec) 703LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
651{ 704{
652 GCtab *t;
653 lj_gc_check(L); 705 lj_gc_check(L);
654 t = lj_tab_new(L, (uint32_t)(narray > 0 ? narray+1 : 0), hsize2hbits(nrec)); 706 settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
655 settabV(L, L->top, t);
656 incr_top(L); 707 incr_top(L);
657} 708}
658 709
@@ -715,8 +766,8 @@ LUA_API void lua_concat(lua_State *L, int n)
715 n -= (int)(L->top - top); 766 n -= (int)(L->top - top);
716 L->top = top+2; 767 L->top = top+2;
717 lj_vm_call(L, top, 1+1); 768 lj_vm_call(L, top, 1+1);
718 L->top--; 769 L->top -= 1+LJ_FR2;
719 copyTV(L, L->top-1, L->top); 770 copyTV(L, L->top-1, L->top+LJ_FR2);
720 } while (--n > 0); 771 } while (--n > 0);
721 } else if (n == 0) { /* Push empty string. */ 772 } else if (n == 0) { /* Push empty string. */
722 setstrV(L, L->top, &G(L)->strempty); 773 setstrV(L, L->top, &G(L)->strempty);
@@ -735,8 +786,8 @@ LUA_API void lua_gettable(lua_State *L, int idx)
735 if (v == NULL) { 786 if (v == NULL) {
736 L->top += 2; 787 L->top += 2;
737 lj_vm_call(L, L->top-2, 1+1); 788 lj_vm_call(L, L->top-2, 1+1);
738 L->top -= 2; 789 L->top -= 2+LJ_FR2;
739 v = L->top+1; 790 v = L->top+1+LJ_FR2;
740 } 791 }
741 copyTV(L, L->top-1, v); 792 copyTV(L, L->top-1, v);
742} 793}
@@ -751,8 +802,8 @@ LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
751 if (v == NULL) { 802 if (v == NULL) {
752 L->top += 2; 803 L->top += 2;
753 lj_vm_call(L, L->top-2, 1+1); 804 lj_vm_call(L, L->top-2, 1+1);
754 L->top -= 2; 805 L->top -= 2+LJ_FR2;
755 v = L->top+1; 806 v = L->top+1+LJ_FR2;
756 } 807 }
757 copyTV(L, L->top, v); 808 copyTV(L, L->top, v);
758 incr_top(L); 809 incr_top(L);
@@ -869,7 +920,7 @@ LUA_API void lua_upvaluejoin(lua_State *L, int idx1, int n1, int idx2, int n2)
869 lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1])); 920 lj_gc_objbarrier(L, fn1, gcref(fn1->l.uvptr[n1]));
870} 921}
871 922
872LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname) 923LUALIB_API void *luaL_testudata(lua_State *L, int idx, const char *tname)
873{ 924{
874 cTValue *o = index2adr(L, idx); 925 cTValue *o = index2adr(L, idx);
875 if (tvisudata(o)) { 926 if (tvisudata(o)) {
@@ -878,8 +929,14 @@ LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
878 if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable)) 929 if (tv && tvistab(tv) && tabV(tv) == tabref(ud->metatable))
879 return uddata(ud); 930 return uddata(ud);
880 } 931 }
881 lj_err_argtype(L, idx, tname); 932 return NULL; /* value is not a userdata with a metatable */
882 return NULL; /* unreachable */ 933}
934
935LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname)
936{
937 void *p = luaL_testudata(L, idx, tname);
938 if (!p) lj_err_argtype(L, idx, tname);
939 return p;
883} 940}
884 941
885/* -- Object setters ------------------------------------------------------ */ 942/* -- Object setters ------------------------------------------------------ */
@@ -893,13 +950,14 @@ LUA_API void lua_settable(lua_State *L, int idx)
893 o = lj_meta_tset(L, t, L->top-2); 950 o = lj_meta_tset(L, t, L->top-2);
894 if (o) { 951 if (o) {
895 /* NOBARRIER: lj_meta_tset ensures the table is not black. */ 952 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
896 copyTV(L, o, L->top-1);
897 L->top -= 2; 953 L->top -= 2;
954 copyTV(L, o, L->top+1);
898 } else { 955 } else {
899 L->top += 3; 956 TValue *base = L->top;
900 copyTV(L, L->top-1, L->top-6); 957 copyTV(L, base+2, base-3-2*LJ_FR2);
901 lj_vm_call(L, L->top-3, 0+1); 958 L->top = base+3;
902 L->top -= 3; 959 lj_vm_call(L, base, 0+1);
960 L->top -= 3+LJ_FR2;
903 } 961 }
904} 962}
905 963
@@ -913,14 +971,14 @@ LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
913 setstrV(L, &key, lj_str_newz(L, k)); 971 setstrV(L, &key, lj_str_newz(L, k));
914 o = lj_meta_tset(L, t, &key); 972 o = lj_meta_tset(L, t, &key);
915 if (o) { 973 if (o) {
916 L->top--;
917 /* NOBARRIER: lj_meta_tset ensures the table is not black. */ 974 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
918 copyTV(L, o, L->top); 975 copyTV(L, o, --L->top);
919 } else { 976 } else {
920 L->top += 3; 977 TValue *base = L->top;
921 copyTV(L, L->top-1, L->top-6); 978 copyTV(L, base+2, base-3-2*LJ_FR2);
922 lj_vm_call(L, L->top-3, 0+1); 979 L->top = base+3;
923 L->top -= 2; 980 lj_vm_call(L, base, 0+1);
981 L->top -= 2+LJ_FR2;
924 } 982 }
925} 983}
926 984
@@ -987,6 +1045,12 @@ LUA_API int lua_setmetatable(lua_State *L, int idx)
987 return 1; 1045 return 1;
988} 1046}
989 1047
1048LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname)
1049{
1050 lua_getfield(L, LUA_REGISTRYINDEX, tname);
1051 lua_setmetatable(L, -2);
1052}
1053
990LUA_API int lua_setfenv(lua_State *L, int idx) 1054LUA_API int lua_setfenv(lua_State *L, int idx)
991{ 1055{
992 cTValue *o = index2adr(L, idx); 1056 cTValue *o = index2adr(L, idx);
@@ -1027,11 +1091,24 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1027 1091
1028/* -- Calls --------------------------------------------------------------- */ 1092/* -- Calls --------------------------------------------------------------- */
1029 1093
1094#if LJ_FR2
1095static TValue *api_call_base(lua_State *L, int nargs)
1096{
1097 TValue *o = L->top, *base = o - nargs;
1098 L->top = o+1;
1099 for (; o > base; o--) copyTV(L, o, o-1);
1100 setnilV(o);
1101 return o+1;
1102}
1103#else
1104#define api_call_base(L, nargs) (L->top - (nargs))
1105#endif
1106
1030LUA_API void lua_call(lua_State *L, int nargs, int nresults) 1107LUA_API void lua_call(lua_State *L, int nargs, int nresults)
1031{ 1108{
1032 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1109 api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
1033 api_checknelems(L, nargs+1); 1110 api_checknelems(L, nargs+1);
1034 lj_vm_call(L, L->top - nargs, nresults+1); 1111 lj_vm_call(L, api_call_base(L, nargs), nresults+1);
1035} 1112}
1036 1113
1037LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) 1114LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
@@ -1040,7 +1117,7 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1040 uint8_t oldh = hook_save(g); 1117 uint8_t oldh = hook_save(g);
1041 ptrdiff_t ef; 1118 ptrdiff_t ef;
1042 int status; 1119 int status;
1043 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1120 api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
1044 api_checknelems(L, nargs+1); 1121 api_checknelems(L, nargs+1);
1045 if (errfunc == 0) { 1122 if (errfunc == 0) {
1046 ef = 0; 1123 ef = 0;
@@ -1049,7 +1126,7 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1049 api_checkvalidindex(L, o); 1126 api_checkvalidindex(L, o);
1050 ef = savestack(L, o); 1127 ef = savestack(L, o);
1051 } 1128 }
1052 status = lj_vm_pcall(L, L->top - nargs, nresults+1, ef); 1129 status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
1053 if (status) hook_restore(g, oldh); 1130 if (status) hook_restore(g, oldh);
1054 return status; 1131 return status;
1055} 1132}
@@ -1057,12 +1134,14 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1057static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud) 1134static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
1058{ 1135{
1059 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L)); 1136 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
1137 TValue *top = L->top;
1060 fn->c.f = func; 1138 fn->c.f = func;
1061 setfuncV(L, L->top, fn); 1139 setfuncV(L, top++, fn);
1062 setlightudV(L->top+1, checklightudptr(L, ud)); 1140 if (LJ_FR2) setnilV(top++);
1141 setlightudV(top++, checklightudptr(L, ud));
1063 cframe_nres(L->cframe) = 1+0; /* Zero results. */ 1142 cframe_nres(L->cframe) = 1+0; /* Zero results. */
1064 L->top += 2; 1143 L->top = top;
1065 return L->top-1; /* Now call the newly allocated C function. */ 1144 return top-1; /* Now call the newly allocated C function. */
1066} 1145}
1067 1146
1068LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud) 1147LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
@@ -1070,7 +1149,7 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1070 global_State *g = G(L); 1149 global_State *g = G(L);
1071 uint8_t oldh = hook_save(g); 1150 uint8_t oldh = hook_save(g);
1072 int status; 1151 int status;
1073 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1152 api_check(L, L->status == LUA_OK || L->status == LUA_ERRERR);
1074 status = lj_vm_cpcall(L, func, ud, cpcall); 1153 status = lj_vm_cpcall(L, func, ud, cpcall);
1075 if (status) hook_restore(g, oldh); 1154 if (status) hook_restore(g, oldh);
1076 return status; 1155 return status;
@@ -1079,10 +1158,11 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
1079LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field) 1158LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1080{ 1159{
1081 if (luaL_getmetafield(L, idx, field)) { 1160 if (luaL_getmetafield(L, idx, field)) {
1082 TValue *base = L->top--; 1161 TValue *top = L->top--;
1083 copyTV(L, base, index2adr(L, idx)); 1162 if (LJ_FR2) setnilV(top++);
1084 L->top = base+1; 1163 copyTV(L, top++, index2adr(L, idx));
1085 lj_vm_call(L, base, 1+1); 1164 L->top = top;
1165 lj_vm_call(L, top-1, 1+1);
1086 return 1; 1166 return 1;
1087 } 1167 }
1088 return 0; 1168 return 0;
@@ -1090,6 +1170,11 @@ LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1090 1170
1091/* -- Coroutine yield and resume ------------------------------------------ */ 1171/* -- Coroutine yield and resume ------------------------------------------ */
1092 1172
1173LUA_API int lua_isyieldable(lua_State *L)
1174{
1175 return cframe_canyield(L->cframe);
1176}
1177
1093LUA_API int lua_yield(lua_State *L, int nresults) 1178LUA_API int lua_yield(lua_State *L, int nresults)
1094{ 1179{
1095 void *cf = L->cframe; 1180 void *cf = L->cframe;
@@ -1109,12 +1194,14 @@ LUA_API int lua_yield(lua_State *L, int nresults)
1109 } else { /* Yield from hook: add a pseudo-frame. */ 1194 } else { /* Yield from hook: add a pseudo-frame. */
1110 TValue *top = L->top; 1195 TValue *top = L->top;
1111 hook_leave(g); 1196 hook_leave(g);
1112 top->u64 = cframe_multres(cf); 1197 (top++)->u64 = cframe_multres(cf);
1113 setcont(top+1, lj_cont_hook); 1198 setcont(top, lj_cont_hook);
1114 setframe_pc(top+1, cframe_pc(cf)-1); 1199 if (LJ_FR2) top++;
1115 setframe_gc(top+2, obj2gco(L)); 1200 setframe_pc(top, cframe_pc(cf)-1);
1116 setframe_ftsz(top+2, (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT); 1201 if (LJ_FR2) top++;
1117 L->top = L->base = top+3; 1202 setframe_gc(top, obj2gco(L), LJ_TTHREAD);
1203 setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
1204 L->top = L->base = top+1;
1118#if LJ_TARGET_X64 1205#if LJ_TARGET_X64
1119 lj_err_throw(L, LUA_YIELD); 1206 lj_err_throw(L, LUA_YIELD);
1120#else 1207#else
@@ -1131,7 +1218,9 @@ LUA_API int lua_yield(lua_State *L, int nresults)
1131LUA_API int lua_resume(lua_State *L, int nargs) 1218LUA_API int lua_resume(lua_State *L, int nargs)
1132{ 1219{
1133 if (L->cframe == NULL && L->status <= LUA_YIELD) 1220 if (L->cframe == NULL && L->status <= LUA_YIELD)
1134 return lj_vm_resume(L, L->top - nargs, 0, 0); 1221 return lj_vm_resume(L,
1222 L->status == LUA_OK ? api_call_base(L, nargs) : L->top - nargs,
1223 0, 0);
1135 L->top = L->base; 1224 L->top = L->base;
1136 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP)); 1225 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
1137 incr_top(L); 1226 incr_top(L);
@@ -1161,7 +1250,7 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
1161 res = (int)(g->gc.total & 0x3ff); 1250 res = (int)(g->gc.total & 0x3ff);
1162 break; 1251 break;
1163 case LUA_GCSTEP: { 1252 case LUA_GCSTEP: {
1164 MSize a = (MSize)data << 10; 1253 GCSize a = (GCSize)data << 10;
1165 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0; 1254 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
1166 while (g->gc.total >= g->gc.threshold) 1255 while (g->gc.total >= g->gc.threshold)
1167 if (lj_gc_step(L) > 0) { 1256 if (lj_gc_step(L) > 0) {
@@ -1178,6 +1267,9 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
1178 res = (int)(g->gc.stepmul); 1267 res = (int)(g->gc.stepmul);
1179 g->gc.stepmul = (MSize)data; 1268 g->gc.stepmul = (MSize)data;
1180 break; 1269 break;
1270 case LUA_GCISRUNNING:
1271 res = (g->gc.threshold != LJ_MAX_MEM);
1272 break;
1181 default: 1273 default:
1182 res = -1; /* Invalid option. */ 1274 res = -1; /* Invalid option. */
1183 } 1275 }