X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/0559abf83c4cc9bbd896b69dfaae1e8422521479..7341eedbaf526ef2f0986b576c656906050e270a:/sig/ffi_type.cpp diff --git a/sig/ffi_type.cpp b/sig/ffi_type.cpp index 73b3912..5d31b0f 100644 --- a/sig/ffi_type.cpp +++ b/sig/ffi_type.cpp @@ -1,5 +1,5 @@ -/* Cycript - Optimizing JavaScript Compiler/Runtime - * Copyright (C) 2009-2015 Jay Freeman (saurik) +/* Cycript - The Truly Universal Scripting Language + * Copyright (C) 2009-2016 Jay Freeman (saurik) */ /* GNU Affero General Public License, Version 3 {{{ */ @@ -29,18 +29,6 @@ namespace sig { -void sig_ffi_types( - CYPool &pool, - const struct Signature *signature, - ffi_type **types, - size_t skip = 0, - size_t offset = 0 -) { - _assert(signature->count >= skip); - for (size_t index = skip; index != signature->count; ++index) - types[index - skip + offset] = signature->elements[index].type->GetFFI(pool); -} - template <> ffi_type *Primitive::GetFFI(CYPool &pool) const { return &ffi_type_uchar; @@ -170,9 +158,17 @@ ffi_type *Aggregate::GetFFI(CYPool &pool) const { ffi->alignment = 0; ffi->type = FFI_TYPE_STRUCT; - ffi->elements = new(pool) ffi_type *[signature.count + 1]; - sig_ffi_types(pool, &signature, ffi->elements); - ffi->elements[signature.count] = NULL; + if (signature.count == 0) { + // https://gcc.gnu.org/ml/gcc-patches/2015-01/msg01286.html + ffi->elements = new(pool) ffi_type *[2]; + ffi->elements[0] = &ffi_type_void; + ffi->elements[1] = NULL; + } else { + ffi->elements = new(pool) ffi_type *[signature.count + 1]; + for (size_t index(0); index != signature.count; ++index) + ffi->elements[index] = signature.elements[index].type->GetFFI(pool); + ffi->elements[signature.count] = NULL; + } return ffi; } @@ -185,19 +181,24 @@ ffi_type *Block::GetFFI(CYPool &pool) const { return &ffi_type_pointer; } -void sig_ffi_cif( - CYPool &pool, - struct Signature *signature, - ffi_cif *cif, - size_t skip, - ffi_type **types, - size_t offset -) { - if (types == NULL) - types = new(pool) ffi_type *[signature->count - 1]; - ffi_type *type = signature->elements[0].type->GetFFI(pool); - sig_ffi_types(pool, signature, types, 1 + skip, offset); - ffi_status status = ffi_prep_cif(cif, FFI_DEFAULT_ABI, signature->count - 1 - skip + offset, type, types); +void sig_ffi_cif(CYPool &pool, size_t variadic, const Signature &signature, ffi_cif *cif) { + _assert(signature.count != 0); + size_t count(signature.count - 1); + ffi_type *type(signature.elements[0].type->GetFFI(pool)); + + ffi_type **types(new(pool) ffi_type *[count]); + for (size_t index(0); index != count; ++index) + types[index] = signature.elements[index + 1].type->GetFFI(pool); + + ffi_status status; +#ifdef HAVE_FFI_PREP_CIF_VAR + if (variadic == 0) +#endif + status = ffi_prep_cif(cif, FFI_DEFAULT_ABI, count, type, types); +#ifdef HAVE_FFI_PREP_CIF_VAR + else + status = ffi_prep_cif_var(cif, FFI_DEFAULT_ABI, variadic - 1, count, type, types); +#endif _assert(status == FFI_OK); }