This repository has been archived by the owner on May 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
0001-FFI-add-nested-struct-support.patch
92 lines (86 loc) · 2.65 KB
/
0001-FFI-add-nested-struct-support.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
From a72506427efe00b1e56e7d8c651884da88c2916e Mon Sep 17 00:00:00 2001
From: Oraoto <[email protected]>
Date: Fri, 8 Feb 2019 15:36:34 +0800
Subject: [PATCH] FFI: add nested struct support
---
ext/ffi/ffi.c | 46 +++++++++++++++++++++++++++++-----------------
1 file changed, 29 insertions(+), 17 deletions(-)
diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c
index 1a8f866520..bcb02d75b8 100644
--- a/ext/ffi/ffi.c
+++ b/ext/ffi/ffi.c
@@ -273,17 +273,9 @@ static int zend_ffi_is_compatible_type(zend_ffi_type *dst_type, zend_ffi_type *s
}
/* }}} */
-static ffi_type *zend_ffi_make_fake_struct_type(zend_ffi_type *type) /* {{{ */
+static int zend_ffi_make_nested_struct_type(zend_ffi_type *type, ffi_type *t, int i) /* {{{ */
{
- ffi_type *t = emalloc(sizeof(ffi_type) + sizeof(ffi_type*) * (zend_hash_num_elements(&type->record.fields) + 1));
- int i;
zend_ffi_field *field;
-
- t->size = type->size;
- t->alignment = type->align;
- t->type = FFI_TYPE_STRUCT;
- t->elements = (ffi_type**)(t + 1);
- i = 0;
ZEND_HASH_FOREACH_PTR(&type->record.fields, field) {
switch (ZEND_FFI_TYPE(field->type)->kind) {
case ZEND_FFI_TYPE_FLOAT:
@@ -318,13 +310,34 @@ static ffi_type *zend_ffi_make_fake_struct_type(zend_ffi_type *type) /* {{{ */
case ZEND_FFI_TYPE_POINTER:
t->elements[i] = &ffi_type_pointer;
break;
+ case ZEND_FFI_TYPE_STRUCT:
+ i = zend_ffi_make_nested_struct_type(field->type, t, i) - 1;
+ break;
default:
- efree(t);
- zend_throw_error(zend_ffi_exception_ce, "Passing incompatible struct/union");
- return NULL;
+ return 0;
}
i++;
} ZEND_HASH_FOREACH_END();
+ return i;
+}
+/* }}} */
+
+static ffi_type *zend_ffi_make_fake_struct_type(zend_ffi_type *type) /* {{{ */
+{
+ ffi_type *t = emalloc(sizeof(ffi_type) + sizeof(ffi_type*) * (zend_hash_num_elements(&type->record.fields) + 1));
+ int i;
+
+ t->size = type->size;
+ t->alignment = type->align;
+ t->type = FFI_TYPE_STRUCT;
+ t->elements = (ffi_type**)(t + 1);
+ i = 0;
+ i = zend_ffi_make_nested_struct_type(type, t, i);
+ if (i == 0) {
+ efree(t);
+ zend_throw_error(zend_ffi_exception_ce, "Passing incompatible struct/union");
+ return NULL;
+ }
t->elements[i] = NULL;
return t;
}
@@ -2422,14 +2435,13 @@ static ZEND_FUNCTION(ffi_trampoline) /* {{{ */
}
ffi_call(&cif, addr, &ret, arg_values);
-
for (n = 0; n < arg_count; n++) {
- if (arg_types[n]->type == FFI_TYPE_STRUCT) {
- efree(arg_types[n]);
+ if (cif.arg_types[n]->type == FFI_TYPE_STRUCT) {
+ efree(cif.arg_types[n]);
}
}
- if (ret_type->type == FFI_TYPE_STRUCT) {
- efree(ret_type);
+ if (cif.rtype->type == FFI_TYPE_STRUCT) {
+ efree(cif.rtype);
}
if (EX_NUM_ARGS()) {
--
2.20.1