refactor(optimizer): 将函数访问修饰符从私有更改为受保护

- 将 FuncCallOptimizer 中的 genFuncGetArgs 和 genFuncGetArg 方法从 public 改为 protected
- 将 SsaPropOptimizer 中的辅助方法从 private 改为 protected,包括 collectObjectAssignments、scanStmtForObjectAssign、resolveNewExprClass 等
- 将 SsaTypeOptimizer 中的常量和辅助方法从 private 改为 protected,包括 SAFE_INT_BINARY_OPS、SAFE_INT_ASSIGN_OPS 和各种检测方法
- 此更改允许子类继承和重用这些优化器中的实用方法
pull/1/head
韩天峰 3 months ago
parent 8950c6d51d
commit de50cad4a8
  1. 4
      src/Php/Optimizer/FuncCallOptimizer.php
  2. 20
      src/Php/Optimizer/SsaPropOptimizer.php
  3. 30
      src/Php/Optimizer/SsaTypeOptimizer.php

@ -12,7 +12,7 @@ use PhpParser\Node;
trait FuncCallOptimizer trait FuncCallOptimizer
{ {
public function genFuncGetArgs(string $name, Node\Expr\FuncCall $expr): string protected function genFuncGetArgs(string $name, Node\Expr\FuncCall $expr): string
{ {
$this->warningUndefinedBehavior($expr); $this->warningUndefinedBehavior($expr);
$funcDef = $this->functionDef; $funcDef = $this->functionDef;
@ -29,7 +29,7 @@ trait FuncCallOptimizer
return $this->genArray($list); return $this->genArray($list);
} }
public function genFuncGetArg(string $name, Node\Expr\FuncCall $expr) protected function genFuncGetArg(string $name, Node\Expr\FuncCall $expr)
{ {
$this->warningUndefinedBehavior($expr); $this->warningUndefinedBehavior($expr);
$position = $expr->args[0]->value; $position = $expr->args[0]->value;

@ -84,7 +84,7 @@ trait SsaPropOptimizer
* Walk the function body AST to find variable assignments that produce * Walk the function body AST to find variable assignments that produce
* typed objects. Returns map of varName => className. * typed objects. Returns map of varName => className.
*/ */
private function collectObjectAssignments(array $stmts): array protected function collectObjectAssignments(array $stmts): array
{ {
$result = []; $result = [];
foreach ($stmts as $stmt) { foreach ($stmts as $stmt) {
@ -93,7 +93,7 @@ trait SsaPropOptimizer
return $result; return $result;
} }
private function scanStmtForObjectAssign($stmt, array &$result): void protected function scanStmtForObjectAssign($stmt, array &$result): void
{ {
if (!$stmt instanceof Node) { if (!$stmt instanceof Node) {
return; return;
@ -139,7 +139,7 @@ trait SsaPropOptimizer
* Resolve the class name from a `new ClassName()` expression, * Resolve the class name from a `new ClassName()` expression,
* or a function/method call that returns a known object type. * or a function/method call that returns a known object type.
*/ */
private function resolveNewExprClass(Expr $expr): ?string protected function resolveNewExprClass(Expr $expr): ?string
{ {
if ($expr instanceof Expr\New_) { if ($expr instanceof Expr\New_) {
if ($expr->class instanceof Node\Name) { if ($expr->class instanceof Node\Name) {
@ -167,7 +167,7 @@ trait SsaPropOptimizer
/** /**
* Check if an object variable has a single stable SSA definition. * Check if an object variable has a single stable SSA definition.
*/ */
private function isObjectSsaStable(SsaBuilder $ssa, string $objName): bool protected function isObjectSsaStable(SsaBuilder $ssa, string $objName): bool
{ {
$foundDef = false; $foundDef = false;
@ -202,7 +202,7 @@ trait SsaPropOptimizer
* Check if an SSA definition sets the variable to an object value. * Check if an SSA definition sets the variable to an object value.
* Accepts both `new ClassName()` and calls that return a typed object. * Accepts both `new ClassName()` and calls that return a typed object.
*/ */
private function isObjectDefinition($ssaVar): bool protected function isObjectDefinition($ssaVar): bool
{ {
$def = $ssaVar->definition; $def = $ssaVar->definition;
if (!$def) { if (!$def) {
@ -227,7 +227,7 @@ trait SsaPropOptimizer
/** /**
* Check if a class has no magic methods that intercept property access. * Check if a class has no magic methods that intercept property access.
*/ */
private function isClassSafeForPropHoisting(string $className): bool protected function isClassSafeForPropHoisting(string $className): bool
{ {
$classDef = $this->classes[$this->escapeClass($className)] ?? null; $classDef = $this->classes[$this->escapeClass($className)] ?? null;
if (!$classDef) { if (!$classDef) {
@ -249,7 +249,7 @@ trait SsaPropOptimizer
* - $ref = &$o->prop — property becomes reference, zval type changes * - $ref = &$o->prop — property becomes reference, zval type changes
* - func(&$o->prop) or $obj->method(&$o->prop) — property passed by ref * - func(&$o->prop) or $obj->method(&$o->prop) — property passed by ref
*/ */
private function hasDangerousPropOps(string $objName, array $stmts): bool protected function hasDangerousPropOps(string $objName, array $stmts): bool
{ {
foreach ($stmts as $stmt) { foreach ($stmts as $stmt) {
if ($this->scanDangerousPropOp($stmt, $objName)) { if ($this->scanDangerousPropOp($stmt, $objName)) {
@ -259,7 +259,7 @@ trait SsaPropOptimizer
return false; return false;
} }
private function scanDangerousPropOp($stmt, string $objName): bool protected function scanDangerousPropOp($stmt, string $objName): bool
{ {
if (!$stmt instanceof Node) { if (!$stmt instanceof Node) {
return false; return false;
@ -319,7 +319,7 @@ trait SsaPropOptimizer
/** /**
* Check if an expression is a property fetch on a specific object. * Check if an expression is a property fetch on a specific object.
*/ */
private function isPropOfObj($node, string $objName): bool protected function isPropOfObj($node, string $objName): bool
{ {
return $node instanceof Expr\PropertyFetch return $node instanceof Expr\PropertyFetch
&& $node->var instanceof Expr\Variable && $node->var instanceof Expr\Variable
@ -327,7 +327,7 @@ trait SsaPropOptimizer
&& $node->var->name === $objName; && $node->var->name === $objName;
} }
private function recurseDangerousPropOp($stmt, string $objName): bool protected function recurseDangerousPropOp($stmt, string $objName): bool
{ {
if ($stmt instanceof Node\Stmt\If_) { if ($stmt instanceof Node\Stmt\If_) {
if ($this->hasDangerousPropOps($objName, $stmt->stmts)) return true; if ($this->hasDangerousPropOps($objName, $stmt->stmts)) return true;

@ -21,7 +21,7 @@ trait SsaTypeOptimizer
* Binary ops that always produce int from int operands and never overflow * Binary ops that always produce int from int operands and never overflow
* to float. Bitwise operations and modulo are safe; arithmetic is not. * to float. Bitwise operations and modulo are safe; arithmetic is not.
*/ */
private const SAFE_INT_BINARY_OPS = [ protected const array SAFE_INT_BINARY_OPS = [
'Expr_BinaryOp_BitwiseAnd' => true, 'Expr_BinaryOp_BitwiseAnd' => true,
'Expr_BinaryOp_BitwiseOr' => true, 'Expr_BinaryOp_BitwiseOr' => true,
'Expr_BinaryOp_BitwiseXor' => true, 'Expr_BinaryOp_BitwiseXor' => true,
@ -33,7 +33,7 @@ trait SsaTypeOptimizer
/** /**
* Compound assignment ops that keep the variable int-typed. * Compound assignment ops that keep the variable int-typed.
*/ */
private const SAFE_INT_ASSIGN_OPS = [ protected const array SAFE_INT_ASSIGN_OPS = [
'Expr_AssignOp_BitwiseAnd' => true, 'Expr_AssignOp_BitwiseAnd' => true,
'Expr_AssignOp_BitwiseOr' => true, 'Expr_AssignOp_BitwiseOr' => true,
'Expr_AssignOp_BitwiseXor' => true, 'Expr_AssignOp_BitwiseXor' => true,
@ -169,7 +169,7 @@ trait SsaTypeOptimizer
* Detect the type produced by a single SSA variable definition. * Detect the type produced by a single SSA variable definition.
* Returns null if the type cannot be determined from the AST. * Returns null if the type cannot be determined from the AST.
*/ */
private function detectSsaDefType(\PhpAot\Php\Analysis\SsaVar $ssaVar): ?string protected function detectSsaDefType(\PhpAot\Php\Analysis\SsaVar $ssaVar): ?string
{ {
$def = $ssaVar->definition; $def = $ssaVar->definition;
if (!$def) { if (!$def) {
@ -209,7 +209,7 @@ trait SsaTypeOptimizer
* Check whether a TYPE_INT expression could overflow int64 at runtime * Check whether a TYPE_INT expression could overflow int64 at runtime
* and produce a float in PHP. * and produce a float in PHP.
*/ */
private function exprCanOverflowInt(NodeAbstract $expr): bool protected function exprCanOverflowInt(NodeAbstract $expr): bool
{ {
// Division always produces float in PHP when operands are int // Division always produces float in PHP when operands are int
if ($expr instanceof Node\Expr\BinaryOp\Div) { if ($expr instanceof Node\Expr\BinaryOp\Div) {
@ -258,7 +258,7 @@ trait SsaTypeOptimizer
return false; return false;
} }
private function getIntConstantValue(NodeAbstract $node): ?int protected function getIntConstantValue(NodeAbstract $node): ?int
{ {
if ($node instanceof Node\Scalar\LNumber) { if ($node instanceof Node\Scalar\LNumber) {
return $node->value; return $node->value;
@ -266,7 +266,7 @@ trait SsaTypeOptimizer
return null; return null;
} }
private function isBoundaryConstant(NodeAbstract $node): bool protected function isBoundaryConstant(NodeAbstract $node): bool
{ {
if ($node instanceof Node\Expr\ConstFetch if ($node instanceof Node\Expr\ConstFetch
&& $node->name instanceof Node\Name) { && $node->name instanceof Node\Name) {
@ -276,7 +276,7 @@ trait SsaTypeOptimizer
return false; return false;
} }
private function phiSourcesHaveMixedTypes(SsaBuilder $ssa, array $varList, string $narrowedType): bool protected function phiSourcesHaveMixedTypes(SsaBuilder $ssa, array $varList, string $narrowedType): bool
{ {
foreach ($varList as $ssaVar) { foreach ($varList as $ssaVar) {
if (($ssaVar->flags & SsaFlags::PHI) && !empty($ssaVar->phiSources)) { if (($ssaVar->flags & SsaFlags::PHI) && !empty($ssaVar->phiSources)) {
@ -300,7 +300,7 @@ trait SsaTypeOptimizer
* (& | ^ << >> ~) and modulo (%) are safe — arithmetic can overflow * (& | ^ << >> ~) and modulo (%) are safe — arithmetic can overflow
* to float, which int64_t would wrap instead. * to float, which int64_t would wrap instead.
*/ */
private function hasDangerousIntOps(string $varName, array $stmts): bool protected function hasDangerousIntOps(string $varName, array $stmts): bool
{ {
foreach ($stmts as $stmt) { foreach ($stmts as $stmt) {
if ($this->scanStmtForDangerousIntOps($stmt, $varName)) { if ($this->scanStmtForDangerousIntOps($stmt, $varName)) {
@ -310,7 +310,7 @@ trait SsaTypeOptimizer
return false; return false;
} }
private function scanStmtForDangerousIntOps($stmt, string $varName): bool protected function scanStmtForDangerousIntOps($stmt, string $varName): bool
{ {
if (!$stmt instanceof Node) { if (!$stmt instanceof Node) {
return false; return false;
@ -385,7 +385,7 @@ trait SsaTypeOptimizer
* narrowed int64_t. Any other BinaryOp, AssignOp, UnaryMinus, or * narrowed int64_t. Any other BinaryOp, AssignOp, UnaryMinus, or
* Inc/Dec that involves $varName is a hazard. * Inc/Dec that involves $varName is a hazard.
*/ */
private function exprHasIntHazard($expr, string $varName): bool protected function exprHasIntHazard($expr, string $varName): bool
{ {
if (!$expr instanceof Node) { if (!$expr instanceof Node) {
return false; return false;
@ -477,7 +477,7 @@ trait SsaTypeOptimizer
/** /**
* Check whether $varName appears anywhere recursively in an AST node. * Check whether $varName appears anywhere recursively in an AST node.
*/ */
private function exprUsesVar($node, string $varName): bool protected function exprUsesVar($node, string $varName): bool
{ {
if (!$node instanceof Node) { if (!$node instanceof Node) {
return false; return false;
@ -510,14 +510,14 @@ trait SsaTypeOptimizer
return false; return false;
} }
private function isVarNamed($node, string $varName): bool protected function isVarNamed($node, string $varName): bool
{ {
return $node instanceof Node\Expr\Variable return $node instanceof Node\Expr\Variable
&& is_string($node->name) && is_string($node->name)
&& $node->name === $varName; && $node->name === $varName;
} }
private function hasDangerousFloatOps(string $varName, array $stmts): bool protected function hasDangerousFloatOps(string $varName, array $stmts): bool
{ {
foreach ($stmts as $stmt) { foreach ($stmts as $stmt) {
if ($this->scanStmtForDangerousFloatOps($stmt, $varName)) { if ($this->scanStmtForDangerousFloatOps($stmt, $varName)) {
@ -527,7 +527,7 @@ trait SsaTypeOptimizer
return false; return false;
} }
private function scanStmtForDangerousFloatOps($stmt, string $varName): bool protected function scanStmtForDangerousFloatOps($stmt, string $varName): bool
{ {
if (!$stmt instanceof Node) { if (!$stmt instanceof Node) {
return false; return false;
@ -553,7 +553,7 @@ trait SsaTypeOptimizer
/** /**
* Recurse into compound statements (if/else, foreach, while, for, try/catch, switch). * Recurse into compound statements (if/else, foreach, while, for, try/catch, switch).
*/ */
private function recurseForDangerousOps($stmt, string $varName, string $mode): bool protected function recurseForDangerousOps($stmt, string $varName, string $mode): bool
{ {
$method = 'hasDangerous' . $mode . 'Ops'; $method = 'hasDangerous' . $mode . 'Ops';

Loading…
Cancel
Save