diff options
Diffstat (limited to 'src/lj_meta.c')
-rw-r--r-- | src/lj_meta.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/src/lj_meta.c b/src/lj_meta.c index 5353e4d4..ce851a22 100644 --- a/src/lj_meta.c +++ b/src/lj_meta.c | |||
@@ -302,10 +302,48 @@ TValue *lj_meta_equal(lua_State *L, GCobj *o1, GCobj *o2, int ne) | |||
302 | return cast(TValue *, (intptr_t)ne); | 302 | return cast(TValue *, (intptr_t)ne); |
303 | } | 303 | } |
304 | 304 | ||
305 | #if LJ_HASFFI | ||
306 | TValue * LJ_FASTCALL lj_meta_equal_cd(lua_State *L, BCIns ins) | ||
307 | { | ||
308 | ASMFunction cont = (bc_op(ins) & 1) ? lj_cont_condf : lj_cont_condt; | ||
309 | int op = (int)bc_op(ins) & ~1; | ||
310 | TValue tv; | ||
311 | cTValue *mo, *o2, *o1 = &L->base[bc_a(ins)]; | ||
312 | if (op == BC_ISEQV) { | ||
313 | cTValue *o = &L->base[bc_d(ins)]; | ||
314 | if (tviscdata(o1)) { | ||
315 | o2 = o; | ||
316 | } else { | ||
317 | o2 = o1; o1 = o; | ||
318 | } | ||
319 | } else if (op == BC_ISEQS) { | ||
320 | setstrV(L, &tv, gco2str(proto_kgc(curr_proto(L), ~(ptrdiff_t)bc_d(ins)))); | ||
321 | o2 = &tv; | ||
322 | } else if (op == BC_ISEQN) { | ||
323 | o2 = &mref(curr_proto(L)->k, cTValue)[bc_d(ins)]; | ||
324 | } else { | ||
325 | lua_assert(op == BC_ISEQP); | ||
326 | setitype(&tv, ~bc_d(ins)); | ||
327 | o2 = &tv; | ||
328 | } | ||
329 | mo = lj_meta_lookup(L, o1, MM_eq); | ||
330 | if (LJ_LIKELY(!tvisnil(mo))) | ||
331 | return mmcall(L, cont, mo, o1, o2); | ||
332 | else | ||
333 | return cast(TValue *, (intptr_t)(bc_op(ins) & 1)); | ||
334 | } | ||
335 | #endif | ||
336 | |||
305 | /* Helper for ordered comparisons. String compare, __lt/__le metamethods. */ | 337 | /* Helper for ordered comparisons. String compare, __lt/__le metamethods. */ |
306 | TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op) | 338 | TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op) |
307 | { | 339 | { |
308 | if (itype(o1) == itype(o2)) { /* Never called with two numbers. */ | 340 | if (LJ_HASFFI && (tviscdata(o1) || tviscdata(o2))) { |
341 | ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt; | ||
342 | MMS mm = (op & 2) ? MM_le : MM_lt; | ||
343 | cTValue *mo = lj_meta_lookup(L, tviscdata(o1) ? o1 : o2, mm); | ||
344 | if (LJ_UNLIKELY(tvisnil(mo))) goto err; | ||
345 | return mmcall(L, cont, mo, o1, o2); | ||
346 | } else if (itype(o1) == itype(o2)) { /* Never called with two numbers. */ | ||
309 | if (tvisstr(o1) && tvisstr(o2)) { | 347 | if (tvisstr(o1) && tvisstr(o2)) { |
310 | int32_t res = lj_str_cmp(strV(o1), strV(o2)); | 348 | int32_t res = lj_str_cmp(strV(o1), strV(o2)); |
311 | return cast(TValue *, (intptr_t)(((op&2) ? res <= 0 : res < 0) ^ (op&1))); | 349 | return cast(TValue *, (intptr_t)(((op&2) ? res <= 0 : res < 0) ^ (op&1))); |