]> granicus.if.org Git - php/commitdiff
Avoid usage of internal get/set object handlers. They are going to be removed in...
authorDmitry Stogov <dmitry@zend.com>
Tue, 28 May 2019 14:08:35 +0000 (17:08 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 28 May 2019 14:08:35 +0000 (17:08 +0300)
Scalar FFI values now should be accessed through special "cdata" property.

    $x = FFI::new("int");
    $x = 42;

    should be changed into

    $x = FFI::new("int");
    $x->cdata = 42;

ext/ffi/ffi.c
ext/ffi/tests/025.phpt
ext/ffi/tests/026.phpt
ext/ffi/tests/036.phpt
ext/ffi/tests/037.phpt
ext/ffi/tests/040.phpt

index 174ebb056c40cde55916e186b9548c2ded5f7746..4b08c9cf2aa1dc16f9e0b561648e48ad4bb4788a 100644 (file)
@@ -882,7 +882,7 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ *
 /* }}} */
 #endif
 
-static zval* zend_ffi_cdata_get(zval *object, zval *rv) /* {{{ */
+static zval *zend_ffi_cdata_get(zval *object, zval *member, int read_type, void **cache_slot, zval *rv) /* {{{ */
 {
        zend_ffi_cdata *cdata = (zend_ffi_cdata*)Z_OBJ_P(object);
        zend_ffi_type  *type = ZEND_FFI_TYPE(cdata->type);
@@ -894,12 +894,18 @@ static zval* zend_ffi_cdata_get(zval *object, zval *rv) /* {{{ */
        }
 #endif
 
+       if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)
+        || UNEXPECTED(!zend_string_equals_literal(Z_STR_P(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(zval *object, zval *value) /* {{{ */
+static zval *zend_ffi_cdata_set(zval *object, zval *member, zval *value, void **cache_slot) /* {{{ */
 {
        zend_ffi_cdata *cdata = (zend_ffi_cdata*)Z_OBJ_P(object);
        zend_ffi_type  *type = ZEND_FFI_TYPE(cdata->type);
@@ -907,16 +913,92 @@ static void zend_ffi_cdata_set(zval *object, 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(Z_TYPE_P(member) != IS_STRING)
+        || UNEXPECTED(!zend_string_equals_literal(Z_STR_P(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(zval *readobj, zval *writeobj, int type) /* {{{ */
 {
+       if (type == IS_STRING) {
+               zend_ffi_cdata *cdata = (zend_ffi_cdata*)Z_OBJ_P(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;
 }
 /* }}} */
@@ -4697,13 +4779,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;
@@ -4711,7 +4791,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;
@@ -4728,7 +4808,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;
index 520f22e7867cfd069fbc81951d4cde1fd7030a3e..d1182c485482c8367e9866f70e4d5f7069cd7a74 100644 (file)
@@ -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);
index d037871f0afb4f73febdb343e93c2054782c4a8c..5e4356041f7db98453b2898e758535c91319fcc1 100644 (file)
@@ -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);
 ?>
index e022d03d222ea84ddc5e02dd3163ddff300c68b8..5c4e0600b832059baab143f0c3c15fc845a9f37d 100644 (file)
@@ -18,7 +18,7 @@ function foo($ptr) {
 }
 
 $int = FFI::new("int");
-$int = 42;
+$int->cdata = 42;
 var_dump(foo(FFI::addr($int)));
 ?>
 --EXPECTF--
index f966cb7956751861c7823474f693a87be6065f6a..0b67e4a4dae150cb2c7832ebde4b3edbfbcfe366 100644 (file)
@@ -14,7 +14,7 @@ function foo($ptr) {
 }
 
 $int = FFI::new("int");
-$int = 42;
+$int->cdata = 42;
 var_dump(foo(FFI::addr($int)));
 ?>
 --EXPECTF--
index 0d6aa8b32c42d152453931de9530527b571d0be0..24bcfb6307e84204612edd7ceea2ab3b655ad4d0 100644 (file)
@@ -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));