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