aboutsummaryrefslogtreecommitdiff
path: root/src/lj_api.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_api.c135
1 files changed, 74 insertions, 61 deletions
diff --git a/src/lj_api.c b/src/lj_api.c
index dacc0d64..0fbb9256 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
@@ -188,7 +189,7 @@ LUA_API int lua_type(lua_State *L, int idx)
188 cTValue *o = index2adr(L, idx); 189 cTValue *o = index2adr(L, idx);
189 if (tvisnumber(o)) { 190 if (tvisnumber(o)) {
190 return LUA_TNUMBER; 191 return LUA_TNUMBER;
191#if LJ_64 192#if LJ_64 && !LJ_GC64
192 } else if (tvislightud(o)) { 193 } else if (tvislightud(o)) {
193 return LUA_TLIGHTUSERDATA; 194 return LUA_TLIGHTUSERDATA;
194#endif 195#endif
@@ -268,7 +269,7 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
268 return 0; 269 return 0;
269 } else if (tvispri(o1)) { 270 } else if (tvispri(o1)) {
270 return o1 != niltv(L) && o2 != niltv(L); 271 return o1 != niltv(L) && o2 != niltv(L);
271#if LJ_64 272#if LJ_64 && !LJ_GC64
272 } else if (tvislightud(o1)) { 273 } else if (tvislightud(o1)) {
273 return o1->u64 == o2->u64; 274 return o1->u64 == o2->u64;
274#endif 275#endif
@@ -283,8 +284,8 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2)
283 } else { 284 } else {
284 L->top = base+2; 285 L->top = base+2;
285 lj_vm_call(L, base, 1+1); 286 lj_vm_call(L, base, 1+1);
286 L->top -= 2; 287 L->top -= 2+LJ_FR2;
287 return tvistruecond(L->top+1); 288 return tvistruecond(L->top+1+LJ_FR2);
288 } 289 }
289 } 290 }
290} 291}
@@ -306,8 +307,8 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2)
306 } else { 307 } else {
307 L->top = base+2; 308 L->top = base+2;
308 lj_vm_call(L, base, 1+1); 309 lj_vm_call(L, base, 1+1);
309 L->top -= 2; 310 L->top -= 2+LJ_FR2;
310 return tvistruecond(L->top+1); 311 return tvistruecond(L->top+1+LJ_FR2);
311 } 312 }
312 } 313 }
313} 314}
@@ -434,7 +435,7 @@ LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len)
434 } else if (tvisnumber(o)) { 435 } else if (tvisnumber(o)) {
435 lj_gc_check(L); 436 lj_gc_check(L);
436 o = index2adr(L, idx); /* GC may move the stack. */ 437 o = index2adr(L, idx); /* GC may move the stack. */
437 s = lj_str_fromnumber(L, o); 438 s = lj_strfmt_number(L, o);
438 setstrV(L, o, s); 439 setstrV(L, o, s);
439 } else { 440 } else {
440 if (len != NULL) *len = 0; 441 if (len != NULL) *len = 0;
@@ -453,7 +454,7 @@ LUALIB_API const char *luaL_checklstring(lua_State *L, int idx, size_t *len)
453 } else if (tvisnumber(o)) { 454 } else if (tvisnumber(o)) {
454 lj_gc_check(L); 455 lj_gc_check(L);
455 o = index2adr(L, idx); /* GC may move the stack. */ 456 o = index2adr(L, idx); /* GC may move the stack. */
456 s = lj_str_fromnumber(L, o); 457 s = lj_strfmt_number(L, o);
457 setstrV(L, o, s); 458 setstrV(L, o, s);
458 } else { 459 } else {
459 lj_err_argt(L, idx, LUA_TSTRING); 460 lj_err_argt(L, idx, LUA_TSTRING);
@@ -475,7 +476,7 @@ LUALIB_API const char *luaL_optlstring(lua_State *L, int idx,
475 } else if (tvisnumber(o)) { 476 } else if (tvisnumber(o)) {
476 lj_gc_check(L); 477 lj_gc_check(L);
477 o = index2adr(L, idx); /* GC may move the stack. */ 478 o = index2adr(L, idx); /* GC may move the stack. */
478 s = lj_str_fromnumber(L, o); 479 s = lj_strfmt_number(L, o);
479 setstrV(L, o, s); 480 setstrV(L, o, s);
480 } else { 481 } else {
481 lj_err_argt(L, idx, LUA_TSTRING); 482 lj_err_argt(L, idx, LUA_TSTRING);
@@ -507,7 +508,7 @@ LUA_API size_t lua_objlen(lua_State *L, int idx)
507 } else if (tvisudata(o)) { 508 } else if (tvisudata(o)) {
508 return udataV(o)->len; 509 return udataV(o)->len;
509 } else if (tvisnumber(o)) { 510 } else if (tvisnumber(o)) {
510 GCstr *s = lj_str_fromnumber(L, o); 511 GCstr *s = lj_strfmt_number(L, o);
511 setstrV(L, o, s); 512 setstrV(L, o, s);
512 return s->len; 513 return s->len;
513 } else { 514 } else {
@@ -545,17 +546,7 @@ LUA_API lua_State *lua_tothread(lua_State *L, int idx)
545 546
546LUA_API const void *lua_topointer(lua_State *L, int idx) 547LUA_API const void *lua_topointer(lua_State *L, int idx)
547{ 548{
548 cTValue *o = index2adr(L, idx); 549 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} 550}
560 551
561/* -- Stack setters (object creation) ------------------------------------- */ 552/* -- Stack setters (object creation) ------------------------------------- */
@@ -606,7 +597,7 @@ LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt,
606 va_list argp) 597 va_list argp)
607{ 598{
608 lj_gc_check(L); 599 lj_gc_check(L);
609 return lj_str_pushvf(L, fmt, argp); 600 return lj_strfmt_pushvf(L, fmt, argp);
610} 601}
611 602
612LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...) 603LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
@@ -615,7 +606,7 @@ LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...)
615 va_list argp; 606 va_list argp;
616 lj_gc_check(L); 607 lj_gc_check(L);
617 va_start(argp, fmt); 608 va_start(argp, fmt);
618 ret = lj_str_pushvf(L, fmt, argp); 609 ret = lj_strfmt_pushvf(L, fmt, argp);
619 va_end(argp); 610 va_end(argp);
620 return ret; 611 return ret;
621} 612}
@@ -649,10 +640,8 @@ LUA_API void lua_pushlightuserdata(lua_State *L, void *p)
649 640
650LUA_API void lua_createtable(lua_State *L, int narray, int nrec) 641LUA_API void lua_createtable(lua_State *L, int narray, int nrec)
651{ 642{
652 GCtab *t;
653 lj_gc_check(L); 643 lj_gc_check(L);
654 t = lj_tab_new(L, (uint32_t)(narray > 0 ? narray+1 : 0), hsize2hbits(nrec)); 644 settabV(L, L->top, lj_tab_new_ah(L, narray, nrec));
655 settabV(L, L->top, t);
656 incr_top(L); 645 incr_top(L);
657} 646}
658 647
@@ -715,8 +704,8 @@ LUA_API void lua_concat(lua_State *L, int n)
715 n -= (int)(L->top - top); 704 n -= (int)(L->top - top);
716 L->top = top+2; 705 L->top = top+2;
717 lj_vm_call(L, top, 1+1); 706 lj_vm_call(L, top, 1+1);
718 L->top--; 707 L->top -= 1+LJ_FR2;
719 copyTV(L, L->top-1, L->top); 708 copyTV(L, L->top-1, L->top+LJ_FR2);
720 } while (--n > 0); 709 } while (--n > 0);
721 } else if (n == 0) { /* Push empty string. */ 710 } else if (n == 0) { /* Push empty string. */
722 setstrV(L, L->top, &G(L)->strempty); 711 setstrV(L, L->top, &G(L)->strempty);
@@ -735,8 +724,8 @@ LUA_API void lua_gettable(lua_State *L, int idx)
735 if (v == NULL) { 724 if (v == NULL) {
736 L->top += 2; 725 L->top += 2;
737 lj_vm_call(L, L->top-2, 1+1); 726 lj_vm_call(L, L->top-2, 1+1);
738 L->top -= 2; 727 L->top -= 2+LJ_FR2;
739 v = L->top+1; 728 v = L->top+1+LJ_FR2;
740 } 729 }
741 copyTV(L, L->top-1, v); 730 copyTV(L, L->top-1, v);
742} 731}
@@ -751,8 +740,8 @@ LUA_API void lua_getfield(lua_State *L, int idx, const char *k)
751 if (v == NULL) { 740 if (v == NULL) {
752 L->top += 2; 741 L->top += 2;
753 lj_vm_call(L, L->top-2, 1+1); 742 lj_vm_call(L, L->top-2, 1+1);
754 L->top -= 2; 743 L->top -= 2+LJ_FR2;
755 v = L->top+1; 744 v = L->top+1+LJ_FR2;
756 } 745 }
757 copyTV(L, L->top, v); 746 copyTV(L, L->top, v);
758 incr_top(L); 747 incr_top(L);
@@ -893,13 +882,14 @@ LUA_API void lua_settable(lua_State *L, int idx)
893 o = lj_meta_tset(L, t, L->top-2); 882 o = lj_meta_tset(L, t, L->top-2);
894 if (o) { 883 if (o) {
895 /* NOBARRIER: lj_meta_tset ensures the table is not black. */ 884 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
896 copyTV(L, o, L->top-1);
897 L->top -= 2; 885 L->top -= 2;
886 copyTV(L, o, L->top+1);
898 } else { 887 } else {
899 L->top += 3; 888 TValue *base = L->top;
900 copyTV(L, L->top-1, L->top-6); 889 copyTV(L, base+2, base-3-2*LJ_FR2);
901 lj_vm_call(L, L->top-3, 0+1); 890 L->top = base+3;
902 L->top -= 3; 891 lj_vm_call(L, base, 0+1);
892 L->top -= 3+LJ_FR2;
903 } 893 }
904} 894}
905 895
@@ -913,14 +903,14 @@ LUA_API void lua_setfield(lua_State *L, int idx, const char *k)
913 setstrV(L, &key, lj_str_newz(L, k)); 903 setstrV(L, &key, lj_str_newz(L, k));
914 o = lj_meta_tset(L, t, &key); 904 o = lj_meta_tset(L, t, &key);
915 if (o) { 905 if (o) {
916 L->top--;
917 /* NOBARRIER: lj_meta_tset ensures the table is not black. */ 906 /* NOBARRIER: lj_meta_tset ensures the table is not black. */
918 copyTV(L, o, L->top); 907 copyTV(L, o, --L->top);
919 } else { 908 } else {
920 L->top += 3; 909 TValue *base = L->top;
921 copyTV(L, L->top-1, L->top-6); 910 copyTV(L, base+2, base-3-2*LJ_FR2);
922 lj_vm_call(L, L->top-3, 0+1); 911 L->top = base+3;
923 L->top -= 2; 912 lj_vm_call(L, base, 0+1);
913 L->top -= 2+LJ_FR2;
924 } 914 }
925} 915}
926 916
@@ -1027,11 +1017,24 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n)
1027 1017
1028/* -- Calls --------------------------------------------------------------- */ 1018/* -- Calls --------------------------------------------------------------- */
1029 1019
1020#if LJ_FR2
1021static TValue *api_call_base(lua_State *L, int nargs)
1022{
1023 TValue *o = L->top, *base = o - nargs;
1024 L->top = o+1;
1025 for (; o > base; o--) copyTV(L, o, o-1);
1026 setnilV(o);
1027 return o+1;
1028}
1029#else
1030#define api_call_base(L, nargs) (L->top - (nargs))
1031#endif
1032
1030LUA_API void lua_call(lua_State *L, int nargs, int nresults) 1033LUA_API void lua_call(lua_State *L, int nargs, int nresults)
1031{ 1034{
1032 api_check(L, L->status == 0 || L->status == LUA_ERRERR); 1035 api_check(L, L->status == 0 || L->status == LUA_ERRERR);
1033 api_checknelems(L, nargs+1); 1036 api_checknelems(L, nargs+1);
1034 lj_vm_call(L, L->top - nargs, nresults+1); 1037 lj_vm_call(L, api_call_base(L, nargs), nresults+1);
1035} 1038}
1036 1039
1037LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) 1040LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
@@ -1049,7 +1052,7 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc)
1049 api_checkvalidindex(L, o); 1052 api_checkvalidindex(L, o);
1050 ef = savestack(L, o); 1053 ef = savestack(L, o);
1051 } 1054 }
1052 status = lj_vm_pcall(L, L->top - nargs, nresults+1, ef); 1055 status = lj_vm_pcall(L, api_call_base(L, nargs), nresults+1, ef);
1053 if (status) hook_restore(g, oldh); 1056 if (status) hook_restore(g, oldh);
1054 return status; 1057 return status;
1055} 1058}
@@ -1057,12 +1060,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) 1060static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud)
1058{ 1061{
1059 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L)); 1062 GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L));
1063 TValue *top = L->top;
1060 fn->c.f = func; 1064 fn->c.f = func;
1061 setfuncV(L, L->top, fn); 1065 setfuncV(L, top++, fn);
1062 setlightudV(L->top+1, checklightudptr(L, ud)); 1066 if (LJ_FR2) setnilV(top++);
1067 setlightudV(top++, checklightudptr(L, ud));
1063 cframe_nres(L->cframe) = 1+0; /* Zero results. */ 1068 cframe_nres(L->cframe) = 1+0; /* Zero results. */
1064 L->top += 2; 1069 L->top = top;
1065 return L->top-1; /* Now call the newly allocated C function. */ 1070 return top-1; /* Now call the newly allocated C function. */
1066} 1071}
1067 1072
1068LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud) 1073LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud)
@@ -1079,10 +1084,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) 1084LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field)
1080{ 1085{
1081 if (luaL_getmetafield(L, idx, field)) { 1086 if (luaL_getmetafield(L, idx, field)) {
1082 TValue *base = L->top--; 1087 TValue *top = L->top--;
1083 copyTV(L, base, index2adr(L, idx)); 1088 if (LJ_FR2) setnilV(top++);
1084 L->top = base+1; 1089 copyTV(L, top++, index2adr(L, idx));
1085 lj_vm_call(L, base, 1+1); 1090 L->top = top;
1091 lj_vm_call(L, top-1, 1+1);
1086 return 1; 1092 return 1;
1087 } 1093 }
1088 return 0; 1094 return 0;
@@ -1109,12 +1115,14 @@ LUA_API int lua_yield(lua_State *L, int nresults)
1109 } else { /* Yield from hook: add a pseudo-frame. */ 1115 } else { /* Yield from hook: add a pseudo-frame. */
1110 TValue *top = L->top; 1116 TValue *top = L->top;
1111 hook_leave(g); 1117 hook_leave(g);
1112 top->u64 = cframe_multres(cf); 1118 (top++)->u64 = cframe_multres(cf);
1113 setcont(top+1, lj_cont_hook); 1119 setcont(top, lj_cont_hook);
1114 setframe_pc(top+1, cframe_pc(cf)-1); 1120 if (LJ_FR2) top++;
1115 setframe_gc(top+2, obj2gco(L)); 1121 setframe_pc(top, cframe_pc(cf)-1);
1116 setframe_ftsz(top+2, (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT); 1122 if (LJ_FR2) top++;
1117 L->top = L->base = top+3; 1123 setframe_gc(top, obj2gco(L), LJ_TTHREAD);
1124 setframe_ftsz(top, ((char *)(top+1)-(char *)L->base)+FRAME_CONT);
1125 L->top = L->base = top+1;
1118#if LJ_TARGET_X64 1126#if LJ_TARGET_X64
1119 lj_err_throw(L, LUA_YIELD); 1127 lj_err_throw(L, LUA_YIELD);
1120#else 1128#else
@@ -1131,7 +1139,9 @@ LUA_API int lua_yield(lua_State *L, int nresults)
1131LUA_API int lua_resume(lua_State *L, int nargs) 1139LUA_API int lua_resume(lua_State *L, int nargs)
1132{ 1140{
1133 if (L->cframe == NULL && L->status <= LUA_YIELD) 1141 if (L->cframe == NULL && L->status <= LUA_YIELD)
1134 return lj_vm_resume(L, L->top - nargs, 0, 0); 1142 return lj_vm_resume(L,
1143 L->status == 0 ? api_call_base(L, nargs) : L->top - nargs,
1144 0, 0);
1135 L->top = L->base; 1145 L->top = L->base;
1136 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP)); 1146 setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP));
1137 incr_top(L); 1147 incr_top(L);
@@ -1161,7 +1171,7 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
1161 res = (int)(g->gc.total & 0x3ff); 1171 res = (int)(g->gc.total & 0x3ff);
1162 break; 1172 break;
1163 case LUA_GCSTEP: { 1173 case LUA_GCSTEP: {
1164 MSize a = (MSize)data << 10; 1174 GCSize a = (GCSize)data << 10;
1165 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0; 1175 g->gc.threshold = (a <= g->gc.total) ? (g->gc.total - a) : 0;
1166 while (g->gc.total >= g->gc.threshold) 1176 while (g->gc.total >= g->gc.threshold)
1167 if (lj_gc_step(L) > 0) { 1177 if (lj_gc_step(L) > 0) {
@@ -1178,6 +1188,9 @@ LUA_API int lua_gc(lua_State *L, int what, int data)
1178 res = (int)(g->gc.stepmul); 1188 res = (int)(g->gc.stepmul);
1179 g->gc.stepmul = (MSize)data; 1189 g->gc.stepmul = (MSize)data;
1180 break; 1190 break;
1191 case LUA_GCISRUNNING:
1192 res = (g->gc.threshold != LJ_MAX_MEM);
1193 break;
1181 default: 1194 default:
1182 res = -1; /* Invalid option. */ 1195 res = -1; /* Invalid option. */
1183 } 1196 }