diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/host/buildvm_libbc.h | 15 | ||||
-rw-r--r-- | src/lib_base.c | 29 | ||||
-rw-r--r-- | src/lib_bit.c | 4 | ||||
-rw-r--r-- | src/lib_ffi.c | 2 | ||||
-rw-r--r-- | src/lib_math.c | 2 | ||||
-rw-r--r-- | src/lib_string.c | 4 | ||||
-rw-r--r-- | src/lj_api.c | 97 | ||||
-rw-r--r-- | src/lj_arch.h | 5 | ||||
-rw-r--r-- | src/lj_asm.c | 2 | ||||
-rw-r--r-- | src/lj_asm_arm.h | 2 | ||||
-rw-r--r-- | src/lj_asm_mips.h | 2 | ||||
-rw-r--r-- | src/lj_asm_ppc.h | 2 | ||||
-rw-r--r-- | src/lj_asm_x86.h | 2 | ||||
-rw-r--r-- | src/lj_bcdump.h | 3 | ||||
-rw-r--r-- | src/lj_bcread.c | 1 | ||||
-rw-r--r-- | src/lj_bcwrite.c | 5 | ||||
-rw-r--r-- | src/lj_ccallback.c | 28 | ||||
-rw-r--r-- | src/lj_crecord.c | 2 | ||||
-rw-r--r-- | src/lj_debug.c | 12 | ||||
-rw-r--r-- | src/lj_dispatch.c | 2 | ||||
-rw-r--r-- | src/lj_err.c | 14 | ||||
-rw-r--r-- | src/lj_ffrecord.c | 2 | ||||
-rw-r--r-- | src/lj_frame.h | 57 | ||||
-rw-r--r-- | src/lj_gc.c | 17 | ||||
-rw-r--r-- | src/lj_lib.h | 5 | ||||
-rw-r--r-- | src/lj_meta.c | 50 | ||||
-rw-r--r-- | src/lj_obj.h | 18 | ||||
-rw-r--r-- | src/lj_parse.c | 14 | ||||
-rw-r--r-- | src/lj_record.c | 25 | ||||
-rw-r--r-- | src/lj_snap.c | 5 | ||||
-rw-r--r-- | src/lj_state.c | 8 | ||||
-rw-r--r-- | src/lj_trace.c | 2 | ||||
-rw-r--r-- | src/lj_vmevent.c | 1 |
33 files changed, 300 insertions, 139 deletions
diff --git a/src/host/buildvm_libbc.h b/src/host/buildvm_libbc.h index e96c8a53..45f8f8cb 100644 --- a/src/host/buildvm_libbc.h +++ b/src/host/buildvm_libbc.h | |||
@@ -3,6 +3,20 @@ | |||
3 | static const int libbc_endian = 0; | 3 | static const int libbc_endian = 0; |
4 | 4 | ||
5 | static const uint8_t libbc_code[] = { | 5 | static const uint8_t libbc_code[] = { |
6 | #if LJ_FR2 | ||
7 | 0,1,2,0,0,1,2,24,1,0,0,76,1,2,0,241,135,158,166,3,220,203,178,130,4,0,1,2,0, | ||
8 | 0,1,2,24,1,0,0,76,1,2,0,243,244,148,165,20,198,190,199,252,3,0,1,2,0,0,0,3, | ||
9 | 16,0,5,0,21,1,0,0,76,1,2,0,0,2,10,0,0,0,15,16,0,12,0,16,1,9,0,41,2,1,0,21,3, | ||
10 | 0,0,41,4,1,0,77,2,8,128,18,6,1,0,18,8,5,0,59,9,5,0,66,6,3,2,10,6,0,0,88,7,1, | ||
11 | 128,76,6,2,0,79,2,248,127,75,0,1,0,0,2,11,0,0,0,16,16,0,12,0,16,1,9,0,43,2, | ||
12 | 0,0,18,3,0,0,41,4,0,0,88,5,7,128,18,7,1,0,18,9,5,0,18,10,6,0,66,7,3,2,10,7, | ||
13 | 0,0,88,8,1,128,76,7,2,0,70,5,3,3,82,5,247,127,75,0,1,0,0,1,2,0,0,0,3,16,0,12, | ||
14 | 0,21,1,0,0,76,1,2,0,0,2,10,0,0,2,30,16,0,12,0,21,2,0,0,11,1,0,0,88,3,7,128, | ||
15 | 8,2,0,0,88,3,23,128,59,3,2,0,43,4,0,0,64,4,2,0,76,3,2,0,88,3,18,128,16,1,14, | ||
16 | 0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2, | ||
17 | 0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4, | ||
18 | 2,0,76,3,2,0,75,0,1,0,0,2,0 | ||
19 | #else | ||
6 | 0,1,2,0,0,1,2,24,1,0,0,76,1,2,0,241,135,158,166,3,220,203,178,130,4,0,1,2,0, | 20 | 0,1,2,0,0,1,2,24,1,0,0,76,1,2,0,241,135,158,166,3,220,203,178,130,4,0,1,2,0, |
7 | 0,1,2,24,1,0,0,76,1,2,0,243,244,148,165,20,198,190,199,252,3,0,1,2,0,0,0,3, | 21 | 0,1,2,24,1,0,0,76,1,2,0,243,244,148,165,20,198,190,199,252,3,0,1,2,0,0,0,3, |
8 | 16,0,5,0,21,1,0,0,76,1,2,0,0,2,9,0,0,0,15,16,0,12,0,16,1,9,0,41,2,1,0,21,3, | 22 | 16,0,5,0,21,1,0,0,76,1,2,0,0,2,9,0,0,0,15,16,0,12,0,16,1,9,0,41,2,1,0,21,3, |
@@ -15,6 +29,7 @@ static const uint8_t libbc_code[] = { | |||
15 | 0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2, | 29 | 0,41,3,1,0,3,3,1,0,88,3,14,128,3,1,2,0,88,3,12,128,59,3,1,0,22,4,1,1,18,5,2, |
16 | 0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4, | 30 | 0,41,6,1,0,77,4,4,128,23,8,1,7,59,9,7,0,64,9,8,0,79,4,252,127,43,4,0,0,64,4, |
17 | 2,0,76,3,2,0,75,0,1,0,0,2,0 | 31 | 2,0,76,3,2,0,75,0,1,0,0,2,0 |
32 | #endif | ||
18 | }; | 33 | }; |
19 | 34 | ||
20 | static const struct { const char *name; int ofs; } libbc_map[] = { | 35 | static const struct { const char *name; int ofs; } libbc_map[] = { |
diff --git a/src/lib_base.c b/src/lib_base.c index 713bdae5..6bb71d54 100644 --- a/src/lib_base.c +++ b/src/lib_base.c | |||
@@ -87,10 +87,11 @@ static int ffh_pairs(lua_State *L, MMS mm) | |||
87 | cTValue *mo = lj_meta_lookup(L, o, mm); | 87 | cTValue *mo = lj_meta_lookup(L, o, mm); |
88 | if ((LJ_52 || tviscdata(o)) && !tvisnil(mo)) { | 88 | if ((LJ_52 || tviscdata(o)) && !tvisnil(mo)) { |
89 | L->top = o+1; /* Only keep one argument. */ | 89 | L->top = o+1; /* Only keep one argument. */ |
90 | copyTV(L, L->base-1, mo); /* Replace callable. */ | 90 | copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */ |
91 | return FFH_TAILCALL; | 91 | return FFH_TAILCALL; |
92 | } else { | 92 | } else { |
93 | if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE); | 93 | if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE); |
94 | if (LJ_FR2) { copyTV(L, o-1, o); o--; } | ||
94 | setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1))); | 95 | setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1))); |
95 | if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0); | 96 | if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0); |
96 | return FFH_RES(3); | 97 | return FFH_RES(3); |
@@ -132,7 +133,7 @@ LJLIB_ASM(setmetatable) LJLIB_REC(.) | |||
132 | lj_err_caller(L, LJ_ERR_PROTMT); | 133 | lj_err_caller(L, LJ_ERR_PROTMT); |
133 | setgcref(t->metatable, obj2gco(mt)); | 134 | setgcref(t->metatable, obj2gco(mt)); |
134 | if (mt) { lj_gc_objbarriert(L, t, mt); } | 135 | if (mt) { lj_gc_objbarriert(L, t, mt); } |
135 | settabV(L, L->base-1, t); | 136 | settabV(L, L->base-1-LJ_FR2, t); |
136 | return FFH_RES(1); | 137 | return FFH_RES(1); |
137 | } | 138 | } |
138 | 139 | ||
@@ -145,6 +146,7 @@ LJLIB_CF(getfenv) LJLIB_REC(.) | |||
145 | o = lj_debug_frame(L, level, &level); | 146 | o = lj_debug_frame(L, level, &level); |
146 | if (o == NULL) | 147 | if (o == NULL) |
147 | lj_err_arg(L, 1, LJ_ERR_INVLVL); | 148 | lj_err_arg(L, 1, LJ_ERR_INVLVL); |
149 | if (LJ_FR2) o--; | ||
148 | } | 150 | } |
149 | fn = &gcval(o)->fn; | 151 | fn = &gcval(o)->fn; |
150 | settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env)); | 152 | settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env)); |
@@ -166,6 +168,7 @@ LJLIB_CF(setfenv) | |||
166 | o = lj_debug_frame(L, level, &level); | 168 | o = lj_debug_frame(L, level, &level); |
167 | if (o == NULL) | 169 | if (o == NULL) |
168 | lj_err_arg(L, 1, LJ_ERR_INVLVL); | 170 | lj_err_arg(L, 1, LJ_ERR_INVLVL); |
171 | if (LJ_FR2) o--; | ||
169 | } | 172 | } |
170 | fn = &gcval(o)->fn; | 173 | fn = &gcval(o)->fn; |
171 | if (!isluafunc(fn)) | 174 | if (!isluafunc(fn)) |
@@ -258,7 +261,7 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
258 | if (base == 10) { | 261 | if (base == 10) { |
259 | TValue *o = lj_lib_checkany(L, 1); | 262 | TValue *o = lj_lib_checkany(L, 1); |
260 | if (lj_strscan_numberobj(o)) { | 263 | if (lj_strscan_numberobj(o)) { |
261 | copyTV(L, L->base-1, o); | 264 | copyTV(L, L->base-1-LJ_FR2, o); |
262 | return FFH_RES(1); | 265 | return FFH_RES(1); |
263 | } | 266 | } |
264 | #if LJ_HASFFI | 267 | #if LJ_HASFFI |
@@ -271,11 +274,11 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
271 | ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) { | 274 | ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) { |
272 | int32_t i; | 275 | int32_t i; |
273 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0); | 276 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0); |
274 | setintV(L->base-1, i); | 277 | setintV(L->base-1-LJ_FR2, i); |
275 | return FFH_RES(1); | 278 | return FFH_RES(1); |
276 | } | 279 | } |
277 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE), | 280 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE), |
278 | (uint8_t *)&(L->base-1)->n, o, 0); | 281 | (uint8_t *)&(L->base-1-LJ_FR2)->n, o, 0); |
279 | return FFH_RES(1); | 282 | return FFH_RES(1); |
280 | } | 283 | } |
281 | } | 284 | } |
@@ -291,14 +294,14 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
291 | while (lj_char_isspace((unsigned char)(*ep))) ep++; | 294 | while (lj_char_isspace((unsigned char)(*ep))) ep++; |
292 | if (*ep == '\0') { | 295 | if (*ep == '\0') { |
293 | if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u)) | 296 | if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u)) |
294 | setintV(L->base-1, (int32_t)ul); | 297 | setintV(L->base-1-LJ_FR2, (int32_t)ul); |
295 | else | 298 | else |
296 | setnumV(L->base-1, (lua_Number)ul); | 299 | setnumV(L->base-1-LJ_FR2, (lua_Number)ul); |
297 | return FFH_RES(1); | 300 | return FFH_RES(1); |
298 | } | 301 | } |
299 | } | 302 | } |
300 | } | 303 | } |
301 | setnilV(L->base-1); | 304 | setnilV(L->base-1-LJ_FR2); |
302 | return FFH_RES(1); | 305 | return FFH_RES(1); |
303 | } | 306 | } |
304 | 307 | ||
@@ -308,11 +311,11 @@ LJLIB_ASM(tostring) LJLIB_REC(.) | |||
308 | cTValue *mo; | 311 | cTValue *mo; |
309 | L->top = o+1; /* Only keep one argument. */ | 312 | L->top = o+1; /* Only keep one argument. */ |
310 | if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { | 313 | if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { |
311 | copyTV(L, L->base-1, mo); /* Replace callable. */ | 314 | copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */ |
312 | return FFH_TAILCALL; | 315 | return FFH_TAILCALL; |
313 | } | 316 | } |
314 | lj_gc_check(L); | 317 | lj_gc_check(L); |
315 | setstrV(L, L->base-1, lj_strfmt_obj(L, L->base)); | 318 | setstrV(L, L->base-1-LJ_FR2, lj_strfmt_obj(L, L->base)); |
316 | return FFH_RES(1); | 319 | return FFH_RES(1); |
317 | } | 320 | } |
318 | 321 | ||
@@ -535,7 +538,7 @@ LJLIB_CF(coroutine_status) | |||
535 | if (co == L) s = "running"; | 538 | if (co == L) s = "running"; |
536 | else if (co->status == LUA_YIELD) s = "suspended"; | 539 | else if (co->status == LUA_YIELD) s = "suspended"; |
537 | else if (co->status != 0) s = "dead"; | 540 | else if (co->status != 0) s = "dead"; |
538 | else if (co->base > tvref(co->stack)+1) s = "normal"; | 541 | else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal"; |
539 | else if (co->top == co->base) s = "dead"; | 542 | else if (co->top == co->base) s = "dead"; |
540 | else s = "suspended"; | 543 | else s = "suspended"; |
541 | lua_pushstring(L, s); | 544 | lua_pushstring(L, s); |
@@ -577,8 +580,8 @@ static int ffh_resume(lua_State *L, lua_State *co, int wrap) | |||
577 | (co->status == 0 && co->top == co->base)) { | 580 | (co->status == 0 && co->top == co->base)) { |
578 | ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD; | 581 | ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD; |
579 | if (wrap) lj_err_caller(L, em); | 582 | if (wrap) lj_err_caller(L, em); |
580 | setboolV(L->base-1, 0); | 583 | setboolV(L->base-1-LJ_FR2, 0); |
581 | setstrV(L, L->base, lj_err_str(L, em)); | 584 | setstrV(L, L->base-LJ_FR2, lj_err_str(L, em)); |
582 | return FFH_RES(2); | 585 | return FFH_RES(2); |
583 | } | 586 | } |
584 | lj_state_growstack(co, (MSize)(L->top - L->base)); | 587 | lj_state_growstack(co, (MSize)(L->top - L->base)); |
diff --git a/src/lib_bit.c b/src/lib_bit.c index ffdc29c1..25731900 100644 --- a/src/lib_bit.c +++ b/src/lib_bit.c | |||
@@ -33,7 +33,7 @@ static int bit_result64(lua_State *L, CTypeID id, uint64_t x) | |||
33 | { | 33 | { |
34 | GCcdata *cd = lj_cdata_new_(L, id, 8); | 34 | GCcdata *cd = lj_cdata_new_(L, id, 8); |
35 | *(uint64_t *)cdataptr(cd) = x; | 35 | *(uint64_t *)cdataptr(cd) = x; |
36 | setcdataV(L, L->base-1, cd); | 36 | setcdataV(L, L->base-1-LJ_FR2, cd); |
37 | return FFH_RES(1); | 37 | return FFH_RES(1); |
38 | } | 38 | } |
39 | #else | 39 | #else |
@@ -56,7 +56,7 @@ LJLIB_ASM(bit_tobit) LJLIB_REC(bit_tobit) | |||
56 | { | 56 | { |
57 | #if LJ_HASFFI | 57 | #if LJ_HASFFI |
58 | CTypeID id = 0; | 58 | CTypeID id = 0; |
59 | setintV(L->base-1, (int32_t)lj_carith_check64(L, 1, &id)); | 59 | setintV(L->base-1-LJ_FR2, (int32_t)lj_carith_check64(L, 1, &id)); |
60 | return FFH_RES(1); | 60 | return FFH_RES(1); |
61 | #else | 61 | #else |
62 | lj_lib_checknumber(L, 1); | 62 | lj_lib_checknumber(L, 1); |
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index bc2339ce..d64f2167 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
@@ -138,7 +138,7 @@ static int ffi_index_meta(lua_State *L, CTState *cts, CType *ct, MMS mm) | |||
138 | } | 138 | } |
139 | } | 139 | } |
140 | copyTV(L, base, L->top); | 140 | copyTV(L, base, L->top); |
141 | tv = L->top-1; | 141 | tv = L->top-1-LJ_FR2; |
142 | } | 142 | } |
143 | return lj_meta_tailcall(L, tv); | 143 | return lj_meta_tailcall(L, tv); |
144 | } | 144 | } |
diff --git a/src/lib_math.c b/src/lib_math.c index 87ec2883..225630d0 100644 --- a/src/lib_math.c +++ b/src/lib_math.c | |||
@@ -57,7 +57,7 @@ LJLIB_ASM(math_log) LJLIB_REC(math_log) | |||
57 | #else | 57 | #else |
58 | x = lj_vm_log2(x); y = 1.0 / lj_vm_log2(y); | 58 | x = lj_vm_log2(x); y = 1.0 / lj_vm_log2(y); |
59 | #endif | 59 | #endif |
60 | setnumV(L->base-1, x*y); /* Do NOT join the expression to x / y. */ | 60 | setnumV(L->base-1-LJ_FR2, x*y); /* Do NOT join the expression to x / y. */ |
61 | return FFH_RES(1); | 61 | return FFH_RES(1); |
62 | } | 62 | } |
63 | return FFH_RETRY; | 63 | return FFH_RETRY; |
diff --git a/src/lib_string.c b/src/lib_string.c index 6ca7a76b..6cab0a19 100644 --- a/src/lib_string.c +++ b/src/lib_string.c | |||
@@ -58,7 +58,7 @@ LJLIB_ASM(string_byte) LJLIB_REC(string_range 0) | |||
58 | lj_state_checkstack(L, (MSize)n); | 58 | lj_state_checkstack(L, (MSize)n); |
59 | p = (const unsigned char *)strdata(s) + start; | 59 | p = (const unsigned char *)strdata(s) + start; |
60 | for (i = 0; i < n; i++) | 60 | for (i = 0; i < n; i++) |
61 | setintV(L->base + i-1, p[i]); | 61 | setintV(L->base + i-1-LJ_FR2, p[i]); |
62 | return FFH_RES(n); | 62 | return FFH_RES(n); |
63 | } | 63 | } |
64 | 64 | ||
@@ -72,7 +72,7 @@ LJLIB_ASM(string_char) LJLIB_REC(.) | |||
72 | lj_err_arg(L, i, LJ_ERR_BADVAL); | 72 | lj_err_arg(L, i, LJ_ERR_BADVAL); |
73 | buf[i-1] = (char)k; | 73 | buf[i-1] = (char)k; |
74 | } | 74 | } |
75 | setstrV(L, L->base-1, lj_str_new(L, buf, (size_t)nargs)); | 75 | setstrV(L, L->base-1-LJ_FR2, lj_str_new(L, buf, (size_t)nargs)); |
76 | return FFH_RES(1); | 76 | return FFH_RES(1); |
77 | } | 77 | } |
78 | 78 | ||
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); |
diff --git a/src/lj_arch.h b/src/lj_arch.h index 36b38886..8f3796fc 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h | |||
@@ -365,8 +365,11 @@ | |||
365 | #endif | 365 | #endif |
366 | #endif | 366 | #endif |
367 | 367 | ||
368 | /* 2-slot frame info. */ | ||
369 | #define LJ_FR2 0 | ||
370 | |||
368 | /* Disable or enable the JIT compiler. */ | 371 | /* Disable or enable the JIT compiler. */ |
369 | #if defined(LUAJIT_DISABLE_JIT) || defined(LJ_ARCH_NOJIT) || defined(LJ_OS_NOJIT) | 372 | #if defined(LUAJIT_DISABLE_JIT) || defined(LJ_ARCH_NOJIT) || defined(LJ_OS_NOJIT) || LJ_FR2 |
370 | #define LJ_HASJIT 0 | 373 | #define LJ_HASJIT 0 |
371 | #else | 374 | #else |
372 | #define LJ_HASJIT 1 | 375 | #define LJ_HASJIT 1 |
diff --git a/src/lj_asm.c b/src/lj_asm.c index e740e8a8..6002392c 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -1913,7 +1913,7 @@ static void asm_tail_link(ASMState *as) | |||
1913 | mres = (int32_t)(snap->nslots - baseslot); | 1913 | mres = (int32_t)(snap->nslots - baseslot); |
1914 | switch (bc_op(*pc)) { | 1914 | switch (bc_op(*pc)) { |
1915 | case BC_CALLM: case BC_CALLMT: | 1915 | case BC_CALLM: case BC_CALLMT: |
1916 | mres -= (int32_t)(1 + bc_a(*pc) + bc_c(*pc)); break; | 1916 | mres -= (int32_t)(1 + LJ_FR2 + bc_a(*pc) + bc_c(*pc)); break; |
1917 | case BC_RETM: mres -= (int32_t)(bc_a(*pc) + bc_d(*pc)); break; | 1917 | case BC_RETM: mres -= (int32_t)(bc_a(*pc) + bc_d(*pc)); break; |
1918 | case BC_TSETM: mres -= (int32_t)bc_a(*pc); break; | 1918 | case BC_TSETM: mres -= (int32_t)bc_a(*pc); break; |
1919 | default: if (bc_op(*pc) < BC_FUNCF) mres = 0; break; | 1919 | default: if (bc_op(*pc) < BC_FUNCF) mres = 0; break; |
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index 8339367b..f8915cfb 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h | |||
@@ -481,7 +481,7 @@ static void asm_retf(ASMState *as, IRIns *ir) | |||
481 | { | 481 | { |
482 | Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); | 482 | Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); |
483 | void *pc = ir_kptr(IR(ir->op2)); | 483 | void *pc = ir_kptr(IR(ir->op2)); |
484 | int32_t delta = 1+bc_a(*((const BCIns *)pc - 1)); | 484 | int32_t delta = 1+LJ_FR2+bc_a(*((const BCIns *)pc - 1)); |
485 | as->topslot -= (BCReg)delta; | 485 | as->topslot -= (BCReg)delta; |
486 | if ((int32_t)as->topslot < 0) as->topslot = 0; | 486 | if ((int32_t)as->topslot < 0) as->topslot = 0; |
487 | irt_setmark(IR(REF_BASE)->t); /* Children must not coalesce with BASE reg. */ | 487 | irt_setmark(IR(REF_BASE)->t); /* Children must not coalesce with BASE reg. */ |
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index bc521596..346e0254 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
@@ -372,7 +372,7 @@ static void asm_retf(ASMState *as, IRIns *ir) | |||
372 | { | 372 | { |
373 | Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); | 373 | Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); |
374 | void *pc = ir_kptr(IR(ir->op2)); | 374 | void *pc = ir_kptr(IR(ir->op2)); |
375 | int32_t delta = 1+bc_a(*((const BCIns *)pc - 1)); | 375 | int32_t delta = 1+LJ_FR2+bc_a(*((const BCIns *)pc - 1)); |
376 | as->topslot -= (BCReg)delta; | 376 | as->topslot -= (BCReg)delta; |
377 | if ((int32_t)as->topslot < 0) as->topslot = 0; | 377 | if ((int32_t)as->topslot < 0) as->topslot = 0; |
378 | irt_setmark(IR(REF_BASE)->t); /* Children must not coalesce with BASE reg. */ | 378 | irt_setmark(IR(REF_BASE)->t); /* Children must not coalesce with BASE reg. */ |
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index 815d9058..6fc8dfb7 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h | |||
@@ -361,7 +361,7 @@ static void asm_retf(ASMState *as, IRIns *ir) | |||
361 | { | 361 | { |
362 | Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); | 362 | Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); |
363 | void *pc = ir_kptr(IR(ir->op2)); | 363 | void *pc = ir_kptr(IR(ir->op2)); |
364 | int32_t delta = 1+bc_a(*((const BCIns *)pc - 1)); | 364 | int32_t delta = 1+LJ_FR2+bc_a(*((const BCIns *)pc - 1)); |
365 | as->topslot -= (BCReg)delta; | 365 | as->topslot -= (BCReg)delta; |
366 | if ((int32_t)as->topslot < 0) as->topslot = 0; | 366 | if ((int32_t)as->topslot < 0) as->topslot = 0; |
367 | irt_setmark(IR(REF_BASE)->t); /* Children must not coalesce with BASE reg. */ | 367 | irt_setmark(IR(REF_BASE)->t); /* Children must not coalesce with BASE reg. */ |
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index bd97764f..c4c7300d 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
@@ -643,7 +643,7 @@ static void asm_retf(ASMState *as, IRIns *ir) | |||
643 | { | 643 | { |
644 | Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); | 644 | Reg base = ra_alloc1(as, REF_BASE, RSET_GPR); |
645 | void *pc = ir_kptr(IR(ir->op2)); | 645 | void *pc = ir_kptr(IR(ir->op2)); |
646 | int32_t delta = 1+bc_a(*((const BCIns *)pc - 1)); | 646 | int32_t delta = 1+LJ_FR2+bc_a(*((const BCIns *)pc - 1)); |
647 | as->topslot -= (BCReg)delta; | 647 | as->topslot -= (BCReg)delta; |
648 | if ((int32_t)as->topslot < 0) as->topslot = 0; | 648 | if ((int32_t)as->topslot < 0) as->topslot = 0; |
649 | irt_setmark(IR(REF_BASE)->t); /* Children must not coalesce with BASE reg. */ | 649 | irt_setmark(IR(REF_BASE)->t); /* Children must not coalesce with BASE reg. */ |
diff --git a/src/lj_bcdump.h b/src/lj_bcdump.h index 940ed147..ba6edfcc 100644 --- a/src/lj_bcdump.h +++ b/src/lj_bcdump.h | |||
@@ -42,8 +42,9 @@ | |||
42 | #define BCDUMP_F_BE 0x01 | 42 | #define BCDUMP_F_BE 0x01 |
43 | #define BCDUMP_F_STRIP 0x02 | 43 | #define BCDUMP_F_STRIP 0x02 |
44 | #define BCDUMP_F_FFI 0x04 | 44 | #define BCDUMP_F_FFI 0x04 |
45 | #define BCDUMP_F_FR2 0x08 | ||
45 | 46 | ||
46 | #define BCDUMP_F_KNOWN (BCDUMP_F_FFI*2-1) | 47 | #define BCDUMP_F_KNOWN (BCDUMP_F_FR2*2-1) |
47 | 48 | ||
48 | /* Type codes for the GC constants of a prototype. Plus length for strings. */ | 49 | /* Type codes for the GC constants of a prototype. Plus length for strings. */ |
49 | enum { | 50 | enum { |
diff --git a/src/lj_bcread.c b/src/lj_bcread.c index cea20e90..898f029c 100644 --- a/src/lj_bcread.c +++ b/src/lj_bcread.c | |||
@@ -394,6 +394,7 @@ static int bcread_header(LexState *ls) | |||
394 | bcread_byte(ls) != BCDUMP_VERSION) return 0; | 394 | bcread_byte(ls) != BCDUMP_VERSION) return 0; |
395 | bcread_flags(ls) = flags = bcread_uleb128(ls); | 395 | bcread_flags(ls) = flags = bcread_uleb128(ls); |
396 | if ((flags & ~(BCDUMP_F_KNOWN)) != 0) return 0; | 396 | if ((flags & ~(BCDUMP_F_KNOWN)) != 0) return 0; |
397 | if ((flags & BCDUMP_F_FR2) != LJ_FR2*BCDUMP_F_FR2) return 0; | ||
397 | if ((flags & BCDUMP_F_FFI)) { | 398 | if ((flags & BCDUMP_F_FFI)) { |
398 | #if LJ_HASFFI | 399 | #if LJ_HASFFI |
399 | lua_State *L = ls->L; | 400 | lua_State *L = ls->L; |
diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c index a70735ca..cc51d0b2 100644 --- a/src/lj_bcwrite.c +++ b/src/lj_bcwrite.c | |||
@@ -309,8 +309,9 @@ static void bcwrite_header(BCWriteCtx *ctx) | |||
309 | *p++ = BCDUMP_HEAD3; | 309 | *p++ = BCDUMP_HEAD3; |
310 | *p++ = BCDUMP_VERSION; | 310 | *p++ = BCDUMP_VERSION; |
311 | *p++ = (ctx->strip ? BCDUMP_F_STRIP : 0) + | 311 | *p++ = (ctx->strip ? BCDUMP_F_STRIP : 0) + |
312 | (LJ_BE ? BCDUMP_F_BE : 0) + | 312 | LJ_BE*BCDUMP_F_BE + |
313 | ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0); | 313 | ((ctx->pt->flags & PROTO_FFI) ? BCDUMP_F_FFI : 0) + |
314 | LJ_FR2*BCDUMP_F_FR2; | ||
314 | if (!ctx->strip) { | 315 | if (!ctx->strip) { |
315 | p = lj_strfmt_wuleb128(p, len); | 316 | p = lj_strfmt_wuleb128(p, len); |
316 | p = lj_buf_wmem(p, name, len); | 317 | p = lj_buf_wmem(p, name, len); |
diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index 5fe63a76..60735ade 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c | |||
@@ -422,7 +422,7 @@ static void callback_conv_args(CTState *cts, lua_State *L) | |||
422 | 422 | ||
423 | if (slot < cts->cb.sizeid && (id = cts->cb.cbid[slot]) != 0) { | 423 | if (slot < cts->cb.sizeid && (id = cts->cb.cbid[slot]) != 0) { |
424 | ct = ctype_get(cts, id); | 424 | ct = ctype_get(cts, id); |
425 | rid = ctype_cid(ct->info); | 425 | rid = ctype_cid(ct->info); /* Return type. x86: +(spadj<<16). */ |
426 | fn = funcV(lj_tab_getint(cts->miscmap, (int32_t)slot)); | 426 | fn = funcV(lj_tab_getint(cts->miscmap, (int32_t)slot)); |
427 | fntp = LJ_TFUNC; | 427 | fntp = LJ_TFUNC; |
428 | } else { /* Must set up frame first, before throwing the error. */ | 428 | } else { /* Must set up frame first, before throwing the error. */ |
@@ -431,9 +431,16 @@ static void callback_conv_args(CTState *cts, lua_State *L) | |||
431 | fn = (GCfunc *)L; | 431 | fn = (GCfunc *)L; |
432 | fntp = LJ_TTHREAD; | 432 | fntp = LJ_TTHREAD; |
433 | } | 433 | } |
434 | o->u32.lo = LJ_CONT_FFI_CALLBACK; /* Continuation returns from callback. */ | 434 | /* Continuation returns from callback. */ |
435 | o->u32.hi = rid; /* Return type. x86: +(spadj<<16). */ | 435 | if (LJ_FR2) { |
436 | o++; | 436 | (o++)->u64 = LJ_CONT_FFI_CALLBACK; |
437 | (o++)->u64 = rid; | ||
438 | o++; | ||
439 | } else { | ||
440 | o->u32.lo = LJ_CONT_FFI_CALLBACK; | ||
441 | o->u32.hi = rid; | ||
442 | o++; | ||
443 | } | ||
437 | setframe_gc(o, obj2gco(fn), fntp); | 444 | setframe_gc(o, obj2gco(fn), fntp); |
438 | setframe_ftsz(o, ((char *)(o+1) - (char *)L->base) + FRAME_CONT); | 445 | setframe_ftsz(o, ((char *)(o+1) - (char *)L->base) + FRAME_CONT); |
439 | L->top = L->base = ++o; | 446 | L->top = L->base = ++o; |
@@ -486,9 +493,14 @@ static void callback_conv_args(CTState *cts, lua_State *L) | |||
486 | L->top = o; | 493 | L->top = o; |
487 | #if LJ_TARGET_X86 | 494 | #if LJ_TARGET_X86 |
488 | /* Store stack adjustment for returns from non-cdecl callbacks. */ | 495 | /* Store stack adjustment for returns from non-cdecl callbacks. */ |
489 | if (ctype_cconv(ct->info) != CTCC_CDECL) | 496 | if (ctype_cconv(ct->info) != CTCC_CDECL) { |
497 | #if LJ_FR2 | ||
498 | (L->base-3)->u64 |= (nsp << (16+2)); | ||
499 | #else | ||
490 | (L->base-2)->u32.hi |= (nsp << (16+2)); | 500 | (L->base-2)->u32.hi |= (nsp << (16+2)); |
491 | #endif | 501 | #endif |
502 | } | ||
503 | #endif | ||
492 | while (gcsteps-- > 0) | 504 | while (gcsteps-- > 0) |
493 | lj_gc_check(L); | 505 | lj_gc_check(L); |
494 | } | 506 | } |
@@ -496,7 +508,11 @@ static void callback_conv_args(CTState *cts, lua_State *L) | |||
496 | /* Convert Lua object to callback result. */ | 508 | /* Convert Lua object to callback result. */ |
497 | static void callback_conv_result(CTState *cts, lua_State *L, TValue *o) | 509 | static void callback_conv_result(CTState *cts, lua_State *L, TValue *o) |
498 | { | 510 | { |
511 | #if LJ_FR2 | ||
512 | CType *ctr = ctype_raw(cts, (uint16_t)(L->base-3)->u64); | ||
513 | #else | ||
499 | CType *ctr = ctype_raw(cts, (uint16_t)(L->base-2)->u32.hi); | 514 | CType *ctr = ctype_raw(cts, (uint16_t)(L->base-2)->u32.hi); |
515 | #endif | ||
500 | #if LJ_TARGET_X86 | 516 | #if LJ_TARGET_X86 |
501 | cts->cb.gpr[2] = 0; | 517 | cts->cb.gpr[2] = 0; |
502 | #endif | 518 | #endif |
@@ -565,7 +581,7 @@ void LJ_FASTCALL lj_ccallback_leave(CTState *cts, TValue *o) | |||
565 | } | 581 | } |
566 | callback_conv_result(cts, L, o); | 582 | callback_conv_result(cts, L, o); |
567 | /* Finally drop C frame and continuation frame. */ | 583 | /* Finally drop C frame and continuation frame. */ |
568 | L->top -= 2; | 584 | L->top -= 2+2*LJ_FR2; |
569 | L->base = obase; | 585 | L->base = obase; |
570 | L->cframe = cframe_prev(L->cframe); | 586 | L->cframe = cframe_prev(L->cframe); |
571 | cts->cb.slot = 0; /* Blacklist C function that called the callback. */ | 587 | cts->cb.slot = 0; /* Blacklist C function that called the callback. */ |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index eb37597a..10334cec 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -1123,7 +1123,7 @@ static void crec_snap_caller(jit_State *J) | |||
1123 | ptrdiff_t delta; | 1123 | ptrdiff_t delta; |
1124 | if (!frame_islua(base-1) || J->framedepth <= 0) | 1124 | if (!frame_islua(base-1) || J->framedepth <= 0) |
1125 | lj_trace_err(J, LJ_TRERR_NYICALL); | 1125 | lj_trace_err(J, LJ_TRERR_NYICALL); |
1126 | J->pc = frame_pc(base-1); delta = 1+bc_a(J->pc[-1]); | 1126 | J->pc = frame_pc(base-1); delta = 1+LJ_FR2+bc_a(J->pc[-1]); |
1127 | L->top = base; L->base = base - delta; | 1127 | L->top = base; L->base = base - delta; |
1128 | J->base[-1] = TREF_FALSE; | 1128 | J->base[-1] = TREF_FALSE; |
1129 | J->base -= delta; J->baseslot -= (BCReg)delta; | 1129 | J->base -= delta; J->baseslot -= (BCReg)delta; |
diff --git a/src/lj_debug.c b/src/lj_debug.c index 1b794753..e9117b31 100644 --- a/src/lj_debug.c +++ b/src/lj_debug.c | |||
@@ -24,7 +24,7 @@ | |||
24 | /* Get frame corresponding to a level. */ | 24 | /* Get frame corresponding to a level. */ |
25 | cTValue *lj_debug_frame(lua_State *L, int level, int *size) | 25 | cTValue *lj_debug_frame(lua_State *L, int level, int *size) |
26 | { | 26 | { |
27 | cTValue *frame, *nextframe, *bot = tvref(L->stack); | 27 | cTValue *frame, *nextframe, *bot = tvref(L->stack)+LJ_FR2; |
28 | /* Traverse frames backwards. */ | 28 | /* Traverse frames backwards. */ |
29 | for (nextframe = frame = L->base-1; frame > bot; ) { | 29 | for (nextframe = frame = L->base-1; frame > bot; ) { |
30 | if (frame_gc(frame) == obj2gco(L)) | 30 | if (frame_gc(frame) == obj2gco(L)) |
@@ -184,7 +184,7 @@ static TValue *debug_localname(lua_State *L, const lua_Debug *ar, | |||
184 | TValue *nextframe = size ? frame + size : NULL; | 184 | TValue *nextframe = size ? frame + size : NULL; |
185 | GCfunc *fn = frame_func(frame); | 185 | GCfunc *fn = frame_func(frame); |
186 | BCPos pc = debug_framepc(L, fn, nextframe); | 186 | BCPos pc = debug_framepc(L, fn, nextframe); |
187 | if (!nextframe) nextframe = L->top; | 187 | if (!nextframe) nextframe = L->top+LJ_FR2; |
188 | if ((int)slot1 < 0) { /* Negative slot number is for varargs. */ | 188 | if ((int)slot1 < 0) { /* Negative slot number is for varargs. */ |
189 | if (pc != NO_BCPOS) { | 189 | if (pc != NO_BCPOS) { |
190 | GCproto *pt = funcproto(fn); | 190 | GCproto *pt = funcproto(fn); |
@@ -194,7 +194,7 @@ static TValue *debug_localname(lua_State *L, const lua_Debug *ar, | |||
194 | nextframe = frame; | 194 | nextframe = frame; |
195 | frame = frame_prevd(frame); | 195 | frame = frame_prevd(frame); |
196 | } | 196 | } |
197 | if (frame + slot1 < nextframe) { | 197 | if (frame + slot1+LJ_FR2 < nextframe) { |
198 | *name = "(*vararg)"; | 198 | *name = "(*vararg)"; |
199 | return frame+slot1; | 199 | return frame+slot1; |
200 | } | 200 | } |
@@ -205,7 +205,7 @@ static TValue *debug_localname(lua_State *L, const lua_Debug *ar, | |||
205 | if (pc != NO_BCPOS && | 205 | if (pc != NO_BCPOS && |
206 | (*name = debug_varname(funcproto(fn), pc, slot1-1)) != NULL) | 206 | (*name = debug_varname(funcproto(fn), pc, slot1-1)) != NULL) |
207 | ; | 207 | ; |
208 | else if (slot1 > 0 && frame + slot1 < nextframe) | 208 | else if (slot1 > 0 && frame + slot1+LJ_FR2 < nextframe) |
209 | *name = "(*temporary)"; | 209 | *name = "(*temporary)"; |
210 | return frame+slot1; | 210 | return frame+slot1; |
211 | } | 211 | } |
@@ -268,7 +268,7 @@ restart: | |||
268 | *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins)))); | 268 | *name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins)))); |
269 | if (ip > proto_bc(pt)) { | 269 | if (ip > proto_bc(pt)) { |
270 | BCIns insp = ip[-1]; | 270 | BCIns insp = ip[-1]; |
271 | if (bc_op(insp) == BC_MOV && bc_a(insp) == ra+1 && | 271 | if (bc_op(insp) == BC_MOV && bc_a(insp) == ra+1+LJ_FR2 && |
272 | bc_d(insp) == bc_b(ins)) | 272 | bc_d(insp) == bc_b(ins)) |
273 | return "method"; | 273 | return "method"; |
274 | } | 274 | } |
@@ -290,7 +290,7 @@ const char *lj_debug_funcname(lua_State *L, cTValue *frame, const char **name) | |||
290 | cTValue *pframe; | 290 | cTValue *pframe; |
291 | GCfunc *fn; | 291 | GCfunc *fn; |
292 | BCPos pc; | 292 | BCPos pc; |
293 | if (frame <= tvref(L->stack)) | 293 | if (frame <= tvref(L->stack)+LJ_FR2) |
294 | return NULL; | 294 | return NULL; |
295 | if (frame_isvarg(frame)) | 295 | if (frame_isvarg(frame)) |
296 | frame = frame_prevd(frame); | 296 | frame = frame_prevd(frame); |
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c index ea196ef2..8ce587a3 100644 --- a/src/lj_dispatch.c +++ b/src/lj_dispatch.c | |||
@@ -393,7 +393,7 @@ static BCReg cur_topslot(GCproto *pt, const BCIns *pc, uint32_t nres) | |||
393 | if (bc_op(ins) == BC_UCLO) | 393 | if (bc_op(ins) == BC_UCLO) |
394 | ins = pc[bc_j(ins)]; | 394 | ins = pc[bc_j(ins)]; |
395 | switch (bc_op(ins)) { | 395 | switch (bc_op(ins)) { |
396 | case BC_CALLM: case BC_CALLMT: return bc_a(ins) + bc_c(ins) + nres-1+1; | 396 | case BC_CALLM: case BC_CALLMT: return bc_a(ins) + bc_c(ins) + nres-1+1+LJ_FR2; |
397 | case BC_RETM: return bc_a(ins) + bc_d(ins) + nres-1; | 397 | case BC_RETM: return bc_a(ins) + bc_d(ins) + nres-1; |
398 | case BC_TSETM: return bc_a(ins) + nres-1; | 398 | case BC_TSETM: return bc_a(ins) + nres-1; |
399 | default: return pt->framesize; | 399 | default: return pt->framesize; |
diff --git a/src/lj_err.c b/src/lj_err.c index a824ee66..5be938e4 100644 --- a/src/lj_err.c +++ b/src/lj_err.c | |||
@@ -106,7 +106,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
106 | return cf; | 106 | return cf; |
107 | } | 107 | } |
108 | } | 108 | } |
109 | if (frame <= tvref(L->stack)) | 109 | if (frame <= tvref(L->stack)+LJ_FR2) |
110 | break; | 110 | break; |
111 | switch (frame_typep(frame)) { | 111 | switch (frame_typep(frame)) { |
112 | case FRAME_LUA: /* Lua frame. */ | 112 | case FRAME_LUA: /* Lua frame. */ |
@@ -171,7 +171,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
171 | } | 171 | } |
172 | /* No C frame. */ | 172 | /* No C frame. */ |
173 | if (errcode) { | 173 | if (errcode) { |
174 | L->base = tvref(L->stack)+1; | 174 | L->base = tvref(L->stack)+1+LJ_FR2; |
175 | L->cframe = NULL; | 175 | L->cframe = NULL; |
176 | unwindstack(L, L->base); | 176 | unwindstack(L, L->base); |
177 | if (G(L)->panic) | 177 | if (G(L)->panic) |
@@ -494,7 +494,7 @@ LJ_NOINLINE void lj_err_mem(lua_State *L) | |||
494 | /* Find error function for runtime errors. Requires an extra stack traversal. */ | 494 | /* Find error function for runtime errors. Requires an extra stack traversal. */ |
495 | static ptrdiff_t finderrfunc(lua_State *L) | 495 | static ptrdiff_t finderrfunc(lua_State *L) |
496 | { | 496 | { |
497 | cTValue *frame = L->base-1, *bot = tvref(L->stack); | 497 | cTValue *frame = L->base-1, *bot = tvref(L->stack)+LJ_FR2; |
498 | void *cf = L->cframe; | 498 | void *cf = L->cframe; |
499 | while (frame > bot && cf) { | 499 | while (frame > bot && cf) { |
500 | while (cframe_nres(cframe_raw(cf)) < 0) { /* cframe without frame? */ | 500 | while (cframe_nres(cframe_raw(cf)) < 0) { /* cframe without frame? */ |
@@ -530,8 +530,8 @@ static ptrdiff_t finderrfunc(lua_State *L) | |||
530 | break; | 530 | break; |
531 | case FRAME_PCALL: | 531 | case FRAME_PCALL: |
532 | case FRAME_PCALLH: | 532 | case FRAME_PCALLH: |
533 | if (frame_ftsz(frame) >= (ptrdiff_t)(2*sizeof(TValue))) /* xpcall? */ | 533 | if (frame_func(frame_prevd(frame))->c.ffid == FF_xpcall) |
534 | return savestack(L, frame-1); /* Point to xpcall's errorfunc. */ | 534 | return savestack(L, frame_prevd(frame)+1); /* xpcall's errorfunc. */ |
535 | return 0; | 535 | return 0; |
536 | default: | 536 | default: |
537 | lua_assert(0); | 537 | lua_assert(0); |
@@ -554,8 +554,9 @@ LJ_NOINLINE void lj_err_run(lua_State *L) | |||
554 | lj_err_throw(L, LUA_ERRERR); | 554 | lj_err_throw(L, LUA_ERRERR); |
555 | } | 555 | } |
556 | L->status = LUA_ERRERR; | 556 | L->status = LUA_ERRERR; |
557 | copyTV(L, top, top-1); | 557 | copyTV(L, top+LJ_FR2, top-1); |
558 | copyTV(L, top-1, errfunc); | 558 | copyTV(L, top-1, errfunc); |
559 | if (LJ_FR2) setnilV(top++); | ||
559 | L->top = top+1; | 560 | L->top = top+1; |
560 | lj_vm_call(L, top, 1+1); /* Stack: |errfunc|msg| -> |msg| */ | 561 | lj_vm_call(L, top, 1+1); /* Stack: |errfunc|msg| -> |msg| */ |
561 | } | 562 | } |
@@ -630,6 +631,7 @@ LJ_NOINLINE void lj_err_optype_call(lua_State *L, TValue *o) | |||
630 | const BCIns *pc = cframe_Lpc(L); | 631 | const BCIns *pc = cframe_Lpc(L); |
631 | if (((ptrdiff_t)pc & FRAME_TYPE) != FRAME_LUA) { | 632 | if (((ptrdiff_t)pc & FRAME_TYPE) != FRAME_LUA) { |
632 | const char *tname = lj_typename(o); | 633 | const char *tname = lj_typename(o); |
634 | if (LJ_FR2) o++; | ||
633 | setframe_pc(o, pc); | 635 | setframe_pc(o, pc); |
634 | setframe_gc(o, obj2gco(L), LJ_TTHREAD); | 636 | setframe_gc(o, obj2gco(L), LJ_TTHREAD); |
635 | L->top = L->base = o+1; | 637 | L->top = L->base = o+1; |
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index b65759a5..55cdc63e 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c | |||
@@ -107,6 +107,7 @@ static void recff_stitch(jit_State *J) | |||
107 | TValue *pframe = frame_prevl(base-1); | 107 | TValue *pframe = frame_prevl(base-1); |
108 | TRef trcont; | 108 | TRef trcont; |
109 | 109 | ||
110 | lua_assert(!LJ_FR2); /* TODO_FR2: handle frame shift. */ | ||
110 | /* Move func + args up in Lua stack and insert continuation. */ | 111 | /* Move func + args up in Lua stack and insert continuation. */ |
111 | memmove(&base[1], &base[-1], sizeof(TValue)*(J->maxslot+1)); | 112 | memmove(&base[1], &base[-1], sizeof(TValue)*(J->maxslot+1)); |
112 | setframe_ftsz(base+1, ((char *)(base+1) - (char *)pframe) + FRAME_CONT); | 113 | setframe_ftsz(base+1, ((char *)(base+1) - (char *)pframe) + FRAME_CONT); |
@@ -466,6 +467,7 @@ static void LJ_FASTCALL recff_xpcall(jit_State *J, RecordFFData *rd) | |||
466 | TValue argv0, argv1; | 467 | TValue argv0, argv1; |
467 | TRef tmp; | 468 | TRef tmp; |
468 | int errcode; | 469 | int errcode; |
470 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
469 | /* Swap function and traceback. */ | 471 | /* Swap function and traceback. */ |
470 | tmp = J->base[0]; J->base[0] = J->base[1]; J->base[1] = tmp; | 472 | tmp = J->base[0]; J->base[0] = J->base[1]; J->base[1] = tmp; |
471 | copyTV(J->L, &argv0, &rd->argv[0]); | 473 | copyTV(J->L, &argv0, &rd->argv[0]); |
diff --git a/src/lj_frame.h b/src/lj_frame.h index 061b396c..226d74f1 100644 --- a/src/lj_frame.h +++ b/src/lj_frame.h | |||
@@ -11,7 +11,16 @@ | |||
11 | 11 | ||
12 | /* -- Lua stack frame ----------------------------------------------------- */ | 12 | /* -- Lua stack frame ----------------------------------------------------- */ |
13 | 13 | ||
14 | /* Frame type markers in callee function slot (callee base-1). */ | 14 | /* Frame type markers in LSB of PC (4-byte aligned) or delta (8-byte aligned: |
15 | ** | ||
16 | ** PC 00 Lua frame | ||
17 | ** delta 001 C frame | ||
18 | ** delta 010 Continuation frame | ||
19 | ** delta 011 Lua vararg frame | ||
20 | ** delta 101 cpcall() frame | ||
21 | ** delta 110 ff pcall() frame | ||
22 | ** delta 111 ff pcall() frame with active hook | ||
23 | */ | ||
15 | enum { | 24 | enum { |
16 | FRAME_LUA, FRAME_C, FRAME_CONT, FRAME_VARG, | 25 | FRAME_LUA, FRAME_C, FRAME_CONT, FRAME_VARG, |
17 | FRAME_LUAP, FRAME_CP, FRAME_PCALL, FRAME_PCALLH | 26 | FRAME_LUAP, FRAME_CP, FRAME_PCALL, FRAME_PCALLH |
@@ -21,12 +30,47 @@ enum { | |||
21 | #define FRAME_TYPEP (FRAME_TYPE|FRAME_P) | 30 | #define FRAME_TYPEP (FRAME_TYPE|FRAME_P) |
22 | 31 | ||
23 | /* Macros to access and modify Lua frames. */ | 32 | /* Macros to access and modify Lua frames. */ |
33 | #if LJ_FR2 | ||
34 | /* Two-slot frame info, required for 64 bit PC/GCRef: | ||
35 | ** | ||
36 | ** base-2 base-1 | base base+1 ... | ||
37 | ** [func PC/delta/ft] | [slots ...] | ||
38 | ** ^-- frame | ^-- base ^-- top | ||
39 | ** | ||
40 | ** Continuation frames: | ||
41 | ** | ||
42 | ** base-4 base-3 base-2 base-1 | base base+1 ... | ||
43 | ** [cont PC ] [func PC/delta/ft] | [slots ...] | ||
44 | ** ^-- frame | ^-- base ^-- top | ||
45 | */ | ||
46 | #define frame_gc(f) (gcval((f)-1)) | ||
47 | #define frame_ftsz(f) ((ptrdiff_t)(f)->ftsz) | ||
48 | #define frame_pc(f) ((const BCIns *)frame_ftsz(f)) | ||
49 | #define setframe_gc(f, p, tp) (setgcVraw((f)-1, (p), (tp))) | ||
50 | #define setframe_ftsz(f, sz) ((f)->ftsz = (sz)) | ||
51 | #define setframe_pc(f, pc) ((f)->ftsz = (int64_t)(intptr_t)(pc)) | ||
52 | #else | ||
53 | /* One-slot frame info, sufficient for 32 bit PC/GCRef: | ||
54 | ** | ||
55 | ** base-1 | base base+1 ... | ||
56 | ** lo hi | | ||
57 | ** [func | PC/delta/ft] | [slots ...] | ||
58 | ** ^-- frame | ^-- base ^-- top | ||
59 | ** | ||
60 | ** Continuation frames: | ||
61 | ** | ||
62 | ** base-2 base-1 | base base+1 ... | ||
63 | ** lo hi lo hi | | ||
64 | ** [cont | PC] [func | PC/delta/ft] | [slots ...] | ||
65 | ** ^-- frame | ^-- base ^-- top | ||
66 | */ | ||
24 | #define frame_gc(f) (gcref((f)->fr.func)) | 67 | #define frame_gc(f) (gcref((f)->fr.func)) |
25 | #define frame_ftsz(f) ((ptrdiff_t)(f)->fr.tp.ftsz) | 68 | #define frame_ftsz(f) ((ptrdiff_t)(f)->fr.tp.ftsz) |
26 | #define frame_pc(f) (mref((f)->fr.tp.pcr, const BCIns)) | 69 | #define frame_pc(f) (mref((f)->fr.tp.pcr, const BCIns)) |
27 | #define setframe_gc(f, p, tp) (setgcref((f)->fr.func, (p)), UNUSED(tp)) | 70 | #define setframe_gc(f, p, tp) (setgcref((f)->fr.func, (p)), UNUSED(tp)) |
28 | #define setframe_ftsz(f, sz) ((f)->fr.tp.ftsz = (int32_t)(sz)) | 71 | #define setframe_ftsz(f, sz) ((f)->fr.tp.ftsz = (int32_t)(sz)) |
29 | #define setframe_pc(f, pc) (setmref((f)->fr.tp.pcr, (pc))) | 72 | #define setframe_pc(f, pc) (setmref((f)->fr.tp.pcr, (pc))) |
73 | #endif | ||
30 | 74 | ||
31 | #define frame_type(f) (frame_ftsz(f) & FRAME_TYPE) | 75 | #define frame_type(f) (frame_ftsz(f) & FRAME_TYPE) |
32 | #define frame_typep(f) (frame_ftsz(f) & FRAME_TYPEP) | 76 | #define frame_typep(f) (frame_ftsz(f) & FRAME_TYPEP) |
@@ -42,9 +86,16 @@ enum { | |||
42 | 86 | ||
43 | enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ | 87 | enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ |
44 | 88 | ||
89 | #if LJ_FR2 | ||
90 | #define frame_contpc(f) (frame_pc((f)-2)) | ||
91 | #define frame_contv(f) (((f)-3)->u64) | ||
92 | #else | ||
45 | #define frame_contpc(f) (frame_pc((f)-1)) | 93 | #define frame_contpc(f) (frame_pc((f)-1)) |
46 | #define frame_contv(f) (((f)-1)->u32.lo) | 94 | #define frame_contv(f) (((f)-1)->u32.lo) |
47 | #if LJ_64 | 95 | #endif |
96 | #if LJ_FR2 | ||
97 | #define frame_contf(f) ((ASMFunction)(uintptr_t)((f)-3)->u64) | ||
98 | #elif LJ_64 | ||
48 | #define frame_contf(f) \ | 99 | #define frame_contf(f) \ |
49 | ((ASMFunction)(void *)((intptr_t)lj_vm_asm_begin + \ | 100 | ((ASMFunction)(void *)((intptr_t)lj_vm_asm_begin + \ |
50 | (intptr_t)(int32_t)((f)-1)->u32.lo)) | 101 | (intptr_t)(int32_t)((f)-1)->u32.lo)) |
@@ -54,7 +105,7 @@ enum { LJ_CONT_TAILCALL, LJ_CONT_FFI_CALLBACK }; /* Special continuations. */ | |||
54 | #define frame_iscont_fficb(f) \ | 105 | #define frame_iscont_fficb(f) \ |
55 | (LJ_HASFFI && frame_contv(f) == LJ_CONT_FFI_CALLBACK) | 106 | (LJ_HASFFI && frame_contv(f) == LJ_CONT_FFI_CALLBACK) |
56 | 107 | ||
57 | #define frame_prevl(f) ((f) - (1+bc_a(frame_pc(f)[-1]))) | 108 | #define frame_prevl(f) ((f) - (1+LJ_FR2+bc_a(frame_pc(f)[-1]))) |
58 | #define frame_prevd(f) ((TValue *)((char *)(f) - frame_sized(f))) | 109 | #define frame_prevd(f) ((TValue *)((char *)(f) - frame_sized(f))) |
59 | #define frame_prev(f) (frame_islua(f)?frame_prevl(f):frame_prevd(f)) | 110 | #define frame_prev(f) (frame_islua(f)?frame_prevl(f):frame_prevd(f)) |
60 | /* Note: this macro does not skip over FRAME_VARG. */ | 111 | /* Note: this macro does not skip over FRAME_VARG. */ |
diff --git a/src/lj_gc.c b/src/lj_gc.c index 5a7127c2..d6dfde93 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c | |||
@@ -268,12 +268,12 @@ static MSize gc_traverse_frames(global_State *g, lua_State *th) | |||
268 | { | 268 | { |
269 | TValue *frame, *top = th->top-1, *bot = tvref(th->stack); | 269 | TValue *frame, *top = th->top-1, *bot = tvref(th->stack); |
270 | /* Note: extra vararg frame not skipped, marks function twice (harmless). */ | 270 | /* Note: extra vararg frame not skipped, marks function twice (harmless). */ |
271 | for (frame = th->base-1; frame > bot; frame = frame_prev(frame)) { | 271 | for (frame = th->base-1; frame > bot+LJ_FR2; frame = frame_prev(frame)) { |
272 | GCfunc *fn = frame_func(frame); | 272 | GCfunc *fn = frame_func(frame); |
273 | TValue *ftop = frame; | 273 | TValue *ftop = frame; |
274 | if (isluafunc(fn)) ftop += funcproto(fn)->framesize; | 274 | if (isluafunc(fn)) ftop += funcproto(fn)->framesize; |
275 | if (ftop > top) top = ftop; | 275 | if (ftop > top) top = ftop; |
276 | gc_markobj(g, fn); /* Need to mark hidden function (or L). */ | 276 | if (!LJ_FR2) gc_markobj(g, fn); /* Need to mark hidden function (or L). */ |
277 | } | 277 | } |
278 | top++; /* Correct bias of -1 (frame == base-1). */ | 278 | top++; /* Correct bias of -1 (frame == base-1). */ |
279 | if (top > tvref(th->maxstack)) top = tvref(th->maxstack); | 279 | if (top > tvref(th->maxstack)) top = tvref(th->maxstack); |
@@ -284,7 +284,7 @@ static MSize gc_traverse_frames(global_State *g, lua_State *th) | |||
284 | static void gc_traverse_thread(global_State *g, lua_State *th) | 284 | static void gc_traverse_thread(global_State *g, lua_State *th) |
285 | { | 285 | { |
286 | TValue *o, *top = th->top; | 286 | TValue *o, *top = th->top; |
287 | for (o = tvref(th->stack)+1; o < top; o++) | 287 | for (o = tvref(th->stack)+1+LJ_FR2; o < top; o++) |
288 | gc_marktv(g, o); | 288 | gc_marktv(g, o); |
289 | if (g->gc.state == GCSatomic) { | 289 | if (g->gc.state == GCSatomic) { |
290 | top = tvref(th->stack) + th->stacksize; | 290 | top = tvref(th->stack) + th->stacksize; |
@@ -456,13 +456,14 @@ static void gc_call_finalizer(global_State *g, lua_State *L, | |||
456 | int errcode; | 456 | int errcode; |
457 | TValue *top; | 457 | TValue *top; |
458 | lj_trace_abort(g); | 458 | lj_trace_abort(g); |
459 | top = L->top; | ||
460 | L->top = top+2; | ||
461 | hook_entergc(g); /* Disable hooks and new traces during __gc. */ | 459 | hook_entergc(g); /* Disable hooks and new traces during __gc. */ |
462 | g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */ | 460 | g->gc.threshold = LJ_MAX_MEM; /* Prevent GC steps. */ |
463 | copyTV(L, top, mo); | 461 | top = L->top; |
464 | setgcV(L, top+1, o, ~o->gch.gct); | 462 | copyTV(L, top++, mo); |
465 | errcode = lj_vm_pcall(L, top+1, 1+0, -1); /* Stack: |mo|o| -> | */ | 463 | if (LJ_FR2) setnilV(top++); |
464 | setgcV(L, top, o, ~o->gch.gct); | ||
465 | L->top = top+1; | ||
466 | errcode = lj_vm_pcall(L, top, 1+0, -1); /* Stack: |mo|o| -> | */ | ||
466 | hook_restore(g, oldh); | 467 | hook_restore(g, oldh); |
467 | g->gc.threshold = oldt; /* Restore GC threshold. */ | 468 | g->gc.threshold = oldt; /* Restore GC threshold. */ |
468 | if (errcode) | 469 | if (errcode) |
diff --git a/src/lj_lib.h b/src/lj_lib.h index 5bfd8d7c..dff99c09 100644 --- a/src/lj_lib.h +++ b/src/lj_lib.h | |||
@@ -47,8 +47,13 @@ LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg); | |||
47 | LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst); | 47 | LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst); |
48 | 48 | ||
49 | /* Avoid including lj_frame.h. */ | 49 | /* Avoid including lj_frame.h. */ |
50 | #if LJ_FR2 | ||
51 | #define lj_lib_upvalue(L, n) \ | ||
52 | (&gcref((L->base-2)->gcr)->fn.c.upvalue[(n)-1]) | ||
53 | #else | ||
50 | #define lj_lib_upvalue(L, n) \ | 54 | #define lj_lib_upvalue(L, n) \ |
51 | (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1]) | 55 | (&gcref((L->base-1)->fr.func)->fn.c.upvalue[(n)-1]) |
56 | #endif | ||
52 | 57 | ||
53 | #if LJ_TARGET_WINDOWS | 58 | #if LJ_TARGET_WINDOWS |
54 | #define lj_lib_checkfpu(L) \ | 59 | #define lj_lib_checkfpu(L) \ |
diff --git a/src/lj_meta.c b/src/lj_meta.c index 520c3763..d26ed220 100644 --- a/src/lj_meta.c +++ b/src/lj_meta.c | |||
@@ -80,12 +80,16 @@ int lj_meta_tailcall(lua_State *L, cTValue *tv) | |||
80 | TValue *base = L->base; | 80 | TValue *base = L->base; |
81 | TValue *top = L->top; | 81 | TValue *top = L->top; |
82 | const BCIns *pc = frame_pc(base-1); /* Preserve old PC from frame. */ | 82 | const BCIns *pc = frame_pc(base-1); /* Preserve old PC from frame. */ |
83 | copyTV(L, base-1, tv); /* Replace frame with new object. */ | 83 | copyTV(L, base-1-LJ_FR2, tv); /* Replace frame with new object. */ |
84 | top->u32.lo = LJ_CONT_TAILCALL; | 84 | if (LJ_FR2) |
85 | setframe_pc(top, pc); | 85 | (top++)->u64 = LJ_CONT_TAILCALL; |
86 | setframe_gc(top+1, obj2gco(L), LJ_TTHREAD); /* Dummy frame object. */ | 86 | else |
87 | setframe_ftsz(top+1, ((char *)(top+2) - (char *)base) + FRAME_CONT); | 87 | top->u32.lo = LJ_CONT_TAILCALL; |
88 | L->base = L->top = top+2; | 88 | setframe_pc(top++, pc); |
89 | if (LJ_FR2) top++; | ||
90 | setframe_gc(top, obj2gco(L), LJ_TTHREAD); /* Dummy frame object. */ | ||
91 | setframe_ftsz(top, ((char *)(top+1) - (char *)base) + FRAME_CONT); | ||
92 | L->base = L->top = top+1; | ||
89 | /* | 93 | /* |
90 | ** before: [old_mo|PC] [... ...] | 94 | ** before: [old_mo|PC] [... ...] |
91 | ** ^base ^top | 95 | ** ^base ^top |
@@ -116,11 +120,13 @@ static TValue *mmcall(lua_State *L, ASMFunction cont, cTValue *mo, | |||
116 | */ | 120 | */ |
117 | TValue *top = L->top; | 121 | TValue *top = L->top; |
118 | if (curr_funcisL(L)) top = curr_topL(L); | 122 | if (curr_funcisL(L)) top = curr_topL(L); |
119 | setcont(top, cont); /* Assembler VM stores PC in upper word. */ | 123 | setcont(top++, cont); /* Assembler VM stores PC in upper word or FR2. */ |
120 | copyTV(L, top+1, mo); /* Store metamethod and two arguments. */ | 124 | if (LJ_FR2) setnilV(top++); |
121 | copyTV(L, top+2, a); | 125 | copyTV(L, top++, mo); /* Store metamethod and two arguments. */ |
122 | copyTV(L, top+3, b); | 126 | if (LJ_FR2) setnilV(top++); |
123 | return top+2; /* Return new base. */ | 127 | copyTV(L, top, a); |
128 | copyTV(L, top+1, b); | ||
129 | return top; /* Return new base. */ | ||
124 | } | 130 | } |
125 | 131 | ||
126 | /* -- C helpers for some instructions, called from assembler VM ----------- */ | 132 | /* -- C helpers for some instructions, called from assembler VM ----------- */ |
@@ -256,10 +262,11 @@ TValue *lj_meta_cat(lua_State *L, TValue *top, int left) | |||
256 | ** after mm: [...][CAT stack ...] <--push-- [result] | 262 | ** after mm: [...][CAT stack ...] <--push-- [result] |
257 | ** next step: [...][CAT stack .............] | 263 | ** next step: [...][CAT stack .............] |
258 | */ | 264 | */ |
259 | copyTV(L, top+2, top); /* Careful with the order of stack copies! */ | 265 | copyTV(L, top+2*LJ_FR2+2, top); /* Carefully ordered stack copies! */ |
260 | copyTV(L, top+1, top-1); | 266 | copyTV(L, top+2*LJ_FR2+1, top-1); |
261 | copyTV(L, top, mo); | 267 | copyTV(L, top+LJ_FR2, mo); |
262 | setcont(top-1, lj_cont_cat); | 268 | setcont(top-1, lj_cont_cat); |
269 | if (LJ_FR2) { setnilV(top); setnilV(top+2); top += 2; } | ||
263 | return top+1; /* Trigger metamethod call. */ | 270 | return top+1; /* Trigger metamethod call. */ |
264 | } else { | 271 | } else { |
265 | /* Pick as many strings as possible from the top and concatenate them: | 272 | /* Pick as many strings as possible from the top and concatenate them: |
@@ -327,12 +334,14 @@ TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne) | |||
327 | return (TValue *)(intptr_t)ne; | 334 | return (TValue *)(intptr_t)ne; |
328 | } | 335 | } |
329 | top = curr_top(L); | 336 | top = curr_top(L); |
330 | setcont(top, ne ? lj_cont_condf : lj_cont_condt); | 337 | setcont(top++, ne ? lj_cont_condf : lj_cont_condt); |
331 | copyTV(L, top+1, mo); | 338 | if (LJ_FR2) setnilV(top++); |
339 | copyTV(L, top++, mo); | ||
340 | if (LJ_FR2) setnilV(top++); | ||
332 | it = ~(uint32_t)o1->gch.gct; | 341 | it = ~(uint32_t)o1->gch.gct; |
333 | setgcV(L, top+2, o1, it); | 342 | setgcV(L, top, o1, it); |
334 | setgcV(L, top+3, o2, it); | 343 | setgcV(L, top+1, o2, it); |
335 | return top+2; /* Trigger metamethod call. */ | 344 | return top; /* Trigger metamethod call. */ |
336 | } | 345 | } |
337 | return (TValue *)(intptr_t)ne; | 346 | return (TValue *)(intptr_t)ne; |
338 | } | 347 | } |
@@ -431,7 +440,8 @@ void lj_meta_call(lua_State *L, TValue *func, TValue *top) | |||
431 | TValue *p; | 440 | TValue *p; |
432 | if (!tvisfunc(mo)) | 441 | if (!tvisfunc(mo)) |
433 | lj_err_optype_call(L, func); | 442 | lj_err_optype_call(L, func); |
434 | for (p = top; p > func; p--) copyTV(L, p, p-1); | 443 | for (p = top; p > func+2*LJ_FR2; p--) copyTV(L, p, p-1); |
444 | if (LJ_FR2) copyTV(L, func+2, func); | ||
435 | copyTV(L, func, mo); | 445 | copyTV(L, func, mo); |
436 | } | 446 | } |
437 | 447 | ||
diff --git a/src/lj_obj.h b/src/lj_obj.h index e5724859..438c83d4 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
@@ -131,7 +131,7 @@ typedef struct SBuf { | |||
131 | /* Frame link. */ | 131 | /* Frame link. */ |
132 | typedef union { | 132 | typedef union { |
133 | int32_t ftsz; /* Frame type and size of previous frame. */ | 133 | int32_t ftsz; /* Frame type and size of previous frame. */ |
134 | MRef pcr; /* Overlaps PC for Lua frames. */ | 134 | MRef pcr; /* Or PC for Lua frames. */ |
135 | } FrameLink; | 135 | } FrameLink; |
136 | 136 | ||
137 | /* Tagged value. */ | 137 | /* Tagged value. */ |
@@ -147,12 +147,16 @@ typedef LJ_ALIGN(8) union TValue { | |||
147 | , uint32_t it; /* Internal object tag. Must overlap MSW of number. */ | 147 | , uint32_t it; /* Internal object tag. Must overlap MSW of number. */ |
148 | ) | 148 | ) |
149 | }; | 149 | }; |
150 | #if LJ_FR2 | ||
151 | int64_t ftsz; /* Frame type and size of previous frame, or PC. */ | ||
152 | #else | ||
150 | struct { | 153 | struct { |
151 | LJ_ENDIAN_LOHI( | 154 | LJ_ENDIAN_LOHI( |
152 | GCRef func; /* Function for next frame (or dummy L). */ | 155 | GCRef func; /* Function for next frame (or dummy L). */ |
153 | , FrameLink tp; /* Link to previous frame. */ | 156 | , FrameLink tp; /* Link to previous frame. */ |
154 | ) | 157 | ) |
155 | } fr; | 158 | } fr; |
159 | #endif | ||
156 | struct { | 160 | struct { |
157 | LJ_ENDIAN_LOHI( | 161 | LJ_ENDIAN_LOHI( |
158 | uint32_t lo; /* Lower 32 bits of number. */ | 162 | uint32_t lo; /* Lower 32 bits of number. */ |
@@ -584,7 +588,11 @@ struct lua_State { | |||
584 | #define registry(L) (&G(L)->registrytv) | 588 | #define registry(L) (&G(L)->registrytv) |
585 | 589 | ||
586 | /* Macros to access the currently executing (Lua) function. */ | 590 | /* Macros to access the currently executing (Lua) function. */ |
591 | #if LJ_FR2 | ||
592 | #define curr_func(L) (&gcref((L->base-2)->gcr)->fn) | ||
593 | #else | ||
587 | #define curr_func(L) (&gcref((L->base-1)->fr.func)->fn) | 594 | #define curr_func(L) (&gcref((L->base-1)->fr.func)->fn) |
595 | #endif | ||
588 | #define curr_funcisL(L) (isluafunc(curr_func(L))) | 596 | #define curr_funcisL(L) (isluafunc(curr_func(L))) |
589 | #define curr_proto(L) (funcproto(curr_func(L))) | 597 | #define curr_proto(L) (funcproto(curr_func(L))) |
590 | #define curr_topL(L) (L->base + curr_proto(L)->framesize) | 598 | #define curr_topL(L) (L->base + curr_proto(L)->framesize) |
@@ -732,10 +740,16 @@ static LJ_AINLINE void setlightudV(TValue *o, void *p) | |||
732 | #if LJ_64 | 740 | #if LJ_64 |
733 | #define checklightudptr(L, p) \ | 741 | #define checklightudptr(L, p) \ |
734 | (((uint64_t)(p) >> 47) ? (lj_err_msg(L, LJ_ERR_BADLU), NULL) : (p)) | 742 | (((uint64_t)(p) >> 47) ? (lj_err_msg(L, LJ_ERR_BADLU), NULL) : (p)) |
743 | #else | ||
744 | #define checklightudptr(L, p) (p) | ||
745 | #endif | ||
746 | |||
747 | #if LJ_FR2 | ||
748 | #define setcont(o, f) ((o)->u64 = (uint64_t)(uintptr_t)(void *)(f)) | ||
749 | #elif LJ_64 | ||
735 | #define setcont(o, f) \ | 750 | #define setcont(o, f) \ |
736 | ((o)->u64 = (uint64_t)(void *)(f) - (uint64_t)lj_vm_asm_begin) | 751 | ((o)->u64 = (uint64_t)(void *)(f) - (uint64_t)lj_vm_asm_begin) |
737 | #else | 752 | #else |
738 | #define checklightudptr(L, p) (p) | ||
739 | #define setcont(o, f) setlightudV((o), (void *)(f)) | 753 | #define setcont(o, f) setlightudV((o), (void *)(f)) |
740 | #endif | 754 | #endif |
741 | 755 | ||
diff --git a/src/lj_parse.c b/src/lj_parse.c index 198ddfc9..91282768 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -662,14 +662,14 @@ static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key) | |||
662 | BCReg idx, func, obj = expr_toanyreg(fs, e); | 662 | BCReg idx, func, obj = expr_toanyreg(fs, e); |
663 | expr_free(fs, e); | 663 | expr_free(fs, e); |
664 | func = fs->freereg; | 664 | func = fs->freereg; |
665 | bcemit_AD(fs, BC_MOV, func+1, obj); /* Copy object to first argument. */ | 665 | bcemit_AD(fs, BC_MOV, func+1+LJ_FR2, obj); /* Copy object to 1st argument. */ |
666 | lua_assert(expr_isstrk(key)); | 666 | lua_assert(expr_isstrk(key)); |
667 | idx = const_str(fs, key); | 667 | idx = const_str(fs, key); |
668 | if (idx <= BCMAX_C) { | 668 | if (idx <= BCMAX_C) { |
669 | bcreg_reserve(fs, 2); | 669 | bcreg_reserve(fs, 2+LJ_FR2); |
670 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); | 670 | bcemit_ABC(fs, BC_TGETS, func, obj, idx); |
671 | } else { | 671 | } else { |
672 | bcreg_reserve(fs, 3); | 672 | bcreg_reserve(fs, 3+LJ_FR2); |
673 | bcemit_AD(fs, BC_KSTR, func+2, idx); | 673 | bcemit_AD(fs, BC_KSTR, func+2, idx); |
674 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2); | 674 | bcemit_ABC(fs, BC_TGETV, func, obj, func+2); |
675 | fs->freereg--; | 675 | fs->freereg--; |
@@ -1913,11 +1913,11 @@ static void parse_args(LexState *ls, ExpDesc *e) | |||
1913 | lua_assert(e->k == VNONRELOC); | 1913 | lua_assert(e->k == VNONRELOC); |
1914 | base = e->u.s.info; /* Base register for call. */ | 1914 | base = e->u.s.info; /* Base register for call. */ |
1915 | if (args.k == VCALL) { | 1915 | if (args.k == VCALL) { |
1916 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1); | 1916 | ins = BCINS_ABC(BC_CALLM, base, 2, args.u.s.aux - base - 1 - LJ_FR2); |
1917 | } else { | 1917 | } else { |
1918 | if (args.k != VVOID) | 1918 | if (args.k != VVOID) |
1919 | expr_tonextreg(fs, &args); | 1919 | expr_tonextreg(fs, &args); |
1920 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base); | 1920 | ins = BCINS_ABC(BC_CALL, base, 2, fs->freereg - base - LJ_FR2); |
1921 | } | 1921 | } |
1922 | expr_init(e, VCALL, bcemit_INS(fs, ins)); | 1922 | expr_init(e, VCALL, bcemit_INS(fs, ins)); |
1923 | e->u.s.aux = base; | 1923 | e->u.s.aux = base; |
@@ -1957,6 +1957,7 @@ static void expr_primary(LexState *ls, ExpDesc *v) | |||
1957 | parse_args(ls, v); | 1957 | parse_args(ls, v); |
1958 | } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') { | 1958 | } else if (ls->tok == '(' || ls->tok == TK_string || ls->tok == '{') { |
1959 | expr_tonextreg(fs, v); | 1959 | expr_tonextreg(fs, v); |
1960 | if (LJ_FR2) bcreg_reserve(fs, 1); | ||
1960 | parse_args(ls, v); | 1961 | parse_args(ls, v); |
1961 | } else { | 1962 | } else { |
1962 | break; | 1963 | break; |
@@ -2537,7 +2538,8 @@ static void parse_for_iter(LexState *ls, GCstr *indexname) | |||
2537 | lex_check(ls, TK_in); | 2538 | lex_check(ls, TK_in); |
2538 | line = ls->linenumber; | 2539 | line = ls->linenumber; |
2539 | assign_adjust(ls, 3, expr_list(ls, &e), &e); | 2540 | assign_adjust(ls, 3, expr_list(ls, &e), &e); |
2540 | bcreg_bump(fs, 3); /* The iterator needs another 3 slots (func + 2 args). */ | 2541 | /* The iterator needs another 3 [4] slots (func [pc] | state ctl). */ |
2542 | bcreg_bump(fs, 3+LJ_FR2); | ||
2541 | isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); | 2543 | isnext = (nvars <= 5 && predict_next(ls, fs, exprpc)); |
2542 | var_add(ls, 3); /* Hidden control variables. */ | 2544 | var_add(ls, 3); /* Hidden control variables. */ |
2543 | lex_check(ls, TK_do); | 2545 | lex_check(ls, TK_do); |
diff --git a/src/lj_record.c b/src/lj_record.c index 01c09c58..539fd197 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -502,6 +502,7 @@ static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl) | |||
502 | static LoopEvent rec_iterl(jit_State *J, const BCIns iterins) | 502 | static LoopEvent rec_iterl(jit_State *J, const BCIns iterins) |
503 | { | 503 | { |
504 | BCReg ra = bc_a(iterins); | 504 | BCReg ra = bc_a(iterins); |
505 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
505 | if (!tref_isnil(getslot(J, ra))) { /* Looping back? */ | 506 | if (!tref_isnil(getslot(J, ra))) { /* Looping back? */ |
506 | J->base[ra-1] = J->base[ra]; /* Copy result of ITERC to control var. */ | 507 | J->base[ra-1] = J->base[ra]; /* Copy result of ITERC to control var. */ |
507 | J->maxslot = ra-1+bc_b(J->pc[-1]); | 508 | J->maxslot = ra-1+bc_b(J->pc[-1]); |
@@ -672,6 +673,7 @@ static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs) | |||
672 | TValue *functv = &J->L->base[func]; | 673 | TValue *functv = &J->L->base[func]; |
673 | TRef *fbase = &J->base[func]; | 674 | TRef *fbase = &J->base[func]; |
674 | ptrdiff_t i; | 675 | ptrdiff_t i; |
676 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
675 | for (i = 0; i <= nargs; i++) | 677 | for (i = 0; i <= nargs; i++) |
676 | (void)getslot(J, func+i); /* Ensure func and all args have a reference. */ | 678 | (void)getslot(J, func+i); /* Ensure func and all args have a reference. */ |
677 | if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */ | 679 | if (!tref_isfunc(fbase[0])) { /* Resolve __call metamethod. */ |
@@ -788,7 +790,8 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
788 | BCIns callins = *(frame_pc(frame)-1); | 790 | BCIns callins = *(frame_pc(frame)-1); |
789 | ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults; | 791 | ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults; |
790 | BCReg cbase = bc_a(callins); | 792 | BCReg cbase = bc_a(callins); |
791 | GCproto *pt = funcproto(frame_func(frame - (cbase+1))); | 793 | GCproto *pt = funcproto(frame_func(frame - (cbase+1-LJ_FR2))); |
794 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame teardown. */ | ||
792 | if ((pt->flags & PROTO_NOJIT)) | 795 | if ((pt->flags & PROTO_NOJIT)) |
793 | lj_trace_err(J, LJ_TRERR_CJITOFF); | 796 | lj_trace_err(J, LJ_TRERR_CJITOFF); |
794 | if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) { | 797 | if (J->framedepth == 0 && J->pt && frame == J->L->base - 1) { |
@@ -973,6 +976,7 @@ static TRef rec_mm_arith(jit_State *J, RecordIndex *ix, MMS mm) | |||
973 | lj_trace_err(J, LJ_TRERR_NOMM); | 976 | lj_trace_err(J, LJ_TRERR_NOMM); |
974 | } | 977 | } |
975 | ok: | 978 | ok: |
979 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
976 | base[0] = ix->mobj; | 980 | base[0] = ix->mobj; |
977 | copyTV(J->L, basev+0, &ix->mobjv); | 981 | copyTV(J->L, basev+0, &ix->mobjv); |
978 | lj_record_call(J, func, 2); | 982 | lj_record_call(J, func, 2); |
@@ -989,6 +993,7 @@ static TRef rec_mm_len(jit_State *J, TRef tr, TValue *tv) | |||
989 | BCReg func = rec_mm_prep(J, lj_cont_ra); | 993 | BCReg func = rec_mm_prep(J, lj_cont_ra); |
990 | TRef *base = J->base + func; | 994 | TRef *base = J->base + func; |
991 | TValue *basev = J->L->base + func; | 995 | TValue *basev = J->L->base + func; |
996 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
992 | base[0] = ix.mobj; copyTV(J->L, basev+0, &ix.mobjv); | 997 | base[0] = ix.mobj; copyTV(J->L, basev+0, &ix.mobjv); |
993 | base[1] = tr; copyTV(J->L, basev+1, tv); | 998 | base[1] = tr; copyTV(J->L, basev+1, tv); |
994 | #if LJ_52 | 999 | #if LJ_52 |
@@ -1011,6 +1016,7 @@ static void rec_mm_callcomp(jit_State *J, RecordIndex *ix, int op) | |||
1011 | BCReg func = rec_mm_prep(J, (op&1) ? lj_cont_condf : lj_cont_condt); | 1016 | BCReg func = rec_mm_prep(J, (op&1) ? lj_cont_condf : lj_cont_condt); |
1012 | TRef *base = J->base + func; | 1017 | TRef *base = J->base + func; |
1013 | TValue *tv = J->L->base + func; | 1018 | TValue *tv = J->L->base + func; |
1019 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
1014 | base[0] = ix->mobj; base[1] = ix->val; base[2] = ix->key; | 1020 | base[0] = ix->mobj; base[1] = ix->val; base[2] = ix->key; |
1015 | copyTV(J->L, tv+0, &ix->mobjv); | 1021 | copyTV(J->L, tv+0, &ix->mobjv); |
1016 | copyTV(J->L, tv+1, &ix->valv); | 1022 | copyTV(J->L, tv+1, &ix->valv); |
@@ -1261,6 +1267,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix) | |||
1261 | BCReg func = rec_mm_prep(J, ix->val ? lj_cont_nop : lj_cont_ra); | 1267 | BCReg func = rec_mm_prep(J, ix->val ? lj_cont_nop : lj_cont_ra); |
1262 | TRef *base = J->base + func; | 1268 | TRef *base = J->base + func; |
1263 | TValue *tv = J->L->base + func; | 1269 | TValue *tv = J->L->base + func; |
1270 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
1264 | base[0] = ix->mobj; base[1] = ix->tab; base[2] = ix->key; | 1271 | base[0] = ix->mobj; base[1] = ix->tab; base[2] = ix->key; |
1265 | setfuncV(J->L, tv+0, funcV(&ix->mobjv)); | 1272 | setfuncV(J->L, tv+0, funcV(&ix->mobjv)); |
1266 | copyTV(J->L, tv+1, &ix->tabv); | 1273 | copyTV(J->L, tv+1, &ix->tabv); |
@@ -2135,28 +2142,28 @@ void lj_record_ins(jit_State *J) | |||
2135 | /* -- Calls and vararg handling ----------------------------------------- */ | 2142 | /* -- Calls and vararg handling ----------------------------------------- */ |
2136 | 2143 | ||
2137 | case BC_ITERC: | 2144 | case BC_ITERC: |
2138 | J->base[ra] = getslot(J, ra-3); | 2145 | J->base[ra] = getslot(J, ra-3-LJ_FR2); |
2139 | J->base[ra+1] = getslot(J, ra-2); | 2146 | J->base[ra+1] = getslot(J, ra-2-LJ_FR2); |
2140 | J->base[ra+2] = getslot(J, ra-1); | 2147 | J->base[ra+2] = getslot(J, ra-1-LJ_FR2); |
2141 | { /* Do the actual copy now because lj_record_call needs the values. */ | 2148 | { /* Do the actual copy now because lj_record_call needs the values. */ |
2142 | TValue *b = &J->L->base[ra]; | 2149 | TValue *b = &J->L->base[ra]; |
2143 | copyTV(J->L, b, b-3); | 2150 | copyTV(J->L, b, b-3-LJ_FR2); |
2144 | copyTV(J->L, b+1, b-2); | 2151 | copyTV(J->L, b+1, b-2-LJ_FR2); |
2145 | copyTV(J->L, b+2, b-1); | 2152 | copyTV(J->L, b+2, b-1-LJ_FR2); |
2146 | } | 2153 | } |
2147 | lj_record_call(J, ra, (ptrdiff_t)rc-1); | 2154 | lj_record_call(J, ra, (ptrdiff_t)rc-1); |
2148 | break; | 2155 | break; |
2149 | 2156 | ||
2150 | /* L->top is set to L->base+ra+rc+NARGS-1+1. See lj_dispatch_ins(). */ | 2157 | /* L->top is set to L->base+ra+rc+NARGS-1+1. See lj_dispatch_ins(). */ |
2151 | case BC_CALLM: | 2158 | case BC_CALLM: |
2152 | rc = (BCReg)(J->L->top - J->L->base) - ra; | 2159 | rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2; |
2153 | /* fallthrough */ | 2160 | /* fallthrough */ |
2154 | case BC_CALL: | 2161 | case BC_CALL: |
2155 | lj_record_call(J, ra, (ptrdiff_t)rc-1); | 2162 | lj_record_call(J, ra, (ptrdiff_t)rc-1); |
2156 | break; | 2163 | break; |
2157 | 2164 | ||
2158 | case BC_CALLMT: | 2165 | case BC_CALLMT: |
2159 | rc = (BCReg)(J->L->top - J->L->base) - ra; | 2166 | rc = (BCReg)(J->L->top - J->L->base) - ra - LJ_FR2; |
2160 | /* fallthrough */ | 2167 | /* fallthrough */ |
2161 | case BC_CALLT: | 2168 | case BC_CALLT: |
2162 | lj_record_tailcall(J, ra, (ptrdiff_t)rc-1); | 2169 | lj_record_tailcall(J, ra, (ptrdiff_t)rc-1); |
diff --git a/src/lj_snap.c b/src/lj_snap.c index 2917424f..4bac2d28 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
@@ -100,6 +100,7 @@ static BCReg snapshot_framelinks(jit_State *J, SnapEntry *map) | |||
100 | GCfunc *fn = frame_func(frame); | 100 | GCfunc *fn = frame_func(frame); |
101 | cTValue *ftop = isluafunc(fn) ? (frame+funcproto(fn)->framesize) : J->L->top; | 101 | cTValue *ftop = isluafunc(fn) ? (frame+funcproto(fn)->framesize) : J->L->top; |
102 | MSize f = 0; | 102 | MSize f = 0; |
103 | lua_assert(!LJ_FR2); /* TODO_FR2: store 64 bit PCs. */ | ||
103 | map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ | 104 | map[f++] = SNAP_MKPC(J->pc); /* The current PC is always the first entry. */ |
104 | while (frame > lim) { /* Backwards traversal of all frames above base. */ | 105 | while (frame > lim) { /* Backwards traversal of all frames above base. */ |
105 | if (frame_islua(frame)) { | 106 | if (frame_islua(frame)) { |
@@ -241,7 +242,8 @@ static BCReg snap_usedef(jit_State *J, uint8_t *udf, | |||
241 | case BCMbase: | 242 | case BCMbase: |
242 | if (op >= BC_CALLM && op <= BC_VARG) { | 243 | if (op >= BC_CALLM && op <= BC_VARG) { |
243 | BCReg top = (op == BC_CALLM || op == BC_CALLMT || bc_c(ins) == 0) ? | 244 | BCReg top = (op == BC_CALLM || op == BC_CALLMT || bc_c(ins) == 0) ? |
244 | maxslot : (bc_a(ins) + bc_c(ins)); | 245 | maxslot : (bc_a(ins) + bc_c(ins)+LJ_FR2); |
246 | if (LJ_FR2) DEF_SLOT(bc_a(ins)+1); | ||
245 | s = bc_a(ins) - ((op == BC_ITERC || op == BC_ITERN) ? 3 : 0); | 247 | s = bc_a(ins) - ((op == BC_ITERC || op == BC_ITERN) ? 3 : 0); |
246 | for (; s < top; s++) USE_SLOT(s); | 248 | for (; s < top; s++) USE_SLOT(s); |
247 | for (; s < maxslot; s++) DEF_SLOT(s); | 249 | for (; s < maxslot; s++) DEF_SLOT(s); |
@@ -836,6 +838,7 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr) | |||
836 | snap_restoreval(J, T, ex, snapno, rfilt, ref+1, &tmp); | 838 | snap_restoreval(J, T, ex, snapno, rfilt, ref+1, &tmp); |
837 | o->u32.hi = tmp.u32.lo; | 839 | o->u32.hi = tmp.u32.lo; |
838 | } else if ((sn & (SNAP_CONT|SNAP_FRAME))) { | 840 | } else if ((sn & (SNAP_CONT|SNAP_FRAME))) { |
841 | lua_assert(!LJ_FR2); /* TODO_FR2: store 64 bit PCs. */ | ||
839 | /* Overwrite tag with frame link. */ | 842 | /* Overwrite tag with frame link. */ |
840 | setframe_ftsz(o, snap_slot(sn) != 0 ? (int32_t)*flinks-- : ftsz0); | 843 | setframe_ftsz(o, snap_slot(sn) != 0 ? (int32_t)*flinks-- : ftsz0); |
841 | L->base = o+1; | 844 | L->base = o+1; |
diff --git a/src/lj_state.c b/src/lj_state.c index 344f8fe1..f7cdb8f3 100644 --- a/src/lj_state.c +++ b/src/lj_state.c | |||
@@ -49,6 +49,7 @@ | |||
49 | ** one extra slot if mobj is not a function. Only lj_meta_tset needs 5 | 49 | ** one extra slot if mobj is not a function. Only lj_meta_tset needs 5 |
50 | ** slots above top, but then mobj is always a function. So we can get by | 50 | ** slots above top, but then mobj is always a function. So we can get by |
51 | ** with 5 extra slots. | 51 | ** with 5 extra slots. |
52 | ** LJ_FR2: We need 2 more slots for the frame PC and the continuation PC. | ||
52 | */ | 53 | */ |
53 | 54 | ||
54 | /* Resize stack slots and adjust pointers in state. */ | 55 | /* Resize stack slots and adjust pointers in state. */ |
@@ -128,8 +129,9 @@ static void stack_init(lua_State *L1, lua_State *L) | |||
128 | L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA; | 129 | L1->stacksize = LJ_STACK_START + LJ_STACK_EXTRA; |
129 | stend = st + L1->stacksize; | 130 | stend = st + L1->stacksize; |
130 | setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1); | 131 | setmref(L1->maxstack, stend - LJ_STACK_EXTRA - 1); |
131 | L1->base = L1->top = st+1; | 132 | setthreadV(L1, st++, L1); /* Needed for curr_funcisL() on empty stack. */ |
132 | setthreadV(L1, st, L1); /* Needed for curr_funcisL() on empty stack. */ | 133 | if (LJ_FR2) setnilV(st++); |
134 | L1->base = L1->top = st; | ||
133 | while (st < stend) /* Clear new slots. */ | 135 | while (st < stend) /* Clear new slots. */ |
134 | setnilV(st++); | 136 | setnilV(st++); |
135 | } | 137 | } |
@@ -253,7 +255,7 @@ LUA_API void lua_close(lua_State *L) | |||
253 | for (i = 0;;) { | 255 | for (i = 0;;) { |
254 | hook_enter(g); | 256 | hook_enter(g); |
255 | L->status = 0; | 257 | L->status = 0; |
256 | L->base = L->top = tvref(L->stack) + 1; | 258 | L->base = L->top = tvref(L->stack) + 1 + LJ_FR2; |
257 | L->cframe = NULL; | 259 | L->cframe = NULL; |
258 | if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == 0) { | 260 | if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == 0) { |
259 | if (++i >= 10) break; | 261 | if (++i >= 10) break; |
diff --git a/src/lj_trace.c b/src/lj_trace.c index f386b95e..7d2ce8f2 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
@@ -830,7 +830,7 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | |||
830 | ERRNO_RESTORE | 830 | ERRNO_RESTORE |
831 | switch (bc_op(*pc)) { | 831 | switch (bc_op(*pc)) { |
832 | case BC_CALLM: case BC_CALLMT: | 832 | case BC_CALLM: case BC_CALLMT: |
833 | return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc)); | 833 | return (int)((BCReg)(L->top - L->base) - bc_a(*pc) - bc_c(*pc) + LJ_FR2); |
834 | case BC_RETM: | 834 | case BC_RETM: |
835 | return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc)); | 835 | return (int)((BCReg)(L->top - L->base) + 1 - bc_a(*pc) - bc_d(*pc)); |
836 | case BC_TSETM: | 836 | case BC_TSETM: |
diff --git a/src/lj_vmevent.c b/src/lj_vmevent.c index e14ad5b6..8e10a627 100644 --- a/src/lj_vmevent.c +++ b/src/lj_vmevent.c | |||
@@ -27,6 +27,7 @@ ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev) | |||
27 | if (tv && tvisfunc(tv)) { | 27 | if (tv && tvisfunc(tv)) { |
28 | lj_state_checkstack(L, LUA_MINSTACK); | 28 | lj_state_checkstack(L, LUA_MINSTACK); |
29 | setfuncV(L, L->top++, funcV(tv)); | 29 | setfuncV(L, L->top++, funcV(tv)); |
30 | if (LJ_FR2) setnilV(L->top++); | ||
30 | return savestack(L, L->top); | 31 | return savestack(L, L->top); |
31 | } | 32 | } |
32 | } | 33 | } |