diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_api.c | 135 |
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 | ||
546 | LUA_API const void *lua_topointer(lua_State *L, int idx) | 547 | LUA_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 | ||
612 | LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...) | 603 | LUA_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 | ||
650 | LUA_API void lua_createtable(lua_State *L, int narray, int nrec) | 641 | LUA_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 | ||
1021 | static 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 | |||
1030 | LUA_API void lua_call(lua_State *L, int nargs, int nresults) | 1033 | LUA_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 | ||
1037 | LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) | 1040 | LUA_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) | |||
1057 | static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud) | 1060 | static 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 | ||
1068 | LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud) | 1073 | LUA_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) | |||
1079 | LUALIB_API int luaL_callmeta(lua_State *L, int idx, const char *field) | 1084 | LUALIB_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) | |||
1131 | LUA_API int lua_resume(lua_State *L, int nargs) | 1139 | LUA_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 | } |