diff options
Diffstat (limited to 'src/lib_ffi.c')
-rw-r--r-- | src/lib_ffi.c | 82 |
1 files changed, 50 insertions, 32 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 83483d95..b3da1f3e 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "lj_ccall.h" | 29 | #include "lj_ccall.h" |
30 | #include "lj_ccallback.h" | 30 | #include "lj_ccallback.h" |
31 | #include "lj_clib.h" | 31 | #include "lj_clib.h" |
32 | #include "lj_strfmt.h" | ||
32 | #include "lj_ff.h" | 33 | #include "lj_ff.h" |
33 | #include "lj_lib.h" | 34 | #include "lj_lib.h" |
34 | 35 | ||
@@ -137,7 +138,7 @@ static int ffi_index_meta(lua_State *L, CTState *cts, CType *ct, MMS mm) | |||
137 | } | 138 | } |
138 | } | 139 | } |
139 | copyTV(L, base, L->top); | 140 | copyTV(L, base, L->top); |
140 | tv = L->top-1; | 141 | tv = L->top-1-LJ_FR2; |
141 | } | 142 | } |
142 | return lj_meta_tailcall(L, tv); | 143 | return lj_meta_tailcall(L, tv); |
143 | } | 144 | } |
@@ -318,7 +319,7 @@ LJLIB_CF(ffi_meta___tostring) | |||
318 | } | 319 | } |
319 | } | 320 | } |
320 | } | 321 | } |
321 | lj_str_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), p); | 322 | lj_strfmt_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), p); |
322 | checkgc: | 323 | checkgc: |
323 | lj_gc_check(L); | 324 | lj_gc_check(L); |
324 | return 1; | 325 | return 1; |
@@ -504,10 +505,7 @@ LJLIB_CF(ffi_new) LJLIB_REC(.) | |||
504 | } | 505 | } |
505 | if (sz == CTSIZE_INVALID) | 506 | if (sz == CTSIZE_INVALID) |
506 | lj_err_arg(L, 1, LJ_ERR_FFI_INVSIZE); | 507 | lj_err_arg(L, 1, LJ_ERR_FFI_INVSIZE); |
507 | if (!(info & CTF_VLA) && ctype_align(info) <= CT_MEMALIGN) | 508 | cd = lj_cdata_newx(cts, id, sz, info); |
508 | cd = lj_cdata_new(cts, id, sz); | ||
509 | else | ||
510 | cd = lj_cdata_newv(cts, id, sz, ctype_align(info)); | ||
511 | setcdataV(L, o-1, cd); /* Anchor the uninitialized cdata. */ | 509 | setcdataV(L, o-1, cd); /* Anchor the uninitialized cdata. */ |
512 | lj_cconv_ct_init(cts, ct, sz, cdataptr(cd), | 510 | lj_cconv_ct_init(cts, ct, sz, cdataptr(cd), |
513 | o, (MSize)(L->top - o)); /* Initialize cdata. */ | 511 | o, (MSize)(L->top - o)); /* Initialize cdata. */ |
@@ -558,6 +556,31 @@ LJLIB_CF(ffi_typeof) LJLIB_REC(.) | |||
558 | return 1; | 556 | return 1; |
559 | } | 557 | } |
560 | 558 | ||
559 | /* Internal and unsupported API. */ | ||
560 | LJLIB_CF(ffi_typeinfo) | ||
561 | { | ||
562 | CTState *cts = ctype_cts(L); | ||
563 | CTypeID id = (CTypeID)ffi_checkint(L, 1); | ||
564 | if (id > 0 && id < cts->top) { | ||
565 | CType *ct = ctype_get(cts, id); | ||
566 | GCtab *t; | ||
567 | lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */ | ||
568 | t = tabV(L->top-1); | ||
569 | setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "info")), (int32_t)ct->info); | ||
570 | if (ct->size != CTSIZE_INVALID) | ||
571 | setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "size")), (int32_t)ct->size); | ||
572 | if (ct->sib) | ||
573 | setintV(lj_tab_setstr(L, t, lj_str_newlit(L, "sib")), (int32_t)ct->sib); | ||
574 | if (gcref(ct->name)) { | ||
575 | GCstr *s = gco2str(gcref(ct->name)); | ||
576 | setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "name")), s); | ||
577 | } | ||
578 | lj_gc_check(L); | ||
579 | return 1; | ||
580 | } | ||
581 | return 0; | ||
582 | } | ||
583 | |||
561 | LJLIB_CF(ffi_istype) LJLIB_REC(.) | 584 | LJLIB_CF(ffi_istype) LJLIB_REC(.) |
562 | { | 585 | { |
563 | CTState *cts = ctype_cts(L); | 586 | CTState *cts = ctype_cts(L); |
@@ -697,44 +720,47 @@ LJLIB_CF(ffi_fill) LJLIB_REC(.) | |||
697 | return 0; | 720 | return 0; |
698 | } | 721 | } |
699 | 722 | ||
700 | #define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be) | ||
701 | |||
702 | /* Test ABI string. */ | 723 | /* Test ABI string. */ |
703 | LJLIB_CF(ffi_abi) LJLIB_REC(.) | 724 | LJLIB_CF(ffi_abi) LJLIB_REC(.) |
704 | { | 725 | { |
705 | GCstr *s = lj_lib_checkstr(L, 1); | 726 | GCstr *s = lj_lib_checkstr(L, 1); |
706 | int b = 0; | 727 | int b = lj_cparse_case(s, |
707 | switch (s->hash) { | ||
708 | #if LJ_64 | 728 | #if LJ_64 |
709 | case H_(849858eb,ad35fd06): b = 1; break; /* 64bit */ | 729 | "\00564bit" |
710 | #else | 730 | #else |
711 | case H_(662d3c79,d0e22477): b = 1; break; /* 32bit */ | 731 | "\00532bit" |
712 | #endif | 732 | #endif |
713 | #if LJ_ARCH_HASFPU | 733 | #if LJ_ARCH_HASFPU |
714 | case H_(e33ee463,e33ee463): b = 1; break; /* fpu */ | 734 | "\003fpu" |
715 | #endif | 735 | #endif |
716 | #if LJ_ABI_SOFTFP | 736 | #if LJ_ABI_SOFTFP |
717 | case H_(61211a23,c2e8c81c): b = 1; break; /* softfp */ | 737 | "\006softfp" |
718 | #else | 738 | #else |
719 | case H_(539417a8,8ce0812f): b = 1; break; /* hardfp */ | 739 | "\006hardfp" |
720 | #endif | 740 | #endif |
721 | #if LJ_ABI_EABI | 741 | #if LJ_ABI_EABI |
722 | case H_(2182df8f,f2ed1152): b = 1; break; /* eabi */ | 742 | "\004eabi" |
723 | #endif | 743 | #endif |
724 | #if LJ_ABI_WIN | 744 | #if LJ_ABI_WIN |
725 | case H_(4ab624a8,4ab624a8): b = 1; break; /* win */ | 745 | "\003win" |
726 | #endif | 746 | #endif |
727 | case H_(3af93066,1f001464): b = 1; break; /* le/be */ | 747 | #if LJ_TARGET_UWP |
728 | default: | 748 | "\003uwp" |
729 | break; | 749 | #endif |
730 | } | 750 | #if LJ_LE |
751 | "\002le" | ||
752 | #else | ||
753 | "\002be" | ||
754 | #endif | ||
755 | #if LJ_GC64 | ||
756 | "\004gc64" | ||
757 | #endif | ||
758 | ) >= 0; | ||
731 | setboolV(L->top-1, b); | 759 | setboolV(L->top-1, b); |
732 | setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */ | 760 | setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */ |
733 | return 1; | 761 | return 1; |
734 | } | 762 | } |
735 | 763 | ||
736 | #undef H_ | ||
737 | |||
738 | LJLIB_PUSH(top-8) LJLIB_SET(!) /* Store reference to miscmap table. */ | 764 | LJLIB_PUSH(top-8) LJLIB_SET(!) /* Store reference to miscmap table. */ |
739 | 765 | ||
740 | LJLIB_CF(ffi_metatype) | 766 | LJLIB_CF(ffi_metatype) |
@@ -768,19 +794,11 @@ LJLIB_CF(ffi_gc) LJLIB_REC(.) | |||
768 | GCcdata *cd = ffi_checkcdata(L, 1); | 794 | GCcdata *cd = ffi_checkcdata(L, 1); |
769 | TValue *fin = lj_lib_checkany(L, 2); | 795 | TValue *fin = lj_lib_checkany(L, 2); |
770 | CTState *cts = ctype_cts(L); | 796 | CTState *cts = ctype_cts(L); |
771 | GCtab *t = cts->finalizer; | ||
772 | CType *ct = ctype_raw(cts, cd->ctypeid); | 797 | CType *ct = ctype_raw(cts, cd->ctypeid); |
773 | if (!(ctype_isptr(ct->info) || ctype_isstruct(ct->info) || | 798 | if (!(ctype_isptr(ct->info) || ctype_isstruct(ct->info) || |
774 | ctype_isrefarray(ct->info))) | 799 | ctype_isrefarray(ct->info))) |
775 | lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE); | 800 | lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE); |
776 | if (gcref(t->metatable)) { /* Update finalizer table, if still enabled. */ | 801 | lj_cdata_setfin(L, cd, gcval(fin), itype(fin)); |
777 | copyTV(L, lj_tab_set(L, t, L->base), fin); | ||
778 | lj_gc_anybarriert(L, t); | ||
779 | if (!tvisnil(fin)) | ||
780 | cd->marked |= LJ_GC_CDATA_FIN; | ||
781 | else | ||
782 | cd->marked &= ~LJ_GC_CDATA_FIN; | ||
783 | } | ||
784 | L->top = L->base+1; /* Pass through the cdata object. */ | 802 | L->top = L->base+1; /* Pass through the cdata object. */ |
785 | return 1; | 803 | return 1; |
786 | } | 804 | } |