diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib_ffi.c | 48 |
1 files changed, 33 insertions, 15 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index aecc3395..1feee215 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); |
@@ -725,6 +748,9 @@ LJLIB_CF(ffi_abi) LJLIB_REC(.) | |||
725 | case H_(4ab624a8,4ab624a8): b = 1; break; /* win */ | 748 | case H_(4ab624a8,4ab624a8): b = 1; break; /* win */ |
726 | #endif | 749 | #endif |
727 | case H_(3af93066,1f001464): b = 1; break; /* le/be */ | 750 | case H_(3af93066,1f001464): b = 1; break; /* le/be */ |
751 | #if LJ_GC64 | ||
752 | case H_(9e89d2c9,13c83c92): b = 1; break; /* gc64 */ | ||
753 | #endif | ||
728 | default: | 754 | default: |
729 | break; | 755 | break; |
730 | } | 756 | } |
@@ -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 | } |