aboutsummaryrefslogtreecommitdiff
path: root/src/lib_ffi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib_ffi.c')
-rw-r--r--src/lib_ffi.c82
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);
322checkgc: 323checkgc:
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. */
560LJLIB_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
561LJLIB_CF(ffi_istype) LJLIB_REC(.) 584LJLIB_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. */
703LJLIB_CF(ffi_abi) LJLIB_REC(.) 724LJLIB_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
738LJLIB_PUSH(top-8) LJLIB_SET(!) /* Store reference to miscmap table. */ 764LJLIB_PUSH(top-8) LJLIB_SET(!) /* Store reference to miscmap table. */
739 765
740LJLIB_CF(ffi_metatype) 766LJLIB_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}