feat(compiler): 添加未定义变量检查和对象处理器初始化

- 在属性访问时检查未定义变量并报告错误
- 初始化类对象处理器以支持对象操作
- 添加对未定义变量属性访问的测试用例
- 添加对未定义变量方法调用的测试用例
- 为动态代码中的类型化属性取消设置添加测试
pull/3/head
韩天峰 2 months ago
parent 72cf8e7166
commit e6c3e22f6e
  1. 29
      phpunit/code/base-class-method.php
  2. 10
      phpunit/src/UndefineTest.php
  3. 6
      src/Php/CompilerBase.php
  4. 5
      src/gen_stub.php
  5. 28
      tests/aot/class/unset-int-prop.phpt

@ -0,0 +1,29 @@
<?php
class FooBase {
function bar()
{
var_dump(__CLASS__);
}
function doSomething() {
$this->bar();
}
}
class FooChild extends FooBase {
function bar()
{
var_dump(__CLASS__);
}
}
function bar(FooBase $o)
{
$o->doSomething();
}
function main() {
$o = new FooChild();
$o2 = any($o);
bar($o2);
}

@ -17,4 +17,14 @@ class UndefineTest extends \BaseTest
{
$this->exec('Attempt to unset static property', 'unset-static-prop.php');
}
public function testPropertyAccessOnUndefinedVar(): void
{
$this->exec('The variable `$obj` is undefined', 'undefined-prop-access.php');
}
public function testMethodCallOnUndefinedVar(): void
{
$this->exec('The variable `$obj` is undefined', 'undefined-method-call.php');
}
}

@ -3975,7 +3975,11 @@ class CompilerBase extends \PhpAot\Core\Translator
$object = $expr->var;
$property = $expr->name;
$id = $this->getPropertyIdentifier($expr, $object, $property);
$objectVar = $this->parseIdentifier($object);
$objectName = $this->parseIdentifier($object);
if ($this->isVarExpr($object) and !$this->hasVar($objectName)) {
$this->errorUndefinedVariable($object);
}
$objectVar = $objectName;
$getProperty = $objectVar . '.attr(' . $id . ', ' . $this->escapeBool($update) . ')';
if ($expr->hasAttribute('nativePropertyDef') and $this->nativeTypes) {
/**

@ -3781,6 +3781,11 @@ class ClassInfo {
$code .= $php80CondEnd;
}
$code .= "\n\tstatic zend_object_handlers class_object_handlers;";
$code .= "\n\tphp_aot_init_object_handlers(&class_object_handlers);";
$code .= "\n\tclass_entry->default_object_handlers = &class_object_handlers;";
$code .= "\n";
$code .= "\n\treturn class_entry;\n";
$code .= "}\n";

@ -0,0 +1,28 @@
--TEST--
unset typed property via dynamic code
--FILE--
<?php
class FooObject {
public int $value = 42;
}
function main() {
$base = new FooObject();
$base->value += 1;
var_dump($base->value);
eval('function test(FooObject $obj) {
unset($obj->value);
}');
test($base);
var_dump($base->value);
echo "done\n";
}
?>
--EXPECT--
int(43)
int(0)
done
Loading…
Cancel
Save