diff options
Diffstat (limited to 'src/lj_api.c')
-rw-r--r-- | src/lj_api.c | 246 |
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 | ||
115 | LUA_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 | ||
116 | LUA_API int lua_gettop(lua_State *L) | 124 | LUA_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 | ||
154 | LUA_API void lua_replace(lua_State *L, int idx) | 162 | static 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 | |||
184 | LUA_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 | ||
191 | LUA_API void lua_copy(lua_State *L, int fromidx, int toidx) | ||
192 | { | ||
193 | copy_slot(L, index2adr(L, fromidx), toidx); | ||
194 | } | ||
195 | |||
178 | LUA_API void lua_pushvalue(lua_State *L, int idx) | 196 | LUA_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 | ||
345 | LUA_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 | |||
327 | LUALIB_API lua_Number luaL_checknumber(lua_State *L, int idx) | 361 | LUALIB_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 | |||
408 | LUA_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 | ||
546 | LUA_API const void *lua_topointer(lua_State *L, int idx) | 609 | LUA_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 | ||
612 | LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...) | 665 | LUA_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 | ||
650 | LUA_API void lua_createtable(lua_State *L, int narray, int nrec) | 703 | LUA_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 | ||
872 | LUALIB_API void *luaL_checkudata(lua_State *L, int idx, const char *tname) | 923 | LUALIB_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 | |||
935 | LUALIB_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 | ||
1048 | LUALIB_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 | |||
990 | LUA_API int lua_setfenv(lua_State *L, int idx) | 1054 | LUA_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 | ||
1095 | static 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 | |||
1030 | LUA_API void lua_call(lua_State *L, int nargs, int nresults) | 1107 | LUA_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 | ||
1037 | LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) | 1114 | LUA_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) | |||
1057 | static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud) | 1134 | static 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 | ||
1068 | LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud) | 1147 | LUA_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) | |||
1079 | LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field) | 1158 | LUALIB_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 | ||
1173 | LUA_API int lua_isyieldable(lua_State *L) | ||
1174 | { | ||
1175 | return cframe_canyield(L->cframe); | ||
1176 | } | ||
1177 | |||
1093 | LUA_API int lua_yield(lua_State *L, int nresults) | 1178 | LUA_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) | |||
1131 | LUA_API int lua_resume(lua_State *L, int nargs) | 1218 | LUA_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 | } |