diff options
Diffstat (limited to 'src/lj_meta.c')
-rw-r--r-- | src/lj_meta.c | 50 |
1 files changed, 30 insertions, 20 deletions
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 | ||