Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 37ec97e

Browse files
committed
[[ Bug 20411 ]] Correct call to objc_msgSend
Whilst 'objc_msgSend' and friends are declared as variadic, they aren't actually variadic functions. The objc_msgSend functions forward the call to the appropriate message, meaning that they must be called with the prototype of the message and not variadically. This difference was not seen on x86 processors where the difference between variadic and non-variadic functions is much less; on ARM however there is a significant difference, resulting in the obj-c FFI not working in many cases on iOS devices.
1 parent b8ee853 commit 37ec97e

File tree

3 files changed

+9
-5
lines changed

3 files changed

+9
-5
lines changed

docs/notes/bugfix-20411.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Fix crash when using Obj-C FFI on iOS

libscript/src/script-execute.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ class MCScriptForeignInvocation
268268
/* There are different variants of objc_msgSend we need to use
269269
* depending on architecture and return type:
270270
* struct return
271-
* all: _stret
271+
* all but arm64: _stret
272272
* float return
273273
* arm: no difference
274274
* i386: _fpret
@@ -289,7 +289,9 @@ class MCScriptForeignInvocation
289289

290290
ffi_cif *t_cif = (ffi_cif *)p_handler->objc.function_cif;
291291
void (*t_objc_msgSend)() = nullptr;
292-
#if defined(__ARM__)
292+
#if defined(__ARM64__)
293+
t_objc_msgSend = (void(*)())objc_msgSend;
294+
#elif defined(__ARM__)
293295
if (t_cif->rtype->type == FFI_TYPE_STRUCT)
294296
t_objc_msgSend = (void(*)())objc_msgSend_stret;
295297
else
@@ -310,12 +312,14 @@ class MCScriptForeignInvocation
310312
t_objc_msgSend = (void(*)())objc_msgSend_fpret;
311313
else
312314
t_objc_msgSend = (void(*)())objc_msgSend;
315+
#else
316+
#error unknown architecture for objc_msgSend
313317
#endif
314318
/* We must use a wrapper function written in an obj-c++ source file so that
315319
* we can capture any obj-c exceptions. */
316320
extern bool MCScriptCallObjCCatchingErrors(ffi_cif*, void (*)(), void *, void **);
317321
return MCScriptCallObjCCatchingErrors(t_cif,
318-
(void(*)())objc_msgSend,
322+
t_objc_msgSend,
319323
p_result_slot_ptr,
320324
t_objc_values);
321325
#else

libscript/src/script-instance.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,9 +1147,8 @@ __MCScriptResolveForeignFunctionBindingForObjC(MCScriptInstanceRef p_instance,
11471147
* make. */
11481148
if (t_valid)
11491149
{
1150-
if (ffi_prep_cif_var(t_cif,
1150+
if (ffi_prep_cif(t_cif,
11511151
FFI_DEFAULT_ABI,
1152-
2,
11531152
t_arg_count,
11541153
t_cif_return_type,
11551154
t_cif_arg_types) != FFI_OK)

0 commit comments

Comments
 (0)