speed_build
yangweijie 3 weeks ago
parent e79ec2cf73
commit fbaac125ae
  1. 38
      src/CompilerBase.php

@ -138,6 +138,16 @@ class CompilerBase implements PropertyAccessContext
use LoopVarOptimizer;
use SsaPropOptimizer;
/**
* Variables (and parameters) within the currently compiled function that must
* be emitted as a runtime variant (php::Var). A variable is recorded here when
* it is assigned incompatible types at different points in the body — which is
* perfectly legal in dynamically typed PHP but would otherwise force a strict
* backend to either fatal ("Cannot re-assign") or silently miscompile. The set
* is populated by computeVariantVars() right before the function body is parsed.
*/
protected array $variantVars = [];
public const string DEFAULT_PHP_VERSION = '8.5';
protected const string NATIVE_PROPERTY_VALUE_VAR = 'var';
protected const string NATIVE_PROPERTY_VALUE_DYNAMIC = 'dynamic';
@ -999,6 +1009,7 @@ class CompilerBase implements PropertyAccessContext
$this->context = new FunctionContext();
$this->function = '';
$this->functionDef = null;
$this->variantVars = [];
}
protected function resetMethod(): void
@ -3946,6 +3957,33 @@ class CompilerBase implements PropertyAccessContext
$this->fatalError($left, "Cannot re-assign $varName from `{$fromType}` to `{$toType}`");
}
/**
* Mirror of checkVarAssignExpr()'s compatibility rules without the fatal side
* effect. Returns true when a variable of type $existing may legally receive a
* value of type $new (used by computeVariantVars() to decide whether a variable
* must be promoted to a runtime variant).
*/
protected function areTypesAssignable(string $existing, string $new): bool
{
if ($existing === Type::VAR or $new === Type::VAR) {
return true;
}
if ($existing === Type::REF or $new === Type::REF) {
return true;
}
if ($existing === $new) {
return true;
}
if ($this->isNativeType($existing) and $this->isNativeType($new)) {
return true;
}
$bigTypes = [Type::BIGINT, Type::DECIMAL, Type::BIGFLOAT];
if (in_array($existing, $bigTypes, true) or in_array($new, $bigTypes, true)) {
return true;
}
return false;
}
/**
* Check a value against a composite PHP type when the value's static type
* is precise enough to prove a mismatch. Composite declarations still use

Loading…
Cancel
Save