diff options
Diffstat (limited to 'src/lj_api.c')
-rw-r--r-- | src/lj_api.c | 97 |
1 files changed, 59 insertions, 38 deletions
diff --git a/src/lj_api.c b/src/lj_api.c index 4a7809bc..6ad09b9d 100644 --- a/src/lj_api.c +++ b/src/lj_api.c | |||
@@ -284,8 +284,8 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2) | |||
284 | } else { | 284 | } else { |
285 | L->top = base+2; | 285 | L->top = base+2; |
286 | lj_vm_call(L, base, 1+1); | 286 | lj_vm_call(L, base, 1+1); |
287 | L->top -= 2; | 287 | L->top -= 2+LJ_FR2; |
288 | return tvistruecond(L->top+1); | 288 | return tvistruecond(L->top+1+LJ_FR2); |
289 | } | 289 | } |
290 | } | 290 | } |
291 | } | 291 | } |
@@ -307,8 +307,8 @@ LUA_API int lua_lessthan(lua_State *L, int idx1, int idx2) | |||
307 | } else { | 307 | } else { |
308 | L->top = base+2; | 308 | L->top = base+2; |
309 | lj_vm_call(L, base, 1+1); | 309 | lj_vm_call(L, base, 1+1); |
310 | L->top -= 2; | 310 | L->top -= 2+LJ_FR2; |
311 | return tvistruecond(L->top+1); | 311 | return tvistruecond(L->top+1+LJ_FR2); |
312 | } | 312 | } |
313 | } | 313 | } |
314 | } | 314 | } |
@@ -704,8 +704,8 @@ LUA_API void lua_concat(lua_State *L, int n) | |||
704 | n -= (int)(L->top - top); | 704 | n -= (int)(L->top - top); |
705 | L->top = top+2; | 705 | L->top = top+2; |
706 | lj_vm_call(L, top, 1+1); | 706 | lj_vm_call(L, top, 1+1); |
707 | L->top--; | 707 | L->top -= 1+LJ_FR2; |
708 | copyTV(L, L->top-1, L->top); | 708 | copyTV(L, L->top-1, L->top+LJ_FR2); |
709 | } while (--n > 0); | 709 | } while (--n > 0); |
710 | } else if (n == 0) { /* Push empty string. */ | 710 | } else if (n == 0) { /* Push empty string. */ |
711 | setstrV(L, L->top, &G(L)->strempty); | 711 | setstrV(L, L->top, &G(L)->strempty); |
@@ -724,8 +724,8 @@ LUA_API void lua_gettable(lua_State *L, int idx) | |||
724 | if (v == NULL) { | 724 | if (v == NULL) { |
725 | L->top += 2; | 725 | L->top += 2; |
726 | lj_vm_call(L, L->top-2, 1+1); | 726 | lj_vm_call(L, L->top-2, 1+1); |
727 | L->top -= 2; | 727 | L->top -= 2+LJ_FR2; |
728 | v = L->top+1; | 728 | v = L->top+1+LJ_FR2; |
729 | } | 729 | } |
730 | copyTV(L, L->top-1, v); | 730 | copyTV(L, L->top-1, v); |
731 | } | 731 | } |
@@ -740,8 +740,8 @@ LUA_API void lua_getfield(lua_State *L, int idx, const char *k) | |||
740 | if (v == NULL) { | 740 | if (v == NULL) { |
741 | L->top += 2; | 741 | L->top += 2; |
742 | lj_vm_call(L, L->top-2, 1+1); | 742 | lj_vm_call(L, L->top-2, 1+1); |
743 | L->top -= 2; | 743 | L->top -= 2+LJ_FR2; |
744 | v = L->top+1; | 744 | v = L->top+1+LJ_FR2; |
745 | } | 745 | } |
746 | copyTV(L, L->top, v); | 746 | copyTV(L, L->top, v); |
747 | incr_top(L); | 747 | incr_top(L); |
@@ -882,13 +882,14 @@ LUA_API void lua_settable(lua_State *L, int idx) | |||
882 | o = lj_meta_tset(L, t, L->top-2); | 882 | o = lj_meta_tset(L, t, L->top-2); |
883 | if (o) { | 883 | if (o) { |
884 | /* NOBARRIER: lj_meta_tset ensures the table is not black. */ | 884 | /* NOBARRIER: lj_meta_tset ensures the table is not black. */ |
885 | copyTV(L, o, L->top-1); | ||
886 | L->top -= 2; | 885 | L->top -= 2; |
886 | copyTV(L, o, L->top+1); | ||
887 | } else { | 887 | } else { |
888 | L->top += 3; | 888 | TValue *base = L->top; |
889 | copyTV(L, L->top-1, L->top-6); | 889 | copyTV(L, base+2, base-3-LJ_FR2); |
890 | lj_vm_call(L, L->top-3, 0+1); | 890 | L->top = base+3; |
891 | L->top -= 3; | 891 | lj_vm_call(L, base, 0+1); |
892 | L->top -= 3+LJ_FR2; | ||
892 | } | 893 | } |
893 | } | 894 | } |
894 | 895 | ||
@@ -902,14 +903,14 @@ LUA_API void lua_setfield(lua_State *L, int idx, const char *k) | |||
902 | setstrV(L, &key, lj_str_newz(L, k)); | 903 | setstrV(L, &key, lj_str_newz(L, k)); |
903 | o = lj_meta_tset(L, t, &key); | 904 | o = lj_meta_tset(L, t, &key); |
904 | if (o) { | 905 | if (o) { |
905 | L->top--; | ||
906 | /* NOBARRIER: lj_meta_tset ensures the table is not black. */ | 906 | /* NOBARRIER: lj_meta_tset ensures the table is not black. */ |
907 | copyTV(L, o, L->top); | 907 | copyTV(L, o, --L->top); |
908 | } else { | 908 | } else { |
909 | L->top += 3; | 909 | TValue *base = L->top; |
910 | copyTV(L, L->top-1, L->top-6); | 910 | copyTV(L, base+2, base-3-LJ_FR2); |
911 | lj_vm_call(L, L->top-3, 0+1); | 911 | L->top = base+3; |
912 | L->top -= 2; | 912 | lj_vm_call(L, base, 0+1); |
913 | L->top -= 2+LJ_FR2; | ||
913 | } | 914 | } |
914 | } | 915 | } |
915 | 916 | ||
@@ -1016,11 +1017,24 @@ LUA_API const char *lua_setupvalue(lua_State *L, int idx, int n) | |||
1016 | 1017 | ||
1017 | /* -- Calls --------------------------------------------------------------- */ | 1018 | /* -- Calls --------------------------------------------------------------- */ |
1018 | 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 | |||
1019 | 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) |
1020 | { | 1034 | { |
1021 | api_check(L, L->status == 0 || L->status == LUA_ERRERR); | 1035 | api_check(L, L->status == 0 || L->status == LUA_ERRERR); |
1022 | api_checknelems(L, nargs+1); | 1036 | api_checknelems(L, nargs+1); |
1023 | lj_vm_call(L, L->top - nargs, nresults+1); | 1037 | lj_vm_call(L, api_call_base(L, nargs), nresults+1); |
1024 | } | 1038 | } |
1025 | 1039 | ||
1026 | 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) |
@@ -1038,7 +1052,7 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) | |||
1038 | api_checkvalidindex(L, o); | 1052 | api_checkvalidindex(L, o); |
1039 | ef = savestack(L, o); | 1053 | ef = savestack(L, o); |
1040 | } | 1054 | } |
1041 | 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); |
1042 | if (status) hook_restore(g, oldh); | 1056 | if (status) hook_restore(g, oldh); |
1043 | return status; | 1057 | return status; |
1044 | } | 1058 | } |
@@ -1046,12 +1060,14 @@ LUA_API int lua_pcall(lua_State *L, int nargs, int nresults, int errfunc) | |||
1046 | static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud) | 1060 | static TValue *cpcall(lua_State *L, lua_CFunction func, void *ud) |
1047 | { | 1061 | { |
1048 | GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L)); | 1062 | GCfunc *fn = lj_func_newC(L, 0, getcurrenv(L)); |
1063 | TValue *top = L->top; | ||
1049 | fn->c.f = func; | 1064 | fn->c.f = func; |
1050 | setfuncV(L, L->top, fn); | 1065 | setfuncV(L, top++, fn); |
1051 | setlightudV(L->top+1, checklightudptr(L, ud)); | 1066 | if (LJ_FR2) setnilV(top++); |
1067 | setlightudV(top++, checklightudptr(L, ud)); | ||
1052 | cframe_nres(L->cframe) = 1+0; /* Zero results. */ | 1068 | cframe_nres(L->cframe) = 1+0; /* Zero results. */ |
1053 | L->top += 2; | 1069 | L->top = top; |
1054 | return L->top-1; /* Now call the newly allocated C function. */ | 1070 | return top-1; /* Now call the newly allocated C function. */ |
1055 | } | 1071 | } |
1056 | 1072 | ||
1057 | 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) |
@@ -1068,10 +1084,11 @@ LUA_API int lua_cpcall(lua_State *L, lua_CFunction func, void *ud) | |||
1068 | 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) |
1069 | { | 1085 | { |
1070 | if (luaL_getmetafield(L, idx, field)) { | 1086 | if (luaL_getmetafield(L, idx, field)) { |
1071 | TValue *base = L->top--; | 1087 | TValue *top = L->top--; |
1072 | copyTV(L, base, index2adr(L, idx)); | 1088 | if (LJ_FR2) setnilV(top++); |
1073 | L->top = base+1; | 1089 | copyTV(L, top++, index2adr(L, idx)); |
1074 | lj_vm_call(L, base, 1+1); | 1090 | L->top = top; |
1091 | lj_vm_call(L, top-1, 1+1); | ||
1075 | return 1; | 1092 | return 1; |
1076 | } | 1093 | } |
1077 | return 0; | 1094 | return 0; |
@@ -1098,12 +1115,14 @@ LUA_API int lua_yield(lua_State *L, int nresults) | |||
1098 | } else { /* Yield from hook: add a pseudo-frame. */ | 1115 | } else { /* Yield from hook: add a pseudo-frame. */ |
1099 | TValue *top = L->top; | 1116 | TValue *top = L->top; |
1100 | hook_leave(g); | 1117 | hook_leave(g); |
1101 | top->u64 = cframe_multres(cf); | 1118 | (top++)->u64 = cframe_multres(cf); |
1102 | setcont(top+1, lj_cont_hook); | 1119 | setcont(top, lj_cont_hook); |
1103 | setframe_pc(top+1, cframe_pc(cf)-1); | 1120 | if (LJ_FR2) top++; |
1104 | setframe_gc(top+2, obj2gco(L), LJ_TTHREAD); | 1121 | setframe_pc(top, cframe_pc(cf)-1); |
1105 | setframe_ftsz(top+2, ((char *)(top+3)-(char *)L->base)+FRAME_CONT); | 1122 | if (LJ_FR2) top++; |
1106 | 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; | ||
1107 | #if LJ_TARGET_X64 | 1126 | #if LJ_TARGET_X64 |
1108 | lj_err_throw(L, LUA_YIELD); | 1127 | lj_err_throw(L, LUA_YIELD); |
1109 | #else | 1128 | #else |
@@ -1120,7 +1139,9 @@ LUA_API int lua_yield(lua_State *L, int nresults) | |||
1120 | LUA_API int lua_resume(lua_State *L, int nargs) | 1139 | LUA_API int lua_resume(lua_State *L, int nargs) |
1121 | { | 1140 | { |
1122 | if (L->cframe == NULL && L->status <= LUA_YIELD) | 1141 | if (L->cframe == NULL && L->status <= LUA_YIELD) |
1123 | 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); | ||
1124 | L->top = L->base; | 1145 | L->top = L->base; |
1125 | setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP)); | 1146 | setstrV(L, L->top, lj_err_str(L, LJ_ERR_COSUSP)); |
1126 | incr_top(L); | 1147 | incr_top(L); |