From 38d828cbbe8f485e0d0d8a241526e110e5962396 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 9 Sep 2026 08:52:10 +0800 Subject: [PATCH] refactor(compiler): simplify object property access in compiler base - Removed redundant zval macro handling for property access - Replaced Z_LVAL_P and Z_DVAL_P calls with direct attribute accessors - Updated property getter logic to use attrInt and attrFloat methods - Modified tests to match new property access pattern - Added comprehensive test case for inherited property reference handling --- phpunit/src/NativePropertyTest.php | 8 ++--- src/CompilerBase.php | 3 +- src/Parser/PropertyAccessTrait.php | 5 +++ ...bjprop-hoist-this-inherited-reference.phpt | 31 +++++++++++++++++++ 4 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 tests/compiler/optimizations/objprop-hoist-this-inherited-reference.phpt diff --git a/phpunit/src/NativePropertyTest.php b/phpunit/src/NativePropertyTest.php index d3a5c664..0e48440a 100644 --- a/phpunit/src/NativePropertyTest.php +++ b/phpunit/src/NativePropertyTest.php @@ -59,11 +59,11 @@ class NativePropertyTest extends \BaseTest } $code = file_get_contents($outputFile); - $this->assertStringContainsString('php::Int &_object_prop_this___value = Z_LVAL_P(this_.attr(', $code); + $this->assertStringContainsString('php::Int &_object_prop_this___value = this_.attrInt(', $code); $this->assertStringContainsString('php::Int &_object_prop_box__value = Z_LVAL_P(box.attr(', $code); $this->assertStringContainsString('_object_prop_this___value += (2L);', $code); $this->assertStringContainsString('_object_prop_box__value += (2L);', $code); - $this->assertSame(2, substr_count($code, 'Z_LVAL_P(')); + $this->assertSame(1, substr_count($code, 'Z_LVAL_P(')); $this->assertStringNotContainsString('typephp_write_property_scoped(', $code); } @@ -92,7 +92,7 @@ class NativePropertyTest extends \BaseTest } $code = file_get_contents($outputFile); - $this->assertStringContainsString('php::Int &_object_prop_this___flags = Z_LVAL_P(this_.attr(', $code); + $this->assertStringContainsString('php::Int &_object_prop_this___flags = this_.attrInt(', $code); // A TypePHP class constant is available during conversion and is // folded before the native property operation is emitted. $this->assertStringContainsString('_object_prop_this___flags &= (~php::toInt(1L));', $code); @@ -125,7 +125,7 @@ class NativePropertyTest extends \BaseTest } $code = file_get_contents($outputFile); - $this->assertStringContainsString('php::Int &_object_prop_this___value = Z_LVAL_P(this_.attr(', $code); + $this->assertStringContainsString('php::Int &_object_prop_this___value = this_.attrInt(', $code); $this->assertStringContainsString('_object_prop_this___value = php::toIntExact(dynamicValue, "NativePropertyThisWriteConversionBox::$value");', $code); } diff --git a/src/CompilerBase.php b/src/CompilerBase.php index 96d40c3d..8ee19187 100644 --- a/src/CompilerBase.php +++ b/src/CompilerBase.php @@ -5340,8 +5340,7 @@ class CompilerBase implements PropertyAccessContext if (($info['kind'] ?? 'zval') === 'var') { $code .= $this->getIndent() . Type::VAR . ' ' . $name . ' = ' . $info['getter'] . ';' . PHP_EOL; } else { - $zvalMacro = ($info['type'] === Type::FLOAT) ? 'Z_DVAL_P' : 'Z_LVAL_P'; - $code .= $this->getIndent() . $info['type'] . ' &' . $name . ' = ' . $zvalMacro . '(' . $info['getter'] . '.unwrap_ptr());' . PHP_EOL; + $code .= $this->getIndent() . $info['type'] . ' &' . $name . ' = ' . $info['getter'] . ';' . PHP_EOL; } } foreach ($this->context->staticPropRefs as $info) { diff --git a/src/Parser/PropertyAccessTrait.php b/src/Parser/PropertyAccessTrait.php index d5c9c617..a7c362d1 100644 --- a/src/Parser/PropertyAccessTrait.php +++ b/src/Parser/PropertyAccessTrait.php @@ -1382,6 +1382,11 @@ trait PropertyAccessTrait if (!$this->canHoistObjectProp($objectVar, $propName, $def)) { return null; } + if ($def->type === Type::INT) { + $getter = $objectVar . '.attrInt(' . $propertyId . ')'; + } elseif ($def->type === Type::FLOAT) { + $getter = $objectVar . '.attrFloat(' . $propertyId . ')'; + } $this->registerHoistedObjectPropVar($propVar, $def->type, $getter); $this->setNativePropertyVar($expr, $propVar); $this->setNativePropertyValueSource($expr, self::NATIVE_PROPERTY_VALUE_VAR); diff --git a/tests/compiler/optimizations/objprop-hoist-this-inherited-reference.phpt b/tests/compiler/optimizations/objprop-hoist-this-inherited-reference.phpt new file mode 100644 index 00000000..4a61cdb9 --- /dev/null +++ b/tests/compiler/optimizations/objprop-hoist-this-inherited-reference.phpt @@ -0,0 +1,31 @@ +--TEST-- +Hoisted this numeric slots preserve inherited properties and existing references +--FILE-- +count += 3; + $this->weight += 0.5; + } +} +function main(): void { + $object = new SlotChild(); + $count =& $object->count; + $weight =& $object->weight; + $object->update(); + var_dump($count, $weight); + $count = 10; + $weight = 3.5; + $object->update(); + var_dump($count, $weight); +} +?> +--EXPECT-- +int(5) +float(2) +int(13) +float(4)