@@ -293,15 +293,86 @@ static int zend_ffi_is_compatible_type(zend_ffi_type *dst_type, zend_ffi_type *s
293
293
}
294
294
/* }}} */
295
295
296
+ static ffi_type * zend_ffi_face_struct_add_fields (ffi_type * t , zend_ffi_type * type , int * i , size_t size )
297
+ {
298
+ zend_ffi_field * field ;
299
+
300
+ ZEND_HASH_FOREACH_PTR (& type -> record .fields , field ) {
301
+ switch (ZEND_FFI_TYPE (field -> type )-> kind ) {
302
+ case ZEND_FFI_TYPE_FLOAT :
303
+ t -> elements [(* i )++ ] = & ffi_type_float ;
304
+ break ;
305
+ case ZEND_FFI_TYPE_DOUBLE :
306
+ t -> elements [(* i )++ ] = & ffi_type_double ;
307
+ break ;
308
+ #ifdef HAVE_LONG_DOUBLE
309
+ case ZEND_FFI_TYPE_LONGDOUBLE :
310
+ t -> elements [(* i )++ ] = & ffi_type_longdouble ;
311
+ break ;
312
+ #endif
313
+ case ZEND_FFI_TYPE_SINT8 :
314
+ case ZEND_FFI_TYPE_UINT8 :
315
+ case ZEND_FFI_TYPE_BOOL :
316
+ case ZEND_FFI_TYPE_CHAR :
317
+ t -> elements [(* i )++ ] = & ffi_type_uint8 ;
318
+ break ;
319
+ case ZEND_FFI_TYPE_SINT16 :
320
+ case ZEND_FFI_TYPE_UINT16 :
321
+ t -> elements [(* i )++ ] = & ffi_type_uint16 ;
322
+ break ;
323
+ case ZEND_FFI_TYPE_SINT32 :
324
+ case ZEND_FFI_TYPE_UINT32 :
325
+ t -> elements [(* i )++ ] = & ffi_type_uint32 ;
326
+ break ;
327
+ case ZEND_FFI_TYPE_SINT64 :
328
+ case ZEND_FFI_TYPE_UINT64 :
329
+ t -> elements [(* i )++ ] = & ffi_type_uint64 ;
330
+ break ;
331
+ case ZEND_FFI_TYPE_POINTER :
332
+ t -> elements [(* i )++ ] = & ffi_type_pointer ;
333
+ break ;
334
+ case ZEND_FFI_TYPE_STRUCT : {
335
+ zend_ffi_type * field_type = ZEND_FFI_TYPE (field -> type );
336
+ /* for unions we use only the first field */
337
+ int num_fields = !(field_type -> attr & ZEND_FFI_ATTR_UNION ) ?
338
+ zend_hash_num_elements (& field_type -> record .fields ) : 1 ;
339
+
340
+ if (num_fields > 1 ) {
341
+ size += sizeof (ffi_type * ) * (num_fields - 1 );
342
+ t = erealloc (t , size );
343
+ t -> elements = (ffi_type * * )(t + 1 );
344
+ }
345
+ t = zend_ffi_face_struct_add_fields (t , field_type , i , size );
346
+ break ;
347
+ }
348
+ default :
349
+ t -> elements [(* i )++ ] = & ffi_type_void ;
350
+ break ;
351
+ }
352
+ if (type -> attr & ZEND_FFI_ATTR_UNION ) {
353
+ /* for unions we use only the first field */
354
+ break ;
355
+ }
356
+ } ZEND_HASH_FOREACH_END ();
357
+ return t ;
358
+ }
359
+
296
360
static ffi_type * zend_ffi_make_fake_struct_type (zend_ffi_type * type ) /* {{{ */
297
361
{
298
- ffi_type * t = emalloc (sizeof (ffi_type ) + sizeof (ffi_type * ));
362
+ /* for unions we use only the first field */
363
+ int num_fields = !(type -> attr & ZEND_FFI_ATTR_UNION ) ?
364
+ zend_hash_num_elements (& type -> record .fields ) : 1 ;
365
+ size_t size = sizeof (ffi_type ) + sizeof (ffi_type * ) * (num_fields + 1 );
366
+ ffi_type * t = emalloc (size );
367
+ int i ;
299
368
300
369
t -> size = type -> size ;
301
370
t -> alignment = type -> align ;
302
371
t -> type = FFI_TYPE_STRUCT ;
303
372
t -> elements = (ffi_type * * )(t + 1 );
304
- t -> elements [0 ] = NULL ;
373
+ i = 0 ;
374
+ t = zend_ffi_face_struct_add_fields (t , type , & i , size );
375
+ t -> elements [i ] = NULL ;
305
376
return t ;
306
377
}
307
378
/* }}} */
0 commit comments