diff --git a/bin/gen_stub.php b/bin/gen_stub.php index fe1fc7d4..fda459b4 100755 --- a/bin/gen_stub.php +++ b/bin/gen_stub.php @@ -2546,7 +2546,7 @@ abstract class VariableLike } $classTypeCount = count($arginfoType->classTypes); - $code .= "\tzend_type_list *{$variableLikeType}_{$variableLikeName}_type_list = malloc(ZEND_TYPE_LIST_SIZE($classTypeCount));\n"; + $code .= "\tzend_type_list *{$variableLikeType}_{$variableLikeName}_type_list = (zend_type_list *) malloc(ZEND_TYPE_LIST_SIZE($classTypeCount));\n"; $code .= "\t{$variableLikeType}_{$variableLikeName}_type_list->num_types = $classTypeCount;\n"; foreach ($arginfoType->classTypes as $k => $classType) { diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 6b7b792d..65ff247f 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -461,38 +461,6 @@ class CompilerBase extends \PhpAot\Core\Translator } } - public function isClosedCall($expr, $call): bool - { - if ($call === '') { - if (!str_starts_with($expr, '(')) { - return false; - } - $startPos = 0; - } else { - if (!str_starts_with($expr, $call . '(')) { - return false; - } - $startPos = strlen($call); - } - - $bracketCount = 0; - $length = strlen($expr); - - for ($i = $startPos; $i < $length; $i++) { - $char = $expr[$i]; - if ($char === '(') { - $bracketCount++; - } elseif ($char === ')') { - $bracketCount--; - if ($bracketCount === 0) { - return $i === $length - 1; - } - } - } - - return false; - } - public function stop(string $string): never { $this->climate->red($string . "\n"); @@ -2416,18 +2384,9 @@ class CompilerBase extends \PhpAot\Core\Translator return $code; } - protected function trimBrackets(string $str): string - { - if ($this->isClosedCall($str, '')) { - return substr($str, 1, -1); - } - - return $str; - } - protected function convertIntExpr(string $expr): string { - if (!$this->isClosedCall($expr, 'php::toInt')) { + if (!$this->isClosedExpr($expr, 'php::toInt')) { return 'php::toInt(' . $this->trimBrackets($expr) . ')'; } @@ -2436,7 +2395,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function convertFloatExpr(string $expr): string { - if (!$this->isClosedCall($expr, 'php::toFloat')) { + if (!$this->isClosedExpr($expr, 'php::toFloat')) { return 'php::toFloat(' . $this->trimBrackets($expr) . ')'; } @@ -2445,7 +2404,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function convertStringExpr(string $expr): string { - if (!$this->isClosedCall($expr, 'php::toString')) { + if (!$this->isClosedExpr($expr, 'php::toString')) { return 'php::toString(' . $this->trimBrackets($expr) . ')'; } @@ -2454,7 +2413,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function convertObjectExpr(string $expr, string $class = ''): string { - if (!$this->isClosedCall($expr, 'php::toObject')) { + if (!$this->isClosedExpr($expr, 'php::toObject')) { if ($class === '') { return 'php::toObject(' . $this->trimBrackets($expr) . ')'; } @@ -2466,7 +2425,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function convertArrayExpr(string $expr): string { - if (!$this->isClosedCall($expr, 'php::toArray')) { + if (!$this->isClosedExpr($expr, 'php::toArray')) { return 'php::toArray(' . $this->trimBrackets($expr) . ')'; } @@ -2475,7 +2434,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function convertBoolExpr(string $expr): string { - if (!$this->isClosedCall($expr, 'php::toBool')) { + if (!$this->isClosedExpr($expr, 'php::toBool')) { return 'php::toBool(' . $this->trimBrackets($expr) . ')'; } @@ -2696,57 +2655,6 @@ class CompilerBase extends \PhpAot\Core\Translator return 'php::concat({' . implode(', ', $list) . '})'; } - protected function escapeString(string $str): string - { - return addcslashes($str, "\\\"\n\r\t\v\f\0\x01..\x1f\x7f..\xff"); - } - - protected function escapeBool(bool $bool): string - { - return $bool ? 'true' : 'false'; - } - - protected function escapeVarName(string $name): string - { - if (in_array($name, Constants::CPP_RESERVED_NAMES)) { - return '_php__var__' . $name; - } - if ($name === 'this') { - return 'this_'; - } - return $name; - } - - protected function escapeNamespace(string $ns): string - { - return str_replace('\\', self::NAMESPACE_SEPARATOR, strtolower($ns)); - } - - protected function escapeZendFnName(string $fn): string - { - return str_replace('\\', '_', strtolower($fn)); - } - - protected function escapeName(string $name): string - { - return strtolower($name); - } - - protected function escapeClass(string $class): string - { - return str_replace('\\', '_', trim(strtolower($class), '\\')); - } - - protected function escapeFileName(string $file): string - { - return str_replace('-', '_', $file); - } - - protected function unescapeVarName(string $name): string - { - return str_replace('_php__var__', '', $name); - } - protected function parseInterpolatedStringPart(Node $expr): string { return '"' . $this->escapeString($expr->value) . '"'; diff --git a/src/Php/Entity/ClassLikeDef.php b/src/Php/Entity/ClassLikeDef.php index ade9c4b7..c3ad921d 100644 --- a/src/Php/Entity/ClassLikeDef.php +++ b/src/Php/Entity/ClassLikeDef.php @@ -29,6 +29,6 @@ class ClassLikeDef return str_replace('\\', '_', $this->namespace . '_' . $this->name); } - return $this->namespace . '\\\\' . $this->name; + return $this->namespace . '\\' . $this->name; } } diff --git a/src/Php/Generator/ClosureGenerator.php b/src/Php/Generator/ClosureGenerator.php index 5b86babf..f53ba13d 100644 --- a/src/Php/Generator/ClosureGenerator.php +++ b/src/Php/Generator/ClosureGenerator.php @@ -32,9 +32,14 @@ trait ClosureGenerator $this->localVars = []; } + $oriObjects = $this->objects; + $oriObjectWrappers = $this->objectWrappers; $oriArgs = $this->arguments; - $this->arguments = []; $oriInClosure = $this->inClosure; + + $this->objects = []; + $this->objectWrappers = []; + $this->arguments = []; $this->inClosure = true; $this->indentLevel++; @@ -67,6 +72,9 @@ trait ClosureGenerator if (!$useCurrentScope) { $this->localVars = $oriLocalVars; } + + $this->objects = $oriObjects; + $this->objectWrappers = $oriObjectWrappers; $this->arguments = $oriArgs; $this->inClosure = $oriInClosure; diff --git a/src/Php/Generator/Utils.php b/src/Php/Generator/Utils.php index bc510c2a..31789a5b 100644 --- a/src/Php/Generator/Utils.php +++ b/src/Php/Generator/Utils.php @@ -9,16 +9,114 @@ namespace PhpAot\Php\Generator; use PhpAot\Php\CompilerBase; +use PhpAot\Php\Constants; trait Utils { - protected function genCharPtr(string $str): string + protected function genCharPtr(string $str, bool $escape = false): string { - return '"' . $str . '"'; + return '"' . ($escape ? $this->escapeString($str) : $str) . '"'; } protected function genArray(array $elements): string { return CompilerBase::TYPE_ARRAY . '{' . implode(', ', $elements) . ' }'; } + + protected function genRawStr(string $str): string + { + return 'R"(' . $str . ')"'; + } + + protected function escapeString(string $str): string + { + return addcslashes($str, "\\\"\n\r\t\v\f\0\x01..\x1f\x7f..\xff"); + } + + protected function escapeBool(bool $bool): string + { + return $bool ? 'true' : 'false'; + } + + protected function escapeVarName(string $name): string + { + if (in_array($name, Constants::CPP_RESERVED_NAMES)) { + return '_php__var__' . $name; + } + if ($name === 'this') { + return 'this_'; + } + return $name; + } + + protected function escapeNamespace(string $ns): string + { + return str_replace('\\', self::NAMESPACE_SEPARATOR, strtolower($ns)); + } + + protected function escapeZendFnName(string $fn): string + { + return str_replace('\\', '_', strtolower($fn)); + } + + protected function escapeName(string $name): string + { + return strtolower($name); + } + + protected function escapeClass(string $class): string + { + return str_replace('\\', '_', trim(strtolower($class), '\\')); + } + + protected function escapeFileName(string $file): string + { + return str_replace('-', '_', $file); + } + + protected function unescapeVarName(string $name): string + { + return str_replace('_php__var__', '', $name); + } + + protected function isClosedExpr($expr, $call): bool + { + if ($call === '') { + if (!str_starts_with($expr, '(')) { + return false; + } + $startPos = 0; + } else { + if (!str_starts_with($expr, $call . '(')) { + return false; + } + $startPos = strlen($call); + } + + $bracketCount = 0; + $length = strlen($expr); + + for ($i = $startPos; $i < $length; $i++) { + $char = $expr[$i]; + if ($char === '(') { + $bracketCount++; + } elseif ($char === ')') { + $bracketCount--; + if ($bracketCount === 0) { + return $i === $length - 1; + } + } + } + + return false; + } + + protected function trimBrackets(string $str): string + { + if ($this->isClosedExpr($str, '')) { + return substr($str, 1, -1); + } + + return $str; + } } diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index 76d6e897..c761cc8f 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -135,7 +135,7 @@ foreach ($this->globalVars as $name => $type): foreach ($this->classes as $classDef): foreach ($classDef->properties as $propertyDef): ?> - getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace)?> = php::getPropertyOffset("getNamespacedName(false)?>", "name?>"); + getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace)?> = php::getPropertyOffset(genCharPtr($classDef->getNamespacedName(false), true)?>, "name?>");