aboutsummaryrefslogtreecommitdiff
path: root/src/lj_meta.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_meta.c')
-rw-r--r--src/lj_meta.c40
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
306TValue * 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. */
306TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op) 338TValue *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)));