diff --git a/.gitmodules b/.gitmodules index b4c0365e..91c1df44 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,7 @@ [submodule "libffi"] path = libffi url = https://github.com/NativeScript/libffi.git - branch = darind/v8-ios + branch = feat/vector-types [submodule "TestRunner/app/shared"] path = TestRunner/app/shared url = https://github.com/NativeScript/common-runtime-tests-app.git diff --git a/NativeScript/include/libffi/arm64/ffi.h b/NativeScript/include/libffi/arm64/ffi.h index 5185731a..d281418c 100644 --- a/NativeScript/include/libffi/arm64/ffi.h +++ b/NativeScript/include/libffi/arm64/ffi.h @@ -1,6 +1,7 @@ /* -----------------------------------------------------------------*-C-*- - libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green - - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc. + libffi 3.7.1 + - Copyright (c) 2011, 2014, 2019, 2021, 2022, 2024, 2025, 2026 Anthony Green + - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -55,6 +56,34 @@ extern "C" { /* ---- System configuration information --------------------------------- */ +/* If these change, update src/mips/ffitarget.h. */ +#define FFI_TYPE_VOID 0 +#define FFI_TYPE_INT 1 +#define FFI_TYPE_FLOAT 2 +#define FFI_TYPE_DOUBLE 3 +#if 0 +#define FFI_TYPE_LONGDOUBLE 4 +#else +#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE +#endif +#define FFI_TYPE_UINT8 5 +#define FFI_TYPE_SINT8 6 +#define FFI_TYPE_UINT16 7 +#define FFI_TYPE_SINT16 8 +#define FFI_TYPE_UINT32 9 +#define FFI_TYPE_SINT32 10 +#define FFI_TYPE_UINT64 11 +#define FFI_TYPE_SINT64 12 +#define FFI_TYPE_STRUCT 13 +#define FFI_TYPE_POINTER 14 +#define FFI_TYPE_COMPLEX 15 +#define FFI_TYPE_UINT128 16 +#define FFI_TYPE_SINT128 17 +#define FFI_TYPE_VECTOR 18 + +/* This should always refer to the last type code (for sanity checks). */ +#define FFI_TYPE_LAST FFI_TYPE_VECTOR + #include "ffitarget.h" #ifndef LIBFFI_ASM @@ -114,13 +143,11 @@ typedef struct _ffi_type when using the static version of the library. Besides, as a workaround, they can define FFI_BUILDING if they *know* they are going to link with the static library. */ -#if defined _MSC_VER +#if defined _MSC_VER && !defined(FFI_STATIC_BUILD) # if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */ # define FFI_API __declspec(dllexport) -# elif !defined FFI_BUILDING /* Importing libffi.DLL */ +# else /* Importing libffi.DLL */ # define FFI_API __declspec(dllimport) -# else /* Building/linking static library */ -# define FFI_API # endif #else # define FFI_API @@ -196,28 +223,25 @@ FFI_EXTERN ffi_type ffi_type_sint64; FFI_EXTERN ffi_type ffi_type_float; FFI_EXTERN ffi_type ffi_type_double; FFI_EXTERN ffi_type ffi_type_pointer; - -#if 0 FFI_EXTERN ffi_type ffi_type_longdouble; -#else -#define ffi_type_longdouble ffi_type_double -#endif #ifdef FFI_TARGET_HAS_COMPLEX_TYPE FFI_EXTERN ffi_type ffi_type_complex_float; FFI_EXTERN ffi_type ffi_type_complex_double; -#if 0 FFI_EXTERN ffi_type ffi_type_complex_longdouble; -#else -#define ffi_type_complex_longdouble ffi_type_complex_double #endif + +#ifdef FFI_TARGET_HAS_INT128 +FFI_EXTERN ffi_type ffi_type_uint128; +FFI_EXTERN ffi_type ffi_type_sint128; #endif #endif /* LIBFFI_HIDE_BASIC_TYPES */ typedef enum { FFI_OK = 0, FFI_BAD_TYPEDEF, - FFI_BAD_ABI + FFI_BAD_ABI, + FFI_BAD_ARGTYPE } ffi_status; typedef struct { @@ -288,15 +312,33 @@ FFI_API void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, - ffi_java_raw *avalue); + ffi_java_raw *avalue) __attribute__((deprecated)); #endif FFI_API -void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw); +void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated)); FFI_API -void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args); +void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated)); FFI_API -size_t ffi_java_raw_size (ffi_cif *cif); +size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated)); + +/* ---- Version API ------------------------------------------------------ */ + +#define FFI_VERSION_STRING "3.7.1" +#define FFI_VERSION_NUMBER 30701 + +#ifndef LIBFFI_ASM +/* Return a version string. */ +FFI_API const char *ffi_get_version (void); + +/* Return the version as an unsigned long value: (x * 10000 + y * 100 + z) */ +FFI_API unsigned long ffi_get_version_number (void); +#endif + +/* ---- Internals API ---------------------------------------------------- */ + +FFI_API unsigned int ffi_get_default_abi (void); +FFI_API size_t ffi_get_closure_size (void); /* ---- Definitions for closures ----------------------------------------- */ @@ -310,11 +352,22 @@ typedef struct { void *trampoline_table; void *trampoline_table_entry; #else - char tramp[FFI_TRAMPOLINE_SIZE]; + /* Anonymous unions are C11 (a GNU extension in C99); __extension__ keeps + the field names without tripping -Wpedantic under -std=c99 (#795). */ +#ifdef __GNUC__ + __extension__ +#endif + union { + char tramp[FFI_TRAMPOLINE_SIZE]; + void *ftramp; + }; #endif ffi_cif *cif; void (*fun)(ffi_cif*,void*,void**,void*); void *user_data; +#if defined(_MSC_VER) && defined(_M_IX86) + void *padding; +#endif } ffi_closure #ifdef __GNUC__ __attribute__((aligned (8))) @@ -347,7 +400,7 @@ ffi_prep_closure_loc (ffi_closure*, ffi_cif *, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data, - void*codeloc); + void *codeloc); #ifdef __sgi # pragma pack 8 @@ -365,7 +418,7 @@ typedef struct { /* If this is enabled, then a raw closure has the same layout as a regular closure. We use this to install an intermediate - handler to do the transaltion, void** -> ffi_raw*. */ + handler to do the translation, void** -> ffi_raw*. */ void (*translate_args)(ffi_cif*,void*,void**,void*); void *this_closure; @@ -421,19 +474,19 @@ FFI_API ffi_status ffi_prep_java_raw_closure (ffi_java_raw_closure*, ffi_cif *cif, void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), - void *user_data); + void *user_data) __attribute__((deprecated)); FFI_API ffi_status ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*, ffi_cif *cif, void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data, - void *codeloc); + void *codeloc) __attribute__((deprecated)); #endif #endif /* FFI_CLOSURES */ -#if FFI_GO_CLOSURES +#ifdef FFI_GO_CLOSURES typedef struct { void *tramp; @@ -472,49 +525,47 @@ void ffi_call(ffi_cif *cif, void *rvalue, void **avalue); +/* Reusable call plans. + + A plan captures a signature's argument placement once so that repeated + calls skip the per-call work that ffi_call would otherwise redo. Build one + with ffi_call_plan_alloc, invoke it as many times as you like, and release + it with ffi_call_plan_free. + + The plan is opaque and caller-owned. The cif must outlive the plan. + ffi_call_plan_alloc returns NULL only on allocation failure; a signature + with no fast path is still valid and ffi_call_plan_invoke falls back to + ffi_call for it. A plan is immutable once built, so it may be shared and + invoked concurrently from multiple threads. */ +typedef struct ffi_call_plan ffi_call_plan; + FFI_API -ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, - size_t *offsets); +ffi_call_plan *ffi_call_plan_alloc (ffi_cif *cif); -/* Useful for eliminating compiler warnings. */ -#define FFI_FN(f) ((void (*)(void))f) +FFI_API +void ffi_call_plan_invoke (ffi_call_plan *plan, + void (*fn)(void), + void *rvalue, + void **avalue); -/* ---- Definitions shared with assembly code ---------------------------- */ +FFI_API +void ffi_call_plan_free (ffi_call_plan *plan); -#endif +FFI_API +ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, + size_t *offsets); -/* If these change, update src/mips/ffitarget.h. */ -#define FFI_TYPE_VOID 0 -#define FFI_TYPE_INT 1 -#define FFI_TYPE_FLOAT 2 -#define FFI_TYPE_DOUBLE 3 -#if 0 -#define FFI_TYPE_LONGDOUBLE 4 +/* Convert between closure and function pointers. */ +#if defined(PA_LINUX) || defined(PA_HPUX) +#define FFI_FN(f) ((void (*)(void))((unsigned int)(f) | 2)) +#define FFI_CL(f) ((void *)((unsigned int)(f) & ~3)) #else -#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE -#endif -#define FFI_TYPE_UINT8 5 -#define FFI_TYPE_SINT8 6 -#define FFI_TYPE_UINT16 7 -#define FFI_TYPE_SINT16 8 -#define FFI_TYPE_UINT32 9 -#define FFI_TYPE_SINT32 10 -#define FFI_TYPE_UINT64 11 -#define FFI_TYPE_SINT64 12 -#define FFI_TYPE_STRUCT 13 -#define FFI_TYPE_POINTER 14 -#define FFI_TYPE_COMPLEX 15 -#if 1 -#define FFI_TYPE_EXT_VECTOR 16 -#else -#define FFI_TYPE_EXT_VECTOR FFI_TYPE_STRUCT +#define FFI_FN(f) ((void (*)(void))f) +#define FFI_CL(f) ((void *)(f)) #endif -/* This should always refer to the last type code (for sanity checks). */ -#if 1 -#define FFI_TYPE_LAST FFI_TYPE_EXT_VECTOR -#else -#define FFI_TYPE_LAST FFI_TYPE_COMPLEX +/* ---- Definitions shared with assembly code ---------------------------- */ + #endif #ifdef __cplusplus diff --git a/NativeScript/include/libffi/arm64/ffitarget.h b/NativeScript/include/libffi/arm64/ffitarget.h index ecb6d2de..8ba86799 100644 --- a/NativeScript/include/libffi/arm64/ffitarget.h +++ b/NativeScript/include/libffi/arm64/ffitarget.h @@ -32,7 +32,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define FFI_SIZEOF_JAVA_RAW 4 typedef unsigned long long ffi_arg; typedef signed long long ffi_sarg; -#elif defined(_M_ARM64) +#elif defined(_WIN32) #define FFI_SIZEOF_ARG 8 typedef unsigned long long ffi_arg; typedef signed long long ffi_sarg; @@ -45,8 +45,13 @@ typedef enum ffi_abi { FFI_FIRST_ABI = 0, FFI_SYSV, + FFI_WIN64, FFI_LAST_ABI, +#if defined(_WIN32) + FFI_DEFAULT_ABI = FFI_WIN64 +#else FFI_DEFAULT_ABI = FFI_SYSV +#endif } ffi_abi; #endif @@ -69,24 +74,30 @@ typedef enum ffi_abi #define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE #endif -#ifdef _M_ARM64 +#ifdef _WIN32 #define FFI_EXTRA_CIF_FIELDS unsigned is_variadic #endif +#define FFI_TARGET_SPECIFIC_VARIADIC /* ---- Internal ---- */ #if defined (__APPLE__) -#define FFI_TARGET_SPECIFIC_VARIADIC #define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs -#elif !defined(_M_ARM64) -/* iOS and Windows reserve x18 for the system. Disable Go closures until +#elif !defined(_WIN32) && !defined(__ANDROID__) +/* iOS, Windows and Android reserve x18 for the system. Disable Go closures until a new static chain is chosen. */ #define FFI_GO_CLOSURES 1 #endif -#ifndef _M_ARM64 +#ifndef _WIN32 /* No complex type on Windows */ #define FFI_TARGET_HAS_COMPLEX_TYPE #endif +/* AAPCS64 passes 8- and 16-byte vectors in V/Q registers and homogeneous + vector aggregates in consecutive V/Q registers; see is_vfp_type. */ +#define FFI_TARGET_HAS_VECTOR_TYPE + +#define FFI_TARGET_HAS_INT128 1 + #endif diff --git a/NativeScript/include/libffi/x86_64/ffi.h b/NativeScript/include/libffi/x86_64/ffi.h index 0cb32bf1..07044832 100644 --- a/NativeScript/include/libffi/x86_64/ffi.h +++ b/NativeScript/include/libffi/x86_64/ffi.h @@ -1,6 +1,7 @@ /* -----------------------------------------------------------------*-C-*- - libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green - - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc. + libffi 3.7.1 + - Copyright (c) 2011, 2014, 2019, 2021, 2022, 2024, 2025, 2026 Anthony Green + - Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -55,6 +56,34 @@ extern "C" { /* ---- System configuration information --------------------------------- */ +/* If these change, update src/mips/ffitarget.h. */ +#define FFI_TYPE_VOID 0 +#define FFI_TYPE_INT 1 +#define FFI_TYPE_FLOAT 2 +#define FFI_TYPE_DOUBLE 3 +#if 1 +#define FFI_TYPE_LONGDOUBLE 4 +#else +#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE +#endif +#define FFI_TYPE_UINT8 5 +#define FFI_TYPE_SINT8 6 +#define FFI_TYPE_UINT16 7 +#define FFI_TYPE_SINT16 8 +#define FFI_TYPE_UINT32 9 +#define FFI_TYPE_SINT32 10 +#define FFI_TYPE_UINT64 11 +#define FFI_TYPE_SINT64 12 +#define FFI_TYPE_STRUCT 13 +#define FFI_TYPE_POINTER 14 +#define FFI_TYPE_COMPLEX 15 +#define FFI_TYPE_UINT128 16 +#define FFI_TYPE_SINT128 17 +#define FFI_TYPE_VECTOR 18 + +/* This should always refer to the last type code (for sanity checks). */ +#define FFI_TYPE_LAST FFI_TYPE_VECTOR + #include "ffitarget.h" #ifndef LIBFFI_ASM @@ -114,13 +143,11 @@ typedef struct _ffi_type when using the static version of the library. Besides, as a workaround, they can define FFI_BUILDING if they *know* they are going to link with the static library. */ -#if defined _MSC_VER +#if defined _MSC_VER && !defined(FFI_STATIC_BUILD) # if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */ # define FFI_API __declspec(dllexport) -# elif !defined FFI_BUILDING /* Importing libffi.DLL */ +# else /* Importing libffi.DLL */ # define FFI_API __declspec(dllimport) -# else /* Building/linking static library */ -# define FFI_API # endif #else # define FFI_API @@ -196,28 +223,25 @@ FFI_EXTERN ffi_type ffi_type_sint64; FFI_EXTERN ffi_type ffi_type_float; FFI_EXTERN ffi_type ffi_type_double; FFI_EXTERN ffi_type ffi_type_pointer; - -#if 1 FFI_EXTERN ffi_type ffi_type_longdouble; -#else -#define ffi_type_longdouble ffi_type_double -#endif #ifdef FFI_TARGET_HAS_COMPLEX_TYPE FFI_EXTERN ffi_type ffi_type_complex_float; FFI_EXTERN ffi_type ffi_type_complex_double; -#if 1 FFI_EXTERN ffi_type ffi_type_complex_longdouble; -#else -#define ffi_type_complex_longdouble ffi_type_complex_double #endif + +#ifdef FFI_TARGET_HAS_INT128 +FFI_EXTERN ffi_type ffi_type_uint128; +FFI_EXTERN ffi_type ffi_type_sint128; #endif #endif /* LIBFFI_HIDE_BASIC_TYPES */ typedef enum { FFI_OK = 0, FFI_BAD_TYPEDEF, - FFI_BAD_ABI + FFI_BAD_ABI, + FFI_BAD_ARGTYPE } ffi_status; typedef struct { @@ -288,15 +312,33 @@ FFI_API void ffi_java_raw_call (ffi_cif *cif, void (*fn)(void), void *rvalue, - ffi_java_raw *avalue); + ffi_java_raw *avalue) __attribute__((deprecated)); #endif FFI_API -void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw); +void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) __attribute__((deprecated)); FFI_API -void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args); +void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) __attribute__((deprecated)); FFI_API -size_t ffi_java_raw_size (ffi_cif *cif); +size_t ffi_java_raw_size (ffi_cif *cif) __attribute__((deprecated)); + +/* ---- Version API ------------------------------------------------------ */ + +#define FFI_VERSION_STRING "3.7.1" +#define FFI_VERSION_NUMBER 30701 + +#ifndef LIBFFI_ASM +/* Return a version string. */ +FFI_API const char *ffi_get_version (void); + +/* Return the version as an unsigned long value: (x * 10000 + y * 100 + z) */ +FFI_API unsigned long ffi_get_version_number (void); +#endif + +/* ---- Internals API ---------------------------------------------------- */ + +FFI_API unsigned int ffi_get_default_abi (void); +FFI_API size_t ffi_get_closure_size (void); /* ---- Definitions for closures ----------------------------------------- */ @@ -310,11 +352,22 @@ typedef struct { void *trampoline_table; void *trampoline_table_entry; #else - char tramp[FFI_TRAMPOLINE_SIZE]; + /* Anonymous unions are C11 (a GNU extension in C99); __extension__ keeps + the field names without tripping -Wpedantic under -std=c99 (#795). */ +#ifdef __GNUC__ + __extension__ +#endif + union { + char tramp[FFI_TRAMPOLINE_SIZE]; + void *ftramp; + }; #endif ffi_cif *cif; void (*fun)(ffi_cif*,void*,void**,void*); void *user_data; +#if defined(_MSC_VER) && defined(_M_IX86) + void *padding; +#endif } ffi_closure #ifdef __GNUC__ __attribute__((aligned (8))) @@ -347,7 +400,7 @@ ffi_prep_closure_loc (ffi_closure*, ffi_cif *, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data, - void*codeloc); + void *codeloc); #ifdef __sgi # pragma pack 8 @@ -365,7 +418,7 @@ typedef struct { /* If this is enabled, then a raw closure has the same layout as a regular closure. We use this to install an intermediate - handler to do the transaltion, void** -> ffi_raw*. */ + handler to do the translation, void** -> ffi_raw*. */ void (*translate_args)(ffi_cif*,void*,void**,void*); void *this_closure; @@ -421,19 +474,19 @@ FFI_API ffi_status ffi_prep_java_raw_closure (ffi_java_raw_closure*, ffi_cif *cif, void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), - void *user_data); + void *user_data) __attribute__((deprecated)); FFI_API ffi_status ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*, ffi_cif *cif, void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data, - void *codeloc); + void *codeloc) __attribute__((deprecated)); #endif #endif /* FFI_CLOSURES */ -#if FFI_GO_CLOSURES +#ifdef FFI_GO_CLOSURES typedef struct { void *tramp; @@ -472,49 +525,47 @@ void ffi_call(ffi_cif *cif, void *rvalue, void **avalue); +/* Reusable call plans. + + A plan captures a signature's argument placement once so that repeated + calls skip the per-call work that ffi_call would otherwise redo. Build one + with ffi_call_plan_alloc, invoke it as many times as you like, and release + it with ffi_call_plan_free. + + The plan is opaque and caller-owned. The cif must outlive the plan. + ffi_call_plan_alloc returns NULL only on allocation failure; a signature + with no fast path is still valid and ffi_call_plan_invoke falls back to + ffi_call for it. A plan is immutable once built, so it may be shared and + invoked concurrently from multiple threads. */ +typedef struct ffi_call_plan ffi_call_plan; + FFI_API -ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, - size_t *offsets); +ffi_call_plan *ffi_call_plan_alloc (ffi_cif *cif); -/* Useful for eliminating compiler warnings. */ -#define FFI_FN(f) ((void (*)(void))f) +FFI_API +void ffi_call_plan_invoke (ffi_call_plan *plan, + void (*fn)(void), + void *rvalue, + void **avalue); -/* ---- Definitions shared with assembly code ---------------------------- */ +FFI_API +void ffi_call_plan_free (ffi_call_plan *plan); -#endif +FFI_API +ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type, + size_t *offsets); -/* If these change, update src/mips/ffitarget.h. */ -#define FFI_TYPE_VOID 0 -#define FFI_TYPE_INT 1 -#define FFI_TYPE_FLOAT 2 -#define FFI_TYPE_DOUBLE 3 -#if 1 -#define FFI_TYPE_LONGDOUBLE 4 +/* Convert between closure and function pointers. */ +#if defined(PA_LINUX) || defined(PA_HPUX) +#define FFI_FN(f) ((void (*)(void))((unsigned int)(f) | 2)) +#define FFI_CL(f) ((void *)((unsigned int)(f) & ~3)) #else -#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE -#endif -#define FFI_TYPE_UINT8 5 -#define FFI_TYPE_SINT8 6 -#define FFI_TYPE_UINT16 7 -#define FFI_TYPE_SINT16 8 -#define FFI_TYPE_UINT32 9 -#define FFI_TYPE_SINT32 10 -#define FFI_TYPE_UINT64 11 -#define FFI_TYPE_SINT64 12 -#define FFI_TYPE_STRUCT 13 -#define FFI_TYPE_POINTER 14 -#define FFI_TYPE_COMPLEX 15 -#if 1 -#define FFI_TYPE_EXT_VECTOR 16 -#else -#define FFI_TYPE_EXT_VECTOR FFI_TYPE_STRUCT +#define FFI_FN(f) ((void (*)(void))f) +#define FFI_CL(f) ((void *)(f)) #endif -/* This should always refer to the last type code (for sanity checks). */ -#if 1 -#define FFI_TYPE_LAST FFI_TYPE_EXT_VECTOR -#else -#define FFI_TYPE_LAST FFI_TYPE_COMPLEX +/* ---- Definitions shared with assembly code ---------------------------- */ + #endif #ifdef __cplusplus diff --git a/NativeScript/include/libffi/x86_64/ffitarget.h b/NativeScript/include/libffi/x86_64/ffitarget.h index 85ccedfe..734ac955 100644 --- a/NativeScript/include/libffi/x86_64/ffitarget.h +++ b/NativeScript/include/libffi/x86_64/ffitarget.h @@ -1,5 +1,5 @@ /* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green + ffitarget.h - Copyright (c) 2012, 2014, 2018, 2026 Anthony Green Copyright (c) 1996-2003, 2010 Red Hat, Inc. Copyright (C) 2008 Free Software Foundation, Inc. @@ -54,6 +54,17 @@ #define FFI_TARGET_HAS_COMPLEX_TYPE #endif +#ifdef X86_64 +#define FFI_TARGET_HAS_INT128 +#endif + +/* The System V x86-64 psABI passes 8- and 16-byte vectors in SSE registers; + this is implemented by the ffi64.c (FFI_UNIX64) backend only. 32-bit x86 + and the Windows x86-64 backend (ffiw64.c) do not marshal vectors. */ +#if defined(X86_64) && !defined(X86_WIN64) +#define FFI_TARGET_HAS_VECTOR_TYPE +#endif + /* ---- Generic type definitions ----------------------------------------- */ #ifndef LIBFFI_ASM @@ -85,9 +96,9 @@ typedef enum ffi_abi { FFI_LAST_ABI, #ifdef __GNUC__ FFI_DEFAULT_ABI = FFI_GNUW64 -#else +#else FFI_DEFAULT_ABI = FFI_WIN64 -#endif +#endif #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) FFI_FIRST_ABI = 1, @@ -136,12 +147,26 @@ typedef enum ffi_abi { #if defined (X86_64) || defined(X86_WIN64) \ || (defined (__x86_64__) && defined (X86_DARWIN)) -# define FFI_TRAMPOLINE_SIZE 24 +/* 4 bytes of ENDBR64 + 7 bytes of LEA + 6 bytes of JMP + 7 bytes of NOP + + 8 bytes of pointer. */ +# define FFI_TRAMPOLINE_SIZE 32 # define FFI_NATIVE_RAW_API 0 #else -# define FFI_TRAMPOLINE_SIZE 12 +/* 4 bytes of ENDBR32 + 5 bytes of MOV + 5 bytes of JMP + 2 unused + bytes. */ +# define FFI_TRAMPOLINE_SIZE 16 # define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ #endif +#if !defined(GENERATE_LIBFFI_MAP) && defined(__CET__) +# include +# if (__CET__ & 1) != 0 +# define ENDBR_PRESENT +# endif +# define _CET_NOTRACK notrack +#else +# define _CET_ENDBR +# define _CET_NOTRACK #endif +#endif diff --git a/NativeScript/lib/arm64-iphoneos/libffi.a b/NativeScript/lib/arm64-iphoneos/libffi.a index 107d04c9..6243c781 100644 Binary files a/NativeScript/lib/arm64-iphoneos/libffi.a and b/NativeScript/lib/arm64-iphoneos/libffi.a differ diff --git a/NativeScript/lib/arm64-iphonesimulator/libffi.a b/NativeScript/lib/arm64-iphonesimulator/libffi.a index 45f9cbf3..65011a74 100644 Binary files a/NativeScript/lib/arm64-iphonesimulator/libffi.a and b/NativeScript/lib/arm64-iphonesimulator/libffi.a differ diff --git a/NativeScript/lib/arm64-xros/libffi.a b/NativeScript/lib/arm64-xros/libffi.a index 107d04c9..79cbbb77 100644 Binary files a/NativeScript/lib/arm64-xros/libffi.a and b/NativeScript/lib/arm64-xros/libffi.a differ diff --git a/NativeScript/lib/arm64-xrsimulator/libffi.a b/NativeScript/lib/arm64-xrsimulator/libffi.a index 45f9cbf3..90ed3817 100644 Binary files a/NativeScript/lib/arm64-xrsimulator/libffi.a and b/NativeScript/lib/arm64-xrsimulator/libffi.a differ diff --git a/NativeScript/lib/x86_64-iphonesimulator/libffi.a b/NativeScript/lib/x86_64-iphonesimulator/libffi.a index 4e87cb77..4823c0cc 100644 Binary files a/NativeScript/lib/x86_64-iphonesimulator/libffi.a and b/NativeScript/lib/x86_64-iphonesimulator/libffi.a differ diff --git a/NativeScript/lib/x86_64-maccatalyst/libffi.a b/NativeScript/lib/x86_64-maccatalyst/libffi.a index 9a796054..b9d57440 100644 Binary files a/NativeScript/lib/x86_64-maccatalyst/libffi.a and b/NativeScript/lib/x86_64-maccatalyst/libffi.a differ diff --git a/NativeScript/runtime/FFICall.cpp b/NativeScript/runtime/FFICall.cpp index a1cbe815..ce235b63 100644 --- a/NativeScript/runtime/FFICall.cpp +++ b/NativeScript/runtime/FFICall.cpp @@ -71,25 +71,24 @@ ffi_type* FFICall::GetArgumentType(const TypeEncoding* typeEncoding, bool isStru } case BinaryTypeEncodingType::ExtVectorEncoding: { size_t size = typeEncoding->details.extVector.size; -#if defined(__x86_64__) - // We need isStructMember because double3 vectors are handled - // differently in x86_64. When a vector is a struct field - // it is passed in memory but when not - the ST0 register is - // used for the third element. In armv8 double3 vector will always - // be passed in memory (as it's size > 16). - if (size == 3 && isStructMember) { -#else - // For armv8 we always need to pass the array size - // as the vector would fill a whole register in order - // to calculate the proper flags value. - if (size == 3) { -#endif - size = 4; - } - + // Vector API (FFI_TYPE_VECTOR): describe the true lane count; + // ffi_prep_cif computes the layout for size == 0 types. The + // runtime also reads ffi_type.size standalone (result marshaling + // mallocs/memcpys by it before any cif exists), so prefill + // size/alignment with the exact values libffi's initialize_vector + // derives — prep_cif honors prefilled aggregates (same convention + // as structs): size = lanes * lane_size rounded up to a power of + // two, alignment = min(size, 16). const TypeEncoding* innerType = typeEncoding->details.extVector.getInnerType(); ffi_type* innerFFIType = FFICall::GetArgumentType(innerType, isStructMember); - ffi_type* type = new ffi_type({ .size = size * innerFFIType->size, .alignment = innerFFIType->alignment, .type = FFI_TYPE_EXT_VECTOR }); + size_t vecSize = size * innerFFIType->size; + size_t p2 = 1; + while (p2 < vecSize) { + p2 <<= 1; + } + ffi_type* type = new ffi_type({ .size = p2, + .alignment = static_cast(p2 < 16 ? p2 : 16), + .type = FFI_TYPE_VECTOR }); type->elements = new ffi_type*[size + 1]; if (size > 0) { diff --git a/TestRunner/app/tests/index.js b/TestRunner/app/tests/index.js index 98e030cb..d8971960 100644 --- a/TestRunner/app/tests/index.js +++ b/TestRunner/app/tests/index.js @@ -48,8 +48,7 @@ require("./Marshalling/ObjCTypesTests"); require("./Marshalling/ConstantsTests"); require("./Marshalling/RecordTests"); require("./Marshalling/VectorTests"); -// todo: figure out why this test is failing with a EXC_BAD_ACCESS on TNSRecords.m matrix initialization -// require("./Marshalling/MatrixTests"); +require("./Marshalling/MatrixTests"); require("./Marshalling/NSStringTests"); //import "./Marshalling/TypesTests"; require("./Marshalling/PointerTests"); diff --git a/build_libffi.sh b/build_libffi.sh index 3b8a8932..45545ece 100755 --- a/build_libffi.sh +++ b/build_libffi.sh @@ -1,66 +1,178 @@ #!/bin/bash -set -e - -pushd libffi - -./autogen.sh - -OUTPUT_DIR=./dist -OUTPUT_ARM64=$OUTPUT_DIR/arm64-iphoneos -OUTPUT_ARM64_SIMULATOR=$OUTPUT_DIR/arm64-iphonesimulator -OUTPUT_X86_64_SIMULATOR=$OUTPUT_DIR/x86_64-iphonesimulator -OUTPUT_X86_64_MACCATALYST=$OUTPUT_DIR/x86_64-maccatalyst - -rm -rf $OUTPUT_DIR -mkdir -p $OUTPUT_ARM64 -mkdir -p $OUTPUT_X86_64_SIMULATOR -mkdir -p $OUTPUT_X86_64_MACCATALYST - -ARM64_OUT="aarch64-apple-darwin13" -export CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch arm64 -fembed-bitcode -miphoneos-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" -export CXX="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch arm64 -fembed-bitcode -miphoneos-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" -./configure --disable-shared --host="$ARM64_OUT" -make -mkdir -p $OUTPUT_ARM64/lib -ar r $OUTPUT_ARM64/lib/libffi.a ./$ARM64_OUT/src/*.o ./$ARM64_OUT/src/aarch64/*.o -cp -r $ARM64_OUT/include $OUTPUT_ARM64 -rm -rf $ARM64_OUT - -ARM64_SIMULATOR_OUT="aarch64-apple-darwin13" -export CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch arm64 -fembed-bitcode -mios-simulator-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk" -export CXX="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch arm64 -fembed-bitcode -mios-simulator-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk" -./configure --disable-shared --host="$ARM64_SIMULATOR_OUT" -make -mkdir -p $OUTPUT_ARM64_SIMULATOR/lib -ar r $OUTPUT_ARM64_SIMULATOR/lib/libffi.a ./$ARM64_SIMULATOR_OUT/src/*.o ./$ARM64_SIMULATOR_OUT/src/aarch64/*.o -cp -r $ARM64_SIMULATOR_OUT/include $OUTPUT_ARM64_SIMULATOR -rm -rf $ARM64_SIMULATOR_OUT - -#ARM_OUT="armv7-apple-darwin13" -#export CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch armv7 -fembed-bitcode -miphoneos-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" -#export CXX="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch armv7 -fembed-bitcode -miphoneos-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk" -#./configure --disable-shared --host="$ARM_OUT" -#make -#ar r ./$ARM_OUT/libffi.a ./$ARM_OUT/src/*.o ./$ARM_OUT/src/arm/*.o - -X86_64_OUT="x86_64-apple-darwin13" -export CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -fembed-bitcode-marker -mios-simulator-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk" -export CXX="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -fembed-bitcode-marker -mios-simulator-version-min=9.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk" -./configure --disable-shared --host="$X86_64_OUT" -make -mkdir -p $OUTPUT_X86_64_SIMULATOR/lib -ar r $OUTPUT_X86_64_SIMULATOR/lib/libffi.a ./$X86_64_OUT/src/*.o ./$X86_64_OUT/src/x86/*.o -cp -r $X86_64_OUT/include $OUTPUT_X86_64_SIMULATOR -rm -rf $X86_64_OUT - -X86_64_CATALYST_OUT="x86_64-apple-darwin13" -export CC="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -target x86_64-apple-ios13.3-macabi -miphoneos-version-min=13.3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" -export CXX="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -target x86_64-apple-ios13.3-macabi -miphoneos-version-min=13.3 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" -./configure --disable-shared --host="$X86_64_CATALYST_OUT" -make -mkdir -p $OUTPUT_X86_64_MACCATALYST/lib -ar r $OUTPUT_X86_64_MACCATALYST/lib/libffi.a ./$X86_64_CATALYST_OUT/src/*.o ./$X86_64_CATALYST_OUT/src/x86/*.o -cp -r $X86_64_CATALYST_OUT/include $OUTPUT_X86_64_MACCATALYST -rm -rf $X86_64_CATALYST_OUT - -popd \ No newline at end of file +set -euo pipefail + +# Builds static libffi slices from the ./libffi submodule for every platform +# the runtime ships, using the currently selected Xcode (xcode-select / +# DEVELOPER_DIR) instead of hardcoded /Applications/Xcode.app paths. +# +# Builds run out-of-tree under build/libffi/ (gitignored) so the libffi +# submodule stays clean. Artifacts land in build/libffi/dist// +# {lib/libffi.a,include}. With --install they are also copied into +# NativeScript/lib// and NativeScript/include/libffi// (the +# vendored locations the Xcode project links against). +# +# Note: all slices build from the same libffi source. On x86_64 the vector +# (SIMD) support caps at 16-byte vectors — wider vectors are rejected with +# FFI_BAD_TYPEDEF at prep time (documented libffi port limitation). + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +LIBFFI_DIR="$SCRIPT_DIR/libffi" +BUILD_ROOT="$SCRIPT_DIR/build/libffi" +DIST_DIR="$BUILD_ROOT/dist" + +ALL_SLICES=( + arm64-iphoneos + arm64-iphonesimulator + arm64-xros + arm64-xrsimulator + x86_64-iphonesimulator + x86_64-maccatalyst +) + +IOS_MIN=13.0 +XROS_MIN=2.0 +CATALYST_MIN=13.3 + +usage() { + cat </ and NativeScript/include/libffi// + --jobs N parallel make jobs (default: number of CPUs) + -h, --help show this help +EOF +} + +INSTALL=0 +JOBS="$(sysctl -n hw.ncpu)" +SLICES=() + +while [[ $# -gt 0 ]]; do + case "$1" in + --install) + INSTALL=1 + ;; + --jobs) + shift + if [ $# -eq 0 ] || ! [[ "$1" =~ ^[0-9]+$ ]]; then + echo "--jobs requires a numeric argument" >&2 + usage + exit 1 + fi + JOBS="$1" + ;; + -h|--help) + usage + exit 0 + ;; + -*) + echo "Unknown option: $1" >&2 + usage + exit 1 + ;; + *) + SLICES+=("$1") + ;; + esac + shift +done + +if [ ${#SLICES[@]} -eq 0 ]; then + SLICES=("${ALL_SLICES[@]}") +fi + +CLANG="$(xcrun -f clang)" +CLANGXX="$(xcrun -f clang++)" + +# slice -> "sdk|host triple|target cflags" +slice_config() { + case "$1" in + arm64-iphoneos) + echo "iphoneos|aarch64-apple-darwin|-arch arm64 -miphoneos-version-min=$IOS_MIN" + ;; + arm64-iphonesimulator) + echo "iphonesimulator|aarch64-apple-darwin|-arch arm64 -mios-simulator-version-min=$IOS_MIN" + ;; + arm64-xros) + echo "xros|aarch64-apple-darwin|-target arm64-apple-xros$XROS_MIN" + ;; + arm64-xrsimulator) + echo "xrsimulator|aarch64-apple-darwin|-target arm64-apple-xros$XROS_MIN-simulator" + ;; + x86_64-iphonesimulator) + echo "iphonesimulator|x86_64-apple-darwin|-arch x86_64 -mios-simulator-version-min=$IOS_MIN" + ;; + x86_64-maccatalyst) + echo "macosx|x86_64-apple-darwin|-target x86_64-apple-ios$CATALYST_MIN-macabi" + ;; + *) + echo "" + ;; + esac +} + +for slice in "${SLICES[@]}"; do + if [ -z "$(slice_config "$slice")" ]; then + echo "Unknown slice: $slice (known: ${ALL_SLICES[*]})" >&2 + exit 1 + fi +done + +pushd "$LIBFFI_DIR" >/dev/null +# Regenerate the build system so a submodule bump can never pair stale +# configure output with new sources. macOS installs GNU libtoolize as +# glibtoolize (via Homebrew). +LIBTOOLIZE="${LIBTOOLIZE:-glibtoolize}" ./autogen.sh +popd >/dev/null + +rm -rf "$DIST_DIR" + +for slice in "${SLICES[@]}"; do + IFS='|' read -r sdk host target_cflags <<< "$(slice_config "$slice")" + sdk_path="$(xcrun --sdk "$sdk" --show-sdk-path)" + build_dir="$BUILD_ROOT/build-$slice" + out_dir="$DIST_DIR/$slice" + + echo "==> $slice (sdk: $(basename "$sdk_path"))" + + rm -rf "$build_dir" + mkdir -p "$build_dir" "$out_dir/lib" "$out_dir/include" + + pushd "$build_dir" >/dev/null + CC="$CLANG $target_cflags -isysroot $sdk_path" \ + CXX="$CLANGXX $target_cflags -isysroot $sdk_path" \ + "$LIBFFI_DIR/configure" --disable-shared --disable-docs --host="$host" >/dev/null + + make -j"$JOBS" >/dev/null + + cp .libs/libffi.a "$out_dir/lib/libffi.a" + cp include/ffi.h include/ffitarget.h "$out_dir/include/" + popd >/dev/null + + rm -rf "$build_dir" +done + +if [ "$INSTALL" -eq 1 ]; then + for slice in "${SLICES[@]}"; do + arch="${slice%%-*}" + echo "==> installing $slice" + mkdir -p "$SCRIPT_DIR/NativeScript/lib/$slice" "$SCRIPT_DIR/NativeScript/include/libffi/$arch" + cp "$DIST_DIR/$slice/lib/libffi.a" "$SCRIPT_DIR/NativeScript/lib/$slice/libffi.a" + # The generated headers are identical for every slice of the same arch. + cp "$DIST_DIR/$slice/include/ffi.h" "$DIST_DIR/$slice/include/ffitarget.h" \ + "$SCRIPT_DIR/NativeScript/include/libffi/$arch/" + # Upstream ffi.h includes its sibling with angle brackets, which only + # resolves in Xcode via basename headermaps — ambiguous with two arch + # copies of ffitarget.h in the project. Use a quoted include so each + # ffi.h deterministically picks up the ffitarget.h next to it. + sed -i '' 's|#include |#include "ffitarget.h"|' \ + "$SCRIPT_DIR/NativeScript/include/libffi/$arch/ffi.h" + done +fi + +echo "Done. Artifacts in $DIST_DIR" diff --git a/libffi b/libffi index 5f28db3e..71a95a2c 160000 --- a/libffi +++ b/libffi @@ -1 +1 @@ -Subproject commit 5f28db3ee282b130f04776638f2ba7b890c3169d +Subproject commit 71a95a2cd433b151b3fcf83a0a830eb9aa38fa3a