Skip to content

Commit af049d6

Browse files
committed
fix: use stret variant of msgSend on x86_64 when struct size > 16
1 parent 136bd9f commit af049d6

File tree

1 file changed

+40
-36
lines changed

1 file changed

+40
-36
lines changed

src/NativeCall.mm

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,43 @@
5050
return cif->returnType->toJS(env, rvalue);
5151
}
5252

53+
inline void objcNativeCall(napi_env env, napi_value jsThis, MethodCif *cif,
54+
id self, void **avalues, void *rvalue) {
55+
bool supercall;
56+
napi_has_named_property(env, jsThis, "__objc_msgSendSuper__", &supercall);
57+
58+
#if defined(x86_64)
59+
bool isStret = cif->returnType->type->size > 16 &&
60+
cif->returnType->type->type == FFI_TYPE_STRUCT;
61+
#endif
62+
63+
if (!supercall) {
64+
#if defined(x86_64)
65+
if (isStret) {
66+
cif->call((void *)objc_msgSend_stret, rvalue, avalues);
67+
} else {
68+
cif->call((void *)objc_msgSend, rvalue, avalues);
69+
}
70+
#else
71+
cif->call((void *)objc_msgSend, rvalue, avalues);
72+
#endif
73+
} else {
74+
struct objc_super superobj = {self,
75+
class_getSuperclass(object_getClass(self))};
76+
auto superobjPtr = &superobj;
77+
avalues[0] = (void *)&superobjPtr;
78+
#if defined(x86_64)
79+
if (isStret) {
80+
cif->call((void *)objc_msgSendSuper_stret, rvalue, avalues);
81+
} else {
82+
cif->call((void *)objc_msgSendSuper, rvalue, avalues);
83+
}
84+
#else
85+
cif->call((void *)objc_msgSendSuper, rvalue, avalues);
86+
#endif
87+
}
88+
}
89+
5390
NAPI_FUNCTION(BridgedMethod) {
5491
napi_value jsThis;
5592
BridgedMethod *method;
@@ -93,18 +130,7 @@
93130
}
94131
}
95132

96-
bool supercall;
97-
napi_has_named_property(env, jsThis, "__objc_msgSendSuper__", &supercall);
98-
99-
if (!supercall) {
100-
cif->call((void *)objc_msgSend, rvalue, avalues);
101-
} else {
102-
struct objc_super superobj = {self,
103-
class_getSuperclass(object_getClass(self))};
104-
auto superobjPtr = &superobj;
105-
avalues[0] = (void *)&superobjPtr;
106-
cif->call((void *)objc_msgSendSuper, rvalue, avalues);
107-
}
133+
objcNativeCall(env, jsThis, cif, self, avalues, rvalue);
108134

109135
for (unsigned int i = 0; i < cif->argc; i++) {
110136
if (shouldFree[i]) {
@@ -147,18 +173,7 @@
147173
avalues[0] = (void *)&self;
148174
avalues[1] = (void *)&method->selector;
149175

150-
bool supercall;
151-
napi_has_named_property(env, jsThis, "__objc_msgSendSuper__", &supercall);
152-
153-
if (!supercall) {
154-
cif->call((void *)objc_msgSend, rvalue, avalues);
155-
} else {
156-
struct objc_super superobj = {self,
157-
class_getSuperclass(object_getClass(self))};
158-
auto superobjPtr = &superobj;
159-
avalues[0] = (void *)&superobjPtr;
160-
cif->call((void *)objc_msgSendSuper, rvalue, avalues);
161-
}
176+
objcNativeCall(env, jsThis, cif, self, avalues, rvalue);
162177

163178
if (cif->returnType->kind == mdTypeInstanceObject) {
164179
napi_value constructor = jsThis;
@@ -198,18 +213,7 @@
198213
bool shouldFree = false;
199214
cif->argTypes[0]->toNative(env, argv, avalues[2], &shouldFree, &shouldFree);
200215

201-
bool supercall;
202-
napi_has_named_property(env, jsThis, "__objc_msgSendSuper__", &supercall);
203-
204-
if (!supercall) {
205-
cif->call((void *)objc_msgSend, rvalue, avalues);
206-
} else {
207-
struct objc_super superobj = {self,
208-
class_getSuperclass(object_getClass(self))};
209-
auto superobjPtr = &superobj;
210-
avalues[0] = (void *)&superobjPtr;
211-
cif->call((void *)objc_msgSendSuper, rvalue, avalues);
212-
}
216+
objcNativeCall(env, jsThis, cif, self, avalues, rvalue);
213217

214218
if (shouldFree) {
215219
cif->argTypes[0]->free(env, *((void **)avalues[2]));

0 commit comments

Comments
 (0)