@@ -2966,7 +2966,6 @@ ZEND_METHOD(FFI, cdef) /* {{{ */
2966
2966
persistent = true;
2967
2967
}
2968
2968
}
2969
-
2970
2969
}
2971
2970
2972
2971
ffi = (zend_ffi * )zend_ffi_new (zend_ffi_ce );
@@ -3167,7 +3166,8 @@ static zend_ffi *zend_ffi_load(const char *filename, bool preload) /* {{{ */
3167
3166
{
3168
3167
struct stat buf ;
3169
3168
int fd ;
3170
- char * code , * code_pos , * scope_name , * lib , * err ;
3169
+ zend_string * code ;
3170
+ char * code_pos , * scope_name , * lib , * err ;
3171
3171
size_t code_size , scope_name_len ;
3172
3172
zend_ffi * ffi ;
3173
3173
DL_HANDLE handle = NULL ;
@@ -3176,6 +3176,7 @@ static zend_ffi *zend_ffi_load(const char *filename, bool preload) /* {{{ */
3176
3176
zend_ffi_symbol * sym ;
3177
3177
zend_ffi_tag * tag ;
3178
3178
void * addr ;
3179
+ bool persistent = false;
3179
3180
3180
3181
if (stat (filename , & buf ) != 0 ) {
3181
3182
if (preload ) {
@@ -3196,24 +3197,36 @@ static zend_ffi *zend_ffi_load(const char *filename, bool preload) /* {{{ */
3196
3197
}
3197
3198
3198
3199
code_size = buf .st_size ;
3199
- code = emalloc (code_size + 1 );
3200
+ code = zend_string_alloc (code_size , 0 );
3200
3201
int open_flags = O_RDONLY ;
3201
3202
#ifdef PHP_WIN32
3202
3203
open_flags |= _O_BINARY ;
3203
3204
#endif
3204
3205
fd = open (filename , open_flags , 0 );
3205
- if (fd < 0 || read (fd , code , code_size ) != code_size ) {
3206
+ if (fd < 0 || read (fd , ZSTR_VAL ( code ) , code_size ) != code_size ) {
3206
3207
if (preload ) {
3207
3208
zend_error (E_WARNING , "FFI: Failed pre-loading '%s', cannot read_file" , filename );
3208
3209
} else {
3209
3210
zend_throw_error (zend_ffi_exception_ce , "Failed loading '%s', cannot read_file" , filename );
3210
3211
}
3211
- efree (code );
3212
+ zend_string_release (code );
3212
3213
close (fd );
3213
3214
return NULL ;
3214
3215
}
3215
3216
close (fd );
3216
- code [code_size ] = 0 ;
3217
+ ZSTR_VAL (code )[code_size ] = 0 ;
3218
+
3219
+ if (!preload && zend_ffi_cache_scope_get ) {
3220
+ zend_ffi_scope * scope = zend_ffi_cache_scope_get (code );
3221
+ if (scope ) {
3222
+ ffi = (zend_ffi * )zend_ffi_new (zend_ffi_ce );
3223
+ ffi -> lib = handle ;
3224
+ ffi -> symbols = scope -> symbols ;
3225
+ ffi -> tags = scope -> tags ;
3226
+ ffi -> persistent = true;
3227
+ return ffi ;
3228
+ }
3229
+ }
3217
3230
3218
3231
FFI_G (symbols ) = NULL ;
3219
3232
FFI_G (tags ) = NULL ;
@@ -3225,13 +3238,13 @@ static zend_ffi *zend_ffi_load(const char *filename, bool preload) /* {{{ */
3225
3238
scope_name = NULL ;
3226
3239
scope_name_len = 0 ;
3227
3240
lib = NULL ;
3228
- code_pos = zend_ffi_parse_directives (filename , code , & scope_name , & lib , preload );
3241
+ code_pos = zend_ffi_parse_directives (filename , ZSTR_VAL ( code ) , & scope_name , & lib , preload );
3229
3242
if (!code_pos ) {
3230
- efree (code );
3243
+ zend_string_release (code );
3231
3244
FFI_G (persistent ) = 0 ;
3232
3245
return NULL ;
3233
3246
}
3234
- code_size -= code_pos - code ;
3247
+ code_size -= code_pos - ZSTR_VAL ( code ) ;
3235
3248
3236
3249
if (zend_ffi_parse_decl (code_pos , code_size ) == FAILURE ) {
3237
3250
if (preload ) {
@@ -3414,21 +3427,45 @@ static zend_ffi *zend_ffi_load(const char *filename, bool preload) /* {{{ */
3414
3427
ffi -> tags = scope -> tags ;
3415
3428
ffi -> persistent = 1 ;
3416
3429
} else {
3430
+ if (zend_ffi_cache_scope_add ) {
3431
+ zend_ffi_scope scope , * cached_scope ;
3432
+
3433
+ scope .symbols = FFI_G (symbols );
3434
+ scope .tags = FFI_G (tags );
3435
+ cached_scope = zend_ffi_cache_scope_add (code , & scope );
3436
+ if (cached_scope ) {
3437
+ if (FFI_G (symbols )) {
3438
+ zend_hash_destroy (FFI_G (symbols ));
3439
+ efree (FFI_G (symbols ));
3440
+ FFI_G (symbols ) = NULL ;
3441
+ }
3442
+ if (FFI_G (tags )) {
3443
+ zend_hash_destroy (FFI_G (tags ));
3444
+ efree (FFI_G (tags ));
3445
+ FFI_G (tags ) = NULL ;
3446
+ }
3447
+ FFI_G (symbols ) = cached_scope -> symbols ;
3448
+ FFI_G (tags ) = cached_scope -> tags ;
3449
+ persistent = true;
3450
+ }
3451
+ }
3452
+
3417
3453
ffi = (zend_ffi * )zend_ffi_new (zend_ffi_ce );
3418
3454
ffi -> lib = handle ;
3419
3455
ffi -> symbols = FFI_G (symbols );
3420
3456
ffi -> tags = FFI_G (tags );
3457
+ ffi -> persistent = persistent ;
3421
3458
}
3422
3459
3423
- efree (code );
3460
+ zend_string_release (code );
3424
3461
FFI_G (symbols ) = NULL ;
3425
3462
FFI_G (tags ) = NULL ;
3426
- FFI_G (persistent ) = 0 ;
3463
+ FFI_G (persistent ) = persistent ;
3427
3464
3428
3465
return ffi ;
3429
3466
3430
3467
cleanup :
3431
- efree (code );
3468
+ zend_string_release (code );
3432
3469
if (FFI_G (symbols )) {
3433
3470
zend_hash_destroy (FFI_G (symbols ));
3434
3471
pefree (FFI_G (symbols ), preload );
0 commit comments