diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 5e5761ae..445374ea 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -5482,13 +5482,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($type === self::TYPE_STD_ARRAY) { $info = $this->context->stdArrays[$name]; if (isset($info['unsafePtr'])) { - $unsafePtrBox = $this->genTmpVarName(); - $code .= 'auto *' . $unsafePtrBox . ' = ' . $info['unsafePtr'] . '.toBox();' . PHP_EOL; - $code .= $this->getIndent() . 'if (UNEXPECTED(' . $unsafePtrBox . '->type_id != ' . $info['typeId'] . ')) {' . PHP_EOL; - $code .= $this->getIndent() . ' php::throwException("RuntimeException", "std::unsafe_cast(): UnsafePtr type mismatch");' . PHP_EOL; - $code .= $this->getIndent() . '}' . PHP_EOL; - $code .= $this->getIndent(); - $code .= 'auto &' . $name . ' = *reinterpret_cast<' . $info['decl'] . '*>(' . $unsafePtrBox . '->ptr);'; + $code .= 'auto &' . $name . ' = php_unsafe_cast<' . $info['decl'] . '>(' . $info['unsafePtr'] . ', ' . $info['typeId'] . ');'; } elseif ($info['bytes'] > self::MAX_BYTES_IN_STACK) { $code .= "auto {$name}_unique_ptr = std::make_unique<{$info['decl']}>();\n"; $code .= $this->getIndent() . ' auto &' . $name . ' = *' . $name . '_unique_ptr;'; @@ -5498,13 +5492,7 @@ class CompilerBase extends \PhpAot\Core\Translator } elseif ($type === self::TYPE_STD_VECTOR) { $info = $this->context->stdContainers[$name]; if (isset($info['unsafePtr'])) { - $unsafePtrBox = $this->genTmpVarName(); - $code .= 'auto *' . $unsafePtrBox . ' = ' . $info['unsafePtr'] . '.toBox();' . PHP_EOL; - $code .= $this->getIndent() . 'if (UNEXPECTED(' . $unsafePtrBox . '->type_id != ' . $info['typeId'] . ')) {' . PHP_EOL; - $code .= $this->getIndent() . ' php::throwException("RuntimeException", "std::unsafe_cast(): UnsafePtr type mismatch");' . PHP_EOL; - $code .= $this->getIndent() . '}' . PHP_EOL; - $code .= $this->getIndent(); - $code .= 'auto &' . $name . ' = *reinterpret_cast<' . $info['decl'] . '*>(' . $unsafePtrBox . '->ptr);'; + $code .= 'auto &' . $name . ' = php_unsafe_cast<' . $info['decl'] . '>(' . $info['unsafePtr'] . ', ' . $info['typeId'] . ');'; } else { $code .= $info['decl'] . ' ' . $name; if ($info['size'] !== null) { @@ -5517,13 +5505,7 @@ class CompilerBase extends \PhpAot\Core\Translator } elseif ($type === self::TYPE_STD_MAP || $type === self::TYPE_STD_UNORDERED_MAP) { $info = $this->context->stdContainers[$name]; if (isset($info['unsafePtr'])) { - $unsafePtrBox = $this->genTmpVarName(); - $code .= 'auto *' . $unsafePtrBox . ' = ' . $info['unsafePtr'] . '.toBox();' . PHP_EOL; - $code .= $this->getIndent() . 'if (UNEXPECTED(' . $unsafePtrBox . '->type_id != ' . $info['typeId'] . ')) {' . PHP_EOL; - $code .= $this->getIndent() . ' php::throwException("RuntimeException", "std::unsafe_cast(): UnsafePtr type mismatch");' . PHP_EOL; - $code .= $this->getIndent() . '}' . PHP_EOL; - $code .= $this->getIndent(); - $code .= 'auto &' . $name . ' = *reinterpret_cast<' . $info['decl'] . '*>(' . $unsafePtrBox . '->ptr);'; + $code .= 'auto &' . $name . ' = php_unsafe_cast<' . $info['decl'] . '>(' . $info['unsafePtr'] . ', ' . $info['typeId'] . ');'; } else { $code .= $info['decl'] . ' ' . $name . '{};'; } diff --git a/src/Php/Parser/StdContainerParser.php b/src/Php/Parser/StdContainerParser.php index 04d126ac..6fa54879 100644 --- a/src/Php/Parser/StdContainerParser.php +++ b/src/Php/Parser/StdContainerParser.php @@ -422,7 +422,7 @@ trait StdContainerParser $this->addLocalVar($var, self::TYPE_STD_ARRAY); $this->parseStdArray($var, $typeExpr); $this->context->stdArrays[$var]['unsafePtr'] = $unsafePtr; - return '// reinterpret_cast<' . $this->context->stdArrays[$var]['decl'] . '*>(' . $unsafePtr . ')'; + return '// php_unsafe_cast<' . $this->context->stdArrays[$var]['decl'] . '>(' . $unsafePtr . ')'; } if ($containerType === 'vector') { @@ -436,7 +436,7 @@ trait StdContainerParser $this->parseStdUnorderedMap($var, $typeExpr); } $this->context->stdContainers[$var]['unsafePtr'] = $unsafePtr; - return '// reinterpret_cast<' . $this->context->stdContainers[$var]['decl'] . '*>(' . $unsafePtr . ')'; + return '// php_unsafe_cast<' . $this->context->stdContainers[$var]['decl'] . '>(' . $unsafePtr . ')'; } protected function parseStdMapKeyType(NodeAbstract $expr, string $owner): string diff --git a/tests/aot/std-array/008.phpt b/tests/aot/std-array/008.phpt new file mode 100644 index 00000000..d95dc6c9 --- /dev/null +++ b/tests/aot/std-array/008.phpt @@ -0,0 +1,22 @@ +--TEST-- +std array: unsafe_cast type mismatch +--FILE-- +getMessage(), "\n"; + } +} +?> +--EXPECT-- +std::unsafe_cast(): UnsafePtr type mismatch diff --git a/tests/aot/std-map/006.phpt b/tests/aot/std-map/006.phpt new file mode 100644 index 00000000..8a21f7c4 --- /dev/null +++ b/tests/aot/std-map/006.phpt @@ -0,0 +1,22 @@ +--TEST-- +std map: unsafe_cast type mismatch +--FILE-- +getMessage(), "\n"; + } +} +?> +--EXPECT-- +std::unsafe_cast(): UnsafePtr type mismatch diff --git a/tests/aot/std-unordered-map/006.phpt b/tests/aot/std-unordered-map/006.phpt new file mode 100644 index 00000000..b85ae61e --- /dev/null +++ b/tests/aot/std-unordered-map/006.phpt @@ -0,0 +1,22 @@ +--TEST-- +std unordered map: unsafe_cast type mismatch +--FILE-- +getMessage(), "\n"; + } +} +?> +--EXPECT-- +std::unsafe_cast(): UnsafePtr type mismatch diff --git a/tests/aot/std-vector/007.phpt b/tests/aot/std-vector/007.phpt index 1aa8d0d1..5855c0da 100644 --- a/tests/aot/std-vector/007.phpt +++ b/tests/aot/std-vector/007.phpt @@ -13,7 +13,7 @@ function main() { try { std_vector_unsafe_ptr_type_mismatch($ptr); - } catch (RuntimeException $e) { + } catch (TypeError $e) { echo $e->getMessage(), "\n"; } } diff --git a/tests/aot/std-vector/008.phpt b/tests/aot/std-vector/008.phpt index a2cc2fb5..95d2e843 100644 --- a/tests/aot/std-vector/008.phpt +++ b/tests/aot/std-vector/008.phpt @@ -21,7 +21,7 @@ function main() { try { std_vector_unsafe_ptr_class_type_mismatch($ptr); - } catch (RuntimeException $e) { + } catch (TypeError $e) { echo $e->getMessage(), "\n"; } }