diff options
author | Mike Pall <mike> | 2011-04-20 01:53:26 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-04-20 01:53:26 +0200 |
commit | 5d096dcfdef5ddb0e6dd67e155adf893df7d7809 (patch) | |
tree | 9bdbd2852738e761b1b2f0f1858eb91f22a8e638 /src | |
parent | 9ea679410c8061741a49350b3fc969365ffe5547 (diff) | |
download | luajit-5d096dcfdef5ddb0e6dd67e155adf893df7d7809.tar.gz luajit-5d096dcfdef5ddb0e6dd67e155adf893df7d7809.tar.bz2 luajit-5d096dcfdef5ddb0e6dd67e155adf893df7d7809.zip |
FFI: Add ffi.istype() function.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib_ffi.c | 30 | ||||
-rw-r--r-- | src/lj_crecord.c | 39 | ||||
-rw-r--r-- | src/lj_crecord.h | 2 |
3 files changed, 58 insertions, 13 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index fe84ca7d..27996f0e 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
@@ -456,6 +456,36 @@ LJLIB_CF(ffi_typeof) | |||
456 | return 1; | 456 | return 1; |
457 | } | 457 | } |
458 | 458 | ||
459 | LJLIB_CF(ffi_istype) LJLIB_REC(ffi_istype) | ||
460 | { | ||
461 | CTState *cts = ctype_cts(L); | ||
462 | CTypeID id1 = ffi_checkctype(L, cts); | ||
463 | TValue *o = lj_lib_checkany(L, 2); | ||
464 | int b = 0; | ||
465 | if (tviscdata(o)) { | ||
466 | GCcdata *cd = cdataV(o); | ||
467 | CTypeID id2 = cd->typeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : | ||
468 | cd->typeid; | ||
469 | CType *ct1 = lj_ctype_rawref(cts, id1); | ||
470 | CType *ct2 = lj_ctype_rawref(cts, id2); | ||
471 | if (ct1 == ct2) { | ||
472 | b = 1; | ||
473 | } else if (ctype_type(ct1->info) == ctype_type(ct2->info) && | ||
474 | ct1->size == ct2->size) { | ||
475 | if (ctype_ispointer(ct1->info)) | ||
476 | b = lj_cconv_compatptr(cts, ct1, ct2, CCF_IGNQUAL); | ||
477 | else if (ctype_isnum(ct1->info) || ctype_isvoid(ct1->info)) | ||
478 | b = (((ct1->info ^ ct2->info) & ~CTF_QUAL) == 0); | ||
479 | } else if (ctype_isstruct(ct1->info) && ctype_isptr(ct2->info) && | ||
480 | ct1 == ctype_rawchild(cts, ct2)) { | ||
481 | b = 1; | ||
482 | } | ||
483 | } | ||
484 | setboolV(L->top-1, b); | ||
485 | setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */ | ||
486 | return 1; | ||
487 | } | ||
488 | |||
459 | LJLIB_CF(ffi_sizeof) | 489 | LJLIB_CF(ffi_sizeof) |
460 | { | 490 | { |
461 | CTState *cts = ctype_cts(L); | 491 | CTState *cts = ctype_cts(L); |
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])) { |
diff --git a/src/lj_crecord.h b/src/lj_crecord.h index 0199e0eb..fce45afe 100644 --- a/src/lj_crecord.h +++ b/src/lj_crecord.h | |||
@@ -19,6 +19,7 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd); | |||
19 | LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd); | 19 | LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd); |
20 | LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd); | 20 | LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd); |
21 | LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd); | 21 | LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd); |
22 | LJ_FUNC void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd); | ||
22 | LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd); | 23 | LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd); |
23 | LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); | 24 | LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); |
24 | #else | 25 | #else |
@@ -30,6 +31,7 @@ LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); | |||
30 | #define recff_ffi_string recff_nyi | 31 | #define recff_ffi_string recff_nyi |
31 | #define recff_ffi_copy recff_nyi | 32 | #define recff_ffi_copy recff_nyi |
32 | #define recff_ffi_fill recff_nyi | 33 | #define recff_ffi_fill recff_nyi |
34 | #define recff_ffi_istype recff_nyi | ||
33 | #define recff_ffi_abi recff_nyi | 35 | #define recff_ffi_abi recff_nyi |
34 | #endif | 36 | #endif |
35 | 37 | ||