diff options
Diffstat (limited to 'src/lj_ffrecord.c')
-rw-r--r-- | src/lj_ffrecord.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index ae567622..64a9a65d 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c | |||
@@ -102,35 +102,41 @@ static void recff_stitch(jit_State *J) | |||
102 | ASMFunction cont = lj_cont_stitch; | 102 | ASMFunction cont = lj_cont_stitch; |
103 | lua_State *L = J->L; | 103 | lua_State *L = J->L; |
104 | TValue *base = L->base; | 104 | TValue *base = L->base; |
105 | BCReg nslot = J->maxslot + 1 + LJ_FR2; | ||
106 | TValue *nframe = base + 1 + LJ_FR2; | ||
105 | const BCIns *pc = frame_pc(base-1); | 107 | const BCIns *pc = frame_pc(base-1); |
106 | TValue *pframe = frame_prevl(base-1); | 108 | TValue *pframe = frame_prevl(base-1); |
107 | 109 | ||
108 | lua_assert(!LJ_FR2); /* TODO_FR2: handle frame shift. */ | ||
109 | /* Move func + args up in Lua stack and insert continuation. */ | 110 | /* Move func + args up in Lua stack and insert continuation. */ |
110 | memmove(&base[1], &base[-1], sizeof(TValue)*(J->maxslot+1)); | 111 | memmove(&base[1], &base[-1-LJ_FR2], sizeof(TValue)*nslot); |
111 | setframe_ftsz(base+1, ((char *)(base+1) - (char *)pframe) + FRAME_CONT); | 112 | setframe_ftsz(nframe, ((char *)nframe - (char *)pframe) + FRAME_CONT); |
112 | setcont(base, cont); | 113 | setcont(base-LJ_FR2, cont); |
113 | setframe_pc(base, pc); | 114 | setframe_pc(base, pc); |
114 | setnilV(base-1); /* Incorrect, but rec_check_slots() won't run anymore. */ | 115 | setnilV(base-1-LJ_FR2); /* Incorrect, but rec_check_slots() won't run anymore. */ |
115 | L->base += 2; | 116 | L->base += 2 + LJ_FR2; |
116 | L->top += 2; | 117 | L->top += 2 + LJ_FR2; |
117 | 118 | ||
118 | /* Ditto for the IR. */ | 119 | /* Ditto for the IR. */ |
119 | memmove(&J->base[1], &J->base[-1], sizeof(TRef)*(J->maxslot+1)); | 120 | memmove(&J->base[1], &J->base[-1-LJ_FR2], sizeof(TRef)*nslot); |
121 | #if LJ_FR2 | ||
122 | J->base[2] = TREF_FRAME; | ||
123 | J->base[-1] = lj_ir_k64(J, IR_KNUM, u64ptr(contptr(cont))); | ||
124 | J->base[0] = lj_ir_k64(J, IR_KNUM, u64ptr(pc)) | TREF_CONT; | ||
125 | #else | ||
120 | J->base[0] = lj_ir_kptr(J, contptr(cont)) | TREF_CONT; | 126 | J->base[0] = lj_ir_kptr(J, contptr(cont)) | TREF_CONT; |
121 | J->base[-1] = lj_ir_ktrace(J); | 127 | #endif |
122 | J->ktrace = tref_ref(J->base[-1]); | 128 | J->ktrace = tref_ref((J->base[-1-LJ_FR2] = lj_ir_ktrace(J))); |
123 | J->base += 2; | 129 | J->base += 2 + LJ_FR2; |
124 | J->baseslot += 2; | 130 | J->baseslot += 2 + LJ_FR2; |
125 | J->framedepth++; | 131 | J->framedepth++; |
126 | 132 | ||
127 | lj_record_stop(J, LJ_TRLINK_STITCH, 0); | 133 | lj_record_stop(J, LJ_TRLINK_STITCH, 0); |
128 | 134 | ||
129 | /* Undo Lua stack changes. */ | 135 | /* Undo Lua stack changes. */ |
130 | memmove(&base[-1], &base[1], sizeof(TValue)*(J->maxslot+1)); | 136 | memmove(&base[-1-LJ_FR2], &base[1], sizeof(TValue)*nslot); |
131 | setframe_pc(base-1, pc); | 137 | setframe_pc(base-1, pc); |
132 | L->base -= 2; | 138 | L->base -= 2 + LJ_FR2; |
133 | L->top -= 2; | 139 | L->top -= 2 + LJ_FR2; |
134 | } | 140 | } |
135 | 141 | ||
136 | /* Fallback handler for fast functions that are not recorded (yet). */ | 142 | /* Fallback handler for fast functions that are not recorded (yet). */ |
@@ -373,10 +379,10 @@ static int recff_metacall(jit_State *J, RecordFFData *rd, MMS mm) | |||
373 | int errcode; | 379 | int errcode; |
374 | TValue argv0; | 380 | TValue argv0; |
375 | /* Temporarily insert metamethod below object. */ | 381 | /* Temporarily insert metamethod below object. */ |
376 | J->base[1] = J->base[0]; | 382 | J->base[1+LJ_FR2] = J->base[0]; |
377 | J->base[0] = ix.mobj; | 383 | J->base[0] = ix.mobj; |
378 | copyTV(J->L, &argv0, &rd->argv[0]); | 384 | copyTV(J->L, &argv0, &rd->argv[0]); |
379 | copyTV(J->L, &rd->argv[1], &rd->argv[0]); | 385 | copyTV(J->L, &rd->argv[1+LJ_FR2], &rd->argv[0]); |
380 | copyTV(J->L, &rd->argv[0], &ix.mobjv); | 386 | copyTV(J->L, &rd->argv[0], &ix.mobjv); |
381 | /* Need to protect lj_record_tailcall because it may throw. */ | 387 | /* Need to protect lj_record_tailcall because it may throw. */ |
382 | errcode = lj_vm_cpcall(J->L, NULL, J, recff_metacall_cp); | 388 | errcode = lj_vm_cpcall(J->L, NULL, J, recff_metacall_cp); |
@@ -443,6 +449,10 @@ static void LJ_FASTCALL recff_xpairs(jit_State *J, RecordFFData *rd) | |||
443 | static void LJ_FASTCALL recff_pcall(jit_State *J, RecordFFData *rd) | 449 | static void LJ_FASTCALL recff_pcall(jit_State *J, RecordFFData *rd) |
444 | { | 450 | { |
445 | if (J->maxslot >= 1) { | 451 | if (J->maxslot >= 1) { |
452 | #if LJ_FR2 | ||
453 | /* Shift function arguments up. */ | ||
454 | memmove(J->base + 1, J->base, sizeof(TRef) * J->maxslot); | ||
455 | #endif | ||
446 | lj_record_call(J, 0, J->maxslot - 1); | 456 | lj_record_call(J, 0, J->maxslot - 1); |
447 | rd->nres = -1; /* Pending call. */ | 457 | rd->nres = -1; /* Pending call. */ |
448 | } /* else: Interpreter will throw. */ | 458 | } /* else: Interpreter will throw. */ |
@@ -462,13 +472,16 @@ static void LJ_FASTCALL recff_xpcall(jit_State *J, RecordFFData *rd) | |||
462 | TValue argv0, argv1; | 472 | TValue argv0, argv1; |
463 | TRef tmp; | 473 | TRef tmp; |
464 | int errcode; | 474 | int errcode; |
465 | lua_assert(!LJ_FR2); /* TODO_FR2: handle different frame setup. */ | ||
466 | /* Swap function and traceback. */ | 475 | /* Swap function and traceback. */ |
467 | tmp = J->base[0]; J->base[0] = J->base[1]; J->base[1] = tmp; | 476 | tmp = J->base[0]; J->base[0] = J->base[1]; J->base[1] = tmp; |
468 | copyTV(J->L, &argv0, &rd->argv[0]); | 477 | copyTV(J->L, &argv0, &rd->argv[0]); |
469 | copyTV(J->L, &argv1, &rd->argv[1]); | 478 | copyTV(J->L, &argv1, &rd->argv[1]); |
470 | copyTV(J->L, &rd->argv[0], &argv1); | 479 | copyTV(J->L, &rd->argv[0], &argv1); |
471 | copyTV(J->L, &rd->argv[1], &argv0); | 480 | copyTV(J->L, &rd->argv[1], &argv0); |
481 | #if LJ_FR2 | ||
482 | /* Shift function arguments up. */ | ||
483 | memmove(J->base + 2, J->base + 1, sizeof(TRef) * (J->maxslot-1)); | ||
484 | #endif | ||
472 | /* Need to protect lj_record_call because it may throw. */ | 485 | /* Need to protect lj_record_call because it may throw. */ |
473 | errcode = lj_vm_cpcall(J->L, NULL, J, recff_xpcall_cp); | 486 | errcode = lj_vm_cpcall(J->L, NULL, J, recff_xpcall_cp); |
474 | /* Always undo Lua stack swap to avoid confusing the interpreter. */ | 487 | /* Always undo Lua stack swap to avoid confusing the interpreter. */ |