diff options
-rw-r--r-- | ext/ffi/ffi.c | 95 | ||||
-rw-r--r-- | ext/ffi/tests/025.phpt | 8 | ||||
-rw-r--r-- | ext/ffi/tests/026.phpt | 2 | ||||
-rw-r--r-- | ext/ffi/tests/036.phpt | 2 | ||||
-rw-r--r-- | ext/ffi/tests/037.phpt | 2 | ||||
-rw-r--r-- | ext/ffi/tests/040.phpt | 2 |
6 files changed, 94 insertions, 17 deletions
diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 7310a7c4c2..1452be4f14 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -882,7 +882,7 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ * /* }}} */ #endif -static zval* zend_ffi_cdata_get(zend_object *obj, zval *rv) /* {{{ */ +static zval *zend_ffi_cdata_get(zend_object *obj, zend_string *member, int read_type, void **cache_slot, zval *rv) /* {{{ */ { zend_ffi_cdata *cdata = (zend_ffi_cdata*)obj; zend_ffi_type *type = ZEND_FFI_TYPE(cdata->type); @@ -894,12 +894,17 @@ static zval* zend_ffi_cdata_get(zend_object *obj, zval *rv) /* {{{ */ } #endif + if (UNEXPECTED(!zend_string_equals_literal(member, "cdata"))) { + zend_throw_error(zend_ffi_exception_ce, "only 'cdata' property may be read"); + return &EG(uninitialized_zval);; + } + zend_ffi_cdata_to_zval(cdata, cdata->ptr, type, BP_VAR_R, rv, 0, 0); return rv; } /* }}} */ -static void zend_ffi_cdata_set(zend_object *obj, zval *value) /* {{{ */ +static zval *zend_ffi_cdata_set(zend_object *obj, zend_string *member, zval *value, void **cache_slot) /* {{{ */ { zend_ffi_cdata *cdata = (zend_ffi_cdata*)obj; zend_ffi_type *type = ZEND_FFI_TYPE(cdata->type); @@ -907,16 +912,91 @@ static void zend_ffi_cdata_set(zend_object *obj, zval *value) /* {{{ */ #if 0 if (UNEXPECTED(!cdata->ptr)) { zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference"); - return; + return &EG(uninitialized_zval);; } #endif + if (UNEXPECTED(!zend_string_equals_literal(member, "cdata"))) { + zend_throw_error(zend_ffi_exception_ce, "only 'cdata' property may be set"); + return &EG(uninitialized_zval);; + } + zend_ffi_zval_to_cdata(cdata->ptr, type, value); + + return value; } /* }}} */ static int zend_ffi_cdata_cast_object(zend_object *readobj, zval *writeobj, int type) /* {{{ */ { + if (type == IS_STRING) { + zend_ffi_cdata *cdata = (zend_ffi_cdata*)readobj; + zend_ffi_type *ctype = ZEND_FFI_TYPE(cdata->type); + void *ptr = cdata->ptr; + zend_ffi_type_kind kind = ctype->kind; + +again: + switch (kind) { + case ZEND_FFI_TYPE_FLOAT: + ZVAL_DOUBLE(writeobj, *(float*)ptr); + break; + case ZEND_FFI_TYPE_DOUBLE: + ZVAL_DOUBLE(writeobj, *(double*)ptr); + break; +#ifdef HAVE_LONG_DOUBLE + case ZEND_FFI_TYPE_LONGDOUBLE: + ZVAL_DOUBLE(writeobj, *(long double*)ptr); + break; +#endif + case ZEND_FFI_TYPE_UINT8: + ZVAL_LONG(writeobj, *(uint8_t*)ptr); + break; + case ZEND_FFI_TYPE_SINT8: + ZVAL_LONG(writeobj, *(int8_t*)ptr); + break; + case ZEND_FFI_TYPE_UINT16: + ZVAL_LONG(writeobj, *(uint16_t*)ptr); + break; + case ZEND_FFI_TYPE_SINT16: + ZVAL_LONG(writeobj, *(int16_t*)ptr); + break; + case ZEND_FFI_TYPE_UINT32: + ZVAL_LONG(writeobj, *(uint32_t*)ptr); + break; + case ZEND_FFI_TYPE_SINT32: + ZVAL_LONG(writeobj, *(int32_t*)ptr); + break; + case ZEND_FFI_TYPE_UINT64: + ZVAL_LONG(writeobj, *(uint64_t*)ptr); + break; + case ZEND_FFI_TYPE_SINT64: + ZVAL_LONG(writeobj, *(int64_t*)ptr); + break; + case ZEND_FFI_TYPE_BOOL: + ZVAL_BOOL(writeobj, *(uint8_t*)ptr); + break; + case ZEND_FFI_TYPE_CHAR: + ZVAL_INTERNED_STR(writeobj, ZSTR_CHAR(*(unsigned char*)ptr)); + return SUCCESS; + case ZEND_FFI_TYPE_ENUM: + kind = ctype->enumeration.kind; + goto again; + case ZEND_FFI_TYPE_POINTER: + if (*(void**)ptr == NULL) { + ZVAL_NULL(writeobj); + break; + } else if ((ctype->attr & ZEND_FFI_ATTR_CONST) && ZEND_FFI_TYPE(ctype->pointer.type)->kind == ZEND_FFI_TYPE_CHAR) { + ZVAL_STRING(writeobj, *(char**)ptr); + return SUCCESS; + } + return FAILURE; + default: + return FAILURE; + } + convert_to_string(writeobj); + return SUCCESS; + } + return FAILURE; } /* }}} */ @@ -4658,13 +4738,11 @@ ZEND_MINIT_FUNCTION(ffi) zend_ffi_cdata_value_handlers.get_constructor = zend_fake_get_constructor; zend_ffi_cdata_value_handlers.free_obj = zend_ffi_cdata_free_obj; zend_ffi_cdata_value_handlers.clone_obj = zend_ffi_cdata_clone_obj; - zend_ffi_cdata_value_handlers.read_property = zend_fake_read_property; - zend_ffi_cdata_value_handlers.write_property = zend_fake_write_property; + zend_ffi_cdata_value_handlers.read_property = zend_ffi_cdata_get; + zend_ffi_cdata_value_handlers.write_property = zend_ffi_cdata_set; zend_ffi_cdata_value_handlers.read_dimension = zend_fake_read_dimension; zend_ffi_cdata_value_handlers.write_dimension = zend_fake_write_dimension; zend_ffi_cdata_value_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr; - zend_ffi_cdata_value_handlers.get = zend_ffi_cdata_get; - zend_ffi_cdata_value_handlers.set = zend_ffi_cdata_set; zend_ffi_cdata_value_handlers.has_property = zend_fake_has_property; zend_ffi_cdata_value_handlers.unset_property = zend_fake_unset_property; zend_ffi_cdata_value_handlers.has_dimension = zend_fake_has_dimension; @@ -4672,7 +4750,7 @@ ZEND_MINIT_FUNCTION(ffi) zend_ffi_cdata_value_handlers.get_method = zend_fake_get_method; zend_ffi_cdata_value_handlers.get_class_name = zend_ffi_cdata_get_class_name; zend_ffi_cdata_value_handlers.compare_objects = zend_ffi_cdata_compare_objects; - zend_ffi_cdata_value_handlers.cast_object = NULL; + zend_ffi_cdata_value_handlers.cast_object = zend_ffi_cdata_cast_object; zend_ffi_cdata_value_handlers.count_elements = NULL; zend_ffi_cdata_value_handlers.get_debug_info = zend_ffi_cdata_get_debug_info; zend_ffi_cdata_value_handlers.get_closure = NULL; @@ -4689,7 +4767,6 @@ ZEND_MINIT_FUNCTION(ffi) zend_ffi_cdata_free_handlers.write_dimension = zend_ffi_free_write_dimension; zend_ffi_cdata_free_handlers.get_property_ptr_ptr = zend_fake_get_property_ptr_ptr; zend_ffi_cdata_free_handlers.get = zend_ffi_free_get; - zend_ffi_cdata_free_handlers.set = NULL; zend_ffi_cdata_free_handlers.has_property = zend_ffi_free_has_property; zend_ffi_cdata_free_handlers.unset_property = zend_ffi_free_unset_property; zend_ffi_cdata_free_handlers.has_dimension = zend_ffi_free_has_dimension; diff --git a/ext/ffi/tests/025.phpt b/ext/ffi/tests/025.phpt index 520f22e786..d1182c4854 100644 --- a/ext/ffi/tests/025.phpt +++ b/ext/ffi/tests/025.phpt @@ -7,17 +7,17 @@ ffi.enable=1 --FILE-- <?php $x = FFI::new("int"); - $x = 5; + $x->cdata = 5; var_dump($x); - $x += 2; + $x->cdata += 2; var_dump($x); echo "$x\n\n"; unset($x); $x = FFI::new("char"); - $x = 'a'; + $x->cdata = 'a'; var_dump($x); - $x++; + $x->cdata++; var_dump($x); echo "$x\n\n"; unset($x); diff --git a/ext/ffi/tests/026.phpt b/ext/ffi/tests/026.phpt index d037871f0a..5e4356041f 100644 --- a/ext/ffi/tests/026.phpt +++ b/ext/ffi/tests/026.phpt @@ -11,7 +11,7 @@ $a[1] = 10; $a[2] = 20; var_dump($a); foreach ($a as &$val) { - $val += 5; + $val->cdata += 5; } var_dump($a); ?> diff --git a/ext/ffi/tests/036.phpt b/ext/ffi/tests/036.phpt index e022d03d22..5c4e0600b8 100644 --- a/ext/ffi/tests/036.phpt +++ b/ext/ffi/tests/036.phpt @@ -18,7 +18,7 @@ function foo($ptr) { } $int = FFI::new("int"); -$int = 42; +$int->cdata = 42; var_dump(foo(FFI::addr($int))); ?> --EXPECTF-- diff --git a/ext/ffi/tests/037.phpt b/ext/ffi/tests/037.phpt index f966cb7956..0b67e4a4da 100644 --- a/ext/ffi/tests/037.phpt +++ b/ext/ffi/tests/037.phpt @@ -14,7 +14,7 @@ function foo($ptr) { } $int = FFI::new("int"); -$int = 42; +$int->cdata = 42; var_dump(foo(FFI::addr($int))); ?> --EXPECTF-- diff --git a/ext/ffi/tests/040.phpt b/ext/ffi/tests/040.phpt index 0d6aa8b32c..24bcfb6307 100644 --- a/ext/ffi/tests/040.phpt +++ b/ext/ffi/tests/040.phpt @@ -7,7 +7,7 @@ ffi.enable=1 --FILE-- <?php $x = FFI::new("int"); -$x = 5; +$x->cdata = 5; var_dump($x); var_dump(FFI::typeof($x)); var_dump(FFI::cast("int8_t[4]", $x)); |