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.c83
1 files changed, 51 insertions, 32 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c
index cc8d419d..ac2b2742 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,32 @@ 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 if (isdead(G(L), obj2gco(s))) flipwhite(obj2gco(s));
577 setstrV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "name")), s);
578 }
579 lj_gc_check(L);
580 return 1;
581 }
582 return 0;
583}
584
561LJLIB_CF(ffi_istype) LJLIB_REC(.) 585LJLIB_CF(ffi_istype) LJLIB_REC(.)
562{ 586{
563 CTState *cts = ctype_cts(L); 587 CTState *cts = ctype_cts(L);
@@ -697,44 +721,47 @@ LJLIB_CF(ffi_fill) LJLIB_REC(.)
697 return 0; 721 return 0;
698} 722}
699 723
700#define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be)
701
702/* Test ABI string. */ 724/* Test ABI string. */
703LJLIB_CF(ffi_abi) LJLIB_REC(.) 725LJLIB_CF(ffi_abi) LJLIB_REC(.)
704{ 726{
705 GCstr *s = lj_lib_checkstr(L, 1); 727 GCstr *s = lj_lib_checkstr(L, 1);
706 int b = 0; 728 int b = lj_cparse_case(s,
707 switch (s->hash) {
708#if LJ_64 729#if LJ_64
709 case H_(849858eb,ad35fd06): b = 1; break; /* 64bit */ 730 "\00564bit"
710#else 731#else
711 case H_(662d3c79,d0e22477): b = 1; break; /* 32bit */ 732 "\00532bit"
712#endif 733#endif
713#if LJ_ARCH_HASFPU 734#if LJ_ARCH_HASFPU
714 case H_(e33ee463,e33ee463): b = 1; break; /* fpu */ 735 "\003fpu"
715#endif 736#endif
716#if LJ_ABI_SOFTFP 737#if LJ_ABI_SOFTFP
717 case H_(61211a23,c2e8c81c): b = 1; break; /* softfp */ 738 "\006softfp"
718#else 739#else
719 case H_(539417a8,8ce0812f): b = 1; break; /* hardfp */ 740 "\006hardfp"
720#endif 741#endif
721#if LJ_ABI_EABI 742#if LJ_ABI_EABI
722 case H_(2182df8f,f2ed1152): b = 1; break; /* eabi */ 743 "\004eabi"
723#endif 744#endif
724#if LJ_ABI_WIN 745#if LJ_ABI_WIN
725 case H_(4ab624a8,4ab624a8): b = 1; break; /* win */ 746 "\003win"
726#endif 747#endif
727 case H_(3af93066,1f001464): b = 1; break; /* le/be */ 748#if LJ_TARGET_UWP
728 default: 749 "\003uwp"
729 break; 750#endif
730 } 751#if LJ_LE
752 "\002le"
753#else
754 "\002be"
755#endif
756#if LJ_GC64
757 "\004gc64"
758#endif
759 ) >= 0;
731 setboolV(L->top-1, b); 760 setboolV(L->top-1, b);
732 setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */ 761 setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */
733 return 1; 762 return 1;
734} 763}
735 764
736#undef H_
737
738LJLIB_PUSH(top-8) LJLIB_SET(!) /* Store reference to miscmap table. */ 765LJLIB_PUSH(top-8) LJLIB_SET(!) /* Store reference to miscmap table. */
739 766
740LJLIB_CF(ffi_metatype) 767LJLIB_CF(ffi_metatype)
@@ -768,19 +795,11 @@ LJLIB_CF(ffi_gc) LJLIB_REC(.)
768 GCcdata *cd = ffi_checkcdata(L, 1); 795 GCcdata *cd = ffi_checkcdata(L, 1);
769 TValue *fin = lj_lib_checkany(L, 2); 796 TValue *fin = lj_lib_checkany(L, 2);
770 CTState *cts = ctype_cts(L); 797 CTState *cts = ctype_cts(L);
771 GCtab *t = cts->finalizer;
772 CType *ct = ctype_raw(cts, cd->ctypeid); 798 CType *ct = ctype_raw(cts, cd->ctypeid);
773 if (!(ctype_isptr(ct->info) || ctype_isstruct(ct->info) || 799 if (!(ctype_isptr(ct->info) || ctype_isstruct(ct->info) ||
774 ctype_isrefarray(ct->info))) 800 ctype_isrefarray(ct->info)))
775 lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE); 801 lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE);
776 if (gcref(t->metatable)) { /* Update finalizer table, if still enabled. */ 802 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. */ 803 L->top = L->base+1; /* Pass through the cdata object. */
785 return 1; 804 return 1;
786} 805}