diff options
Diffstat (limited to 'ext/ffi/ffi.c')
| -rw-r--r-- | ext/ffi/ffi.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 0968764459..07b1d8cd1c 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -775,7 +775,7 @@ again: } /* }}} */ -#if defined(ZEND_WIN32) && (defined(HAVE_FFI_FASTCALL) || defined(HAVE_FFI_STDCALL)) +#if defined(ZEND_WIN32) && (defined(HAVE_FFI_FASTCALL) || defined(HAVE_FFI_STDCALL) || defined(HAVE_FFI_VECTORCALL_PARTIAL)) static size_t zend_ffi_arg_size(zend_ffi_type *type) /* {{{ */ { zend_ffi_type *arg_type; @@ -801,6 +801,10 @@ static zend_always_inline zend_string *zend_ffi_mangled_func_name(zend_string *n case FFI_STDCALL: return strpprintf(0, "_%s@%zu", ZSTR_VAL(name), zend_ffi_arg_size(type)); # endif +# ifdef HAVE_FFI_VECTORCALL_PARTIAL + case FFI_VECTORCALL_PARTIAL: + return strpprintf(0, "%s@@%zu", ZSTR_VAL(name), zend_ffi_arg_size(type)); +# endif } #endif return zend_string_copy(name); @@ -5884,6 +5888,29 @@ void zend_ffi_make_func_type(zend_ffi_dcl *dcl, HashTable *args, zend_ffi_dcl *n } } +#ifdef HAVE_FFI_VECTORCALL_PARTIAL + if (dcl->abi == ZEND_FFI_ABI_VECTORCALL && args) { + zend_ulong i; + zend_ffi_type *arg_type; + + ZEND_HASH_FOREACH_NUM_KEY_PTR(args, i, arg_type) { + arg_type = ZEND_FFI_TYPE(arg_type); +# ifdef _WIN64 + if (i >= 4 && i <= 5 && (arg_type->kind == ZEND_FFI_TYPE_FLOAT || arg_type->kind == ZEND_FFI_TYPE_DOUBLE)) { +# else + if (i < 6 && (arg_type->kind == ZEND_FFI_TYPE_FLOAT || arg_type->kind == ZEND_FFI_TYPE_DOUBLE)) { +# endif + zend_ffi_cleanup_dcl(nested_dcl); + zend_ffi_cleanup_dcl(dcl); + zend_hash_destroy(args); + pefree(args, FFI_G(persistent)); + zend_ffi_parser_error("'float'/'double' type not allowed at position " ZEND_ULONG_FMT " with __vectorcall at line %d", i+1, FFI_G(line)); + return; + } + } ZEND_HASH_FOREACH_END(); + } +#endif + if (zend_ffi_validate_func_ret_type(ret_type) != SUCCESS) { zend_ffi_cleanup_dcl(nested_dcl); zend_ffi_cleanup_dcl(dcl); @@ -5940,6 +5967,11 @@ void zend_ffi_make_func_type(zend_ffi_dcl *dcl, HashTable *args, zend_ffi_dcl *n type->func.abi = FFI_SYSV; break; #endif +#ifdef HAVE_FFI_VECTORCALL_PARTIAL + case ZEND_FFI_ABI_VECTORCALL: + type->func.abi = FFI_VECTORCALL_PARTIAL; + break; +#endif default: type->func.abi = FFI_DEFAULT_ABI; zend_ffi_cleanup_dcl(nested_dcl); @@ -6192,6 +6224,7 @@ void zend_ffi_set_abi(zend_ffi_dcl *dcl, uint16_t abi) /* {{{ */ _(stdcall) \ _(ms_abi) \ _(sysv_abi) \ + _(vectorcall) \ _(aligned) \ _(packed) \ _(ms_struct) \ @@ -6257,6 +6290,9 @@ void zend_ffi_add_attribute(zend_ffi_dcl *dcl, const char *name, size_t name_len case attr_sysv_abi: zend_ffi_set_abi(dcl, ZEND_FFI_ABI_SYSV); break; + case attr_vectorcall: + zend_ffi_set_abi(dcl, ZEND_FFI_ABI_VECTORCALL); + break; case attr_aligned: dcl->align = __BIGGEST_ALIGNMENT__; break; |
