diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 3d0de88c..afdd96da 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -191,6 +191,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected array $beforeStmtLines = []; protected array $afterStmtLines = []; protected bool $inLoop = false; + protected bool $inClosure = false; /** * 赋值表达式的左值,写操作,右值为读操作. @@ -895,7 +896,7 @@ class CompilerBase extends \PhpAot\Core\Translator $result = $this->parseEcho($v); break; case 'Stmt_Return': - $result = $this->parseReturn($v) . ';'; + $result = $this->parseReturn($v); break; case 'Stmt_For': $this->inLoop = true; @@ -1244,7 +1245,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseReturn(mixed $v): string { if ($v->expr === null) { - if ($this->functionDef->returnType === self::TYPE_VOID) { + if ($this->functionDef->returnType === self::TYPE_VOID and !$this->inClosure) { return 'return;'; } else { return 'return ' . self::VALUE_NULL . ';'; @@ -3522,10 +3523,14 @@ class CompilerBase extends \PhpAot\Core\Translator . self::TYPE_OBJECT . ' &this_, ' . self::TYPE_ARGS . ' &vars_) ' . '-> ' . self::TYPE_VAR . ' {' . PHP_EOL; + $oriLocalVars = $this->localVars; $this->localVars = []; $oriArgs = $this->arguments; $this->arguments = []; + $oriInClosure = $this->inClosure; + $this->inClosure = true; + $this->indentLevel++; $fnBodyCode = ''; @@ -3550,7 +3555,7 @@ class CompilerBase extends \PhpAot\Core\Translator $fnCode .= $fnBodyCode; if (!$this->isReturnStmtInLastLine($expr->stmts)) { - $fnCode .= 'return '.self::VALUE_NAN. ';' . PHP_EOL; + $fnCode .= 'return ' . self::VALUE_NULL . ';' . PHP_EOL; } $this->indentLevel--; @@ -3559,6 +3564,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->beforeStmtLines[] = $fnCode; $this->localVars = $oriLocalVars; $this->arguments = $oriArgs; + $this->inClosure = $oriInClosure; $useVars = []; foreach ($expr->uses as $useItem) { diff --git a/tests/zend/closures/closure_007.phpt b/tests/zend/closures/closure_007.phpt new file mode 100644 index 00000000..21aec8b9 --- /dev/null +++ b/tests/zend/closures/closure_007.phpt @@ -0,0 +1,41 @@ +--TEST-- +Closure 007: Nested lambdas in classes +--FILE-- +x++; + }; + }; + } + + function printX () { + echo $this->x."\n"; + } +} + +function main() { + $a = new A; + $a->printX(); + $getClosure = $a->getClosureGetter(); + $a->printX(); + $closure = $getClosure(); + $a->printX(); + $closure(); + $a->printX(); + + echo "Done\n"; +} + +?> +--EXPECT-- +0 +0 +0 +1 +Done diff --git a/tests/zend/closures/closure_008.phpt b/tests/zend/closures/closure_008.phpt new file mode 100644 index 00000000..bb226dfd --- /dev/null +++ b/tests/zend/closures/closure_008.phpt @@ -0,0 +1,24 @@ +--TEST-- +Closure 008: Use in preg_replace_callback() +--FILE-- + +--EXPECT-- +1 2 3 +1  2  3 +1   2   3 +Done diff --git a/tests/zend/closures/closure_009.phpt b/tests/zend/closures/closure_009.phpt new file mode 100644 index 00000000..c6881d59 --- /dev/null +++ b/tests/zend/closures/closure_009.phpt @@ -0,0 +1,33 @@ +--TEST-- +Closure 009: Using static vars inside lambda +--FILE-- + +--EXPECT-- +1:1:1 +2:2:1 +3:3:1 +4:1:1 +5:2:1:1 +6:3:2:1:1 diff --git a/tests/zend/closures/closure_010.phpt b/tests/zend/closures/closure_010.phpt new file mode 100644 index 00000000..04516f6a --- /dev/null +++ b/tests/zend/closures/closure_010.phpt @@ -0,0 +1,20 @@ +--TEST-- +Closure 010: Closure calls itself +--FILE-- + +--EXPECT-- +3 +2 +1 +0