@@ -776,7 +776,7 @@ static zend_always_inline int zend_ffi_zval_to_cdata(void *ptr, zend_ffi_type *t
776
776
}
777
777
/* }}} */
778
778
779
- #if defined(ZEND_WIN32 ) && (defined(HAVE_FFI_FASTCALL ) || defined(HAVE_FFI_STDCALL ))
779
+ #if defined(ZEND_WIN32 ) && (defined(HAVE_FFI_FASTCALL ) || defined(HAVE_FFI_STDCALL ) || defined( HAVE_FFI_VECTORCALL_PARTIAL ) )
780
780
static size_t zend_ffi_arg_size (zend_ffi_type * type ) /* {{{ */
781
781
{
782
782
zend_ffi_type * arg_type ;
@@ -801,6 +801,10 @@ static zend_always_inline zend_string *zend_ffi_mangled_func_name(zend_string *n
801
801
# ifdef HAVE_FFI_STDCALL
802
802
case FFI_STDCALL :
803
803
return strpprintf (0 , "_%s@%zu" , ZSTR_VAL (name ), zend_ffi_arg_size (type ));
804
+ # endif
805
+ # ifdef HAVE_FFI_VECTORCALL_PARTIAL
806
+ case FFI_VECTORCALL_PARTIAL :
807
+ return strpprintf (0 , "%s@@%zu" , ZSTR_VAL (name ), zend_ffi_arg_size (type ));
804
808
# endif
805
809
}
806
810
#endif
@@ -6008,6 +6012,29 @@ void zend_ffi_make_func_type(zend_ffi_dcl *dcl, HashTable *args, zend_ffi_dcl *n
6008
6012
}
6009
6013
}
6010
6014
6015
+ #ifdef HAVE_FFI_VECTORCALL_PARTIAL
6016
+ if (dcl -> abi == ZEND_FFI_ABI_VECTORCALL && args ) {
6017
+ zend_ulong i ;
6018
+ zend_ffi_type * arg_type ;
6019
+
6020
+ ZEND_HASH_FOREACH_NUM_KEY_PTR (args , i , arg_type ) {
6021
+ arg_type = ZEND_FFI_TYPE (arg_type );
6022
+ # ifdef _WIN64
6023
+ if (i >= 4 && i <= 5 && (arg_type -> kind == ZEND_FFI_TYPE_FLOAT || arg_type -> kind == ZEND_FFI_TYPE_DOUBLE )) {
6024
+ # else
6025
+ if (i < 6 && (arg_type -> kind == ZEND_FFI_TYPE_FLOAT || arg_type -> kind == ZEND_FFI_TYPE_DOUBLE )) {
6026
+ # endif
6027
+ zend_ffi_cleanup_dcl (nested_dcl );
6028
+ zend_ffi_cleanup_dcl (dcl );
6029
+ zend_hash_destroy (args );
6030
+ pefree (args , FFI_G (persistent ));
6031
+ zend_ffi_parser_error ("'float'/'double' type not allowed at position " ZEND_ULONG_FMT " with __vectorcall at line %d" , i + 1 , FFI_G (line ));
6032
+ return ;
6033
+ }
6034
+ } ZEND_HASH_FOREACH_END ();
6035
+ }
6036
+ #endif
6037
+
6011
6038
if (zend_ffi_validate_func_ret_type (ret_type ) != SUCCESS ) {
6012
6039
zend_ffi_cleanup_dcl (nested_dcl );
6013
6040
zend_ffi_cleanup_dcl (dcl );
@@ -6063,6 +6090,11 @@ void zend_ffi_make_func_type(zend_ffi_dcl *dcl, HashTable *args, zend_ffi_dcl *n
6063
6090
case ZEND_FFI_ABI_SYSV :
6064
6091
type -> func .abi = FFI_SYSV ;
6065
6092
break ;
6093
+ #endif
6094
+ #ifdef HAVE_FFI_VECTORCALL_PARTIAL
6095
+ case ZEND_FFI_ABI_VECTORCALL :
6096
+ type -> func .abi = FFI_VECTORCALL_PARTIAL ;
6097
+ break ;
6066
6098
#endif
6067
6099
default :
6068
6100
type -> func .abi = FFI_DEFAULT_ABI ;
@@ -6316,6 +6348,7 @@ void zend_ffi_set_abi(zend_ffi_dcl *dcl, uint16_t abi) /* {{{ */
6316
6348
_(stdcall) \
6317
6349
_(ms_abi) \
6318
6350
_(sysv_abi) \
6351
+ _(vectorcall) \
6319
6352
_(aligned) \
6320
6353
_(packed) \
6321
6354
_(ms_struct) \
@@ -6381,6 +6414,9 @@ void zend_ffi_add_attribute(zend_ffi_dcl *dcl, const char *name, size_t name_len
6381
6414
case attr_sysv_abi :
6382
6415
zend_ffi_set_abi (dcl , ZEND_FFI_ABI_SYSV );
6383
6416
break ;
6417
+ case attr_vectorcall :
6418
+ zend_ffi_set_abi (dcl , ZEND_FFI_ABI_VECTORCALL );
6419
+ break ;
6384
6420
case attr_aligned :
6385
6421
dcl -> align = __BIGGEST_ALIGNMENT__ ;
6386
6422
break ;
0 commit comments