test(compiler): reject mixed cache lifetime IDs

debug/ci-class-id-cache
韩天峰 9 hours ago
parent 8c6ea1d14e
commit 1b235d0769
  1. 14
      phpunit/src/CompilerBaseApiTest.php
  2. 18
      src/CompilerBase.php

@ -98,6 +98,20 @@ class CompilerBaseApiTest extends TestCase
$this->assertSame([], $this->getPropertyValue('persistentFuncMap'));
}
public function testMethodCacheRejectsMismatchedLifetimeDomains(): void
{
$this->setPropertyValue('classMap', ['LateKnownClass' => 0]);
$this->setPropertyValue('classIndex', 1);
$this->setPropertyValue('persistentFuncMap', ['LateKnownClass::run' => 0]);
$this->setPropertyValue('persistentFuncIndex', 1);
$this->expectException(\LogicException::class);
$this->expectExceptionMessage(
'Cache lifetime mismatch for LateKnownClass::run: method ID 0 is persistent, class ID 0 is request-local',
);
$this->invokeMethod('getMethodPtr', 'LateKnownClass', 'run');
}
private function fixturePath(string $file): string
{
return __DIR__ . '/../code/compiler_api/' . $file;

@ -1426,10 +1426,22 @@ class CompilerBase implements PropertyAccessContext
protected function getMethodPtr(string $class, string $method): string
{
$funcId = $this->getFuncId($class . '::' . $method);
$key = $class . '::' . $method;
$funcId = $this->getFuncId($key);
$classId = $this->getClassId($class);
// 方法的稳定性与所属类一致,因此 class_id 必定落在同一张表中
$helper = isset($this->persistentFuncMap[$class . '::' . $method]) ? 'get_persistent_method' : 'get_method';
$persistentMethod = isset($this->persistentFuncMap[$key]);
$persistentClass = isset($this->persistentClassMap[$class]);
if ($persistentMethod !== $persistentClass) {
throw new \LogicException(sprintf(
'Cache lifetime mismatch for %s: method ID %d is %s, class ID %d is %s',
$key,
$funcId,
$persistentMethod ? 'persistent' : 'request-local',
$classId,
$persistentClass ? 'persistent' : 'request-local',
));
}
$helper = $persistentMethod ? 'get_persistent_method' : 'get_method';
return $helper . '(' . $funcId . ', ' . $this->getLiteralString($method) . ', ' . $classId . ', ' . $this->getLiteralString($class) . ')';
}

Loading…
Cancel
Save