diff options
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r-- | src/lj_crecord.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 83c57063..8330faaf 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -51,6 +51,18 @@ static GCcdata *argv2cdata(jit_State *J, TRef tr, cTValue *o) | |||
51 | return cd; | 51 | return cd; |
52 | } | 52 | } |
53 | 53 | ||
54 | /* Specialize to the CTypeID held by a cdata constructor. */ | ||
55 | static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr) | ||
56 | { | ||
57 | CTypeID id; | ||
58 | lua_assert(tref_iscdata(tr) && cd->typeid == CTID_CTYPEID); | ||
59 | id = *(CTypeID *)cdataptr(cd); | ||
60 | tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata))); | ||
61 | tr = emitir(IRT(IR_XLOAD, IRT_INT), tr, 0); | ||
62 | emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id)); | ||
63 | return id; | ||
64 | } | ||
65 | |||
54 | static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o) | 66 | static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o) |
55 | { | 67 | { |
56 | if (tref_isstr(tr)) { | 68 | if (tref_isstr(tr)) { |
@@ -70,7 +82,8 @@ static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o) | |||
70 | return cp.val.id; | 82 | return cp.val.id; |
71 | } else { | 83 | } else { |
72 | GCcdata *cd = argv2cdata(J, tr, o); | 84 | GCcdata *cd = argv2cdata(J, tr, o); |
73 | return cd->typeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : cd->typeid; | 85 | return cd->typeid == CTID_CTYPEID ? crec_constructor(J, cd, tr) : |
86 | cd->typeid; | ||
74 | } | 87 | } |
75 | } | 88 | } |
76 | 89 | ||
@@ -427,18 +440,6 @@ doconv: | |||
427 | 440 | ||
428 | /* -- C data metamethods -------------------------------------------------- */ | 441 | /* -- C data metamethods -------------------------------------------------- */ |
429 | 442 | ||
430 | /* Specialize to the CTypeID held by a cdata constructor. */ | ||
431 | static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr) | ||
432 | { | ||
433 | CTypeID id; | ||
434 | lua_assert(tref_iscdata(tr) && cd->typeid == CTID_CTYPEID); | ||
435 | id = *(CTypeID *)cdataptr(cd); | ||
436 | tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata))); | ||
437 | tr = emitir(IRT(IR_XLOAD, IRT_INT), tr, 0); | ||
438 | emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id)); | ||
439 | return id; | ||
440 | } | ||
441 | |||
442 | /* This would be rather difficult in FOLD, so do it here: | 443 | /* This would be rather difficult in FOLD, so do it here: |
443 | ** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k) | 444 | ** (base+k)+(idx*sz)+ofs ==> (base+idx*sz)+(ofs+k) |
444 | ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz) | 445 | ** (base+(idx+k)*sz)+ofs ==> (base+idx*sz)+(ofs+k*sz) |
@@ -1100,6 +1101,18 @@ void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd) | |||
1100 | } /* else: interpreter will throw. */ | 1101 | } /* else: interpreter will throw. */ |
1101 | } | 1102 | } |
1102 | 1103 | ||
1104 | void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd) | ||
1105 | { | ||
1106 | argv2ctype(J, J->base[0], &rd->argv[0]); | ||
1107 | if (tref_iscdata(J->base[1])) { | ||
1108 | argv2ctype(J, J->base[1], &rd->argv[1]); | ||
1109 | J->postproc = LJ_POST_FIXBOOL; | ||
1110 | J->base[0] = TREF_TRUE; | ||
1111 | } else { | ||
1112 | J->base[0] = TREF_FALSE; | ||
1113 | } | ||
1114 | } | ||
1115 | |||
1103 | void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd) | 1116 | void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd) |
1104 | { | 1117 | { |
1105 | if (tref_isstr(J->base[0])) { | 1118 | if (tref_isstr(J->base[0])) { |