diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 491a89f5..6266b229 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -70,6 +70,7 @@ class CompilerBase extends \PhpAot\Core\Translator public const string VALUE_NAN = 'std::numeric_limits::quiet_NaN()'; public const string VALUE_INF = 'std::numeric_limits::infinity()'; public const string VALUE_NULL = 'php::null'; + public const string VALUE_ZERO = 'php::zero'; public const string LITERAL_STRINGS = '_literal_strings'; public const string ANON_CLASS = '_anon_class_'; public const string STATIC_VAR = '_static_var_'; @@ -956,6 +957,19 @@ class CompilerBase extends \PhpAot\Core\Translator return $list; } + protected function parseArrayKey(NodeAbstract $expr): string + { + $key = $this->parseIdentifier($expr); + if (str_starts_with($key, self::LITERAL_STRINGS)) { + $key = "{$key}.str()"; + } elseif ($key === '0L') { + // 0 在 C++ 中是一个特殊的值,存在二义性,既是空指针,也是整数,这会导致产生 ambiguous 错误 + // 必须转为 php::zero 常量,保证作为 key 时正确匹配到 IntKeyMap + $key = self::VALUE_ZERO; + } + return $key; + } + protected function parseIdentifier(NodeAbstract $expr): string { $type = $expr->getType(); @@ -1941,14 +1955,8 @@ class CompilerBase extends \PhpAot\Core\Translator foreach ($items as $item) { $value = $this->parseIdentifier($item->value); if ($item->key) { - $key = $this->parseIdentifier($item->key); - if (str_starts_with($key, self::LITERAL_STRINGS)) { - $key = "{$key}.toStdString()"; - } elseif ($key === '0L') { - $key = 'php::zero'; - } - $list[] = $this->getIndent() . '{ ' . $key . ', ' . - self::TYPE_VAR . '(' . $value . ') }'; + $key = $this->parseArrayKey($item->key); + $list[] = $this->getIndent() . '{ ' . $key . ', ' . self::TYPE_VAR . '(' . $value . ') }'; } else { $list[] = $this->getIndent() . self::TYPE_VAR . '(' . $value . ')'; } @@ -4858,12 +4866,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($item->unpack) { $this->context->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.merge(' . $value . ');'; } elseif ($item->key) { - $key = $this->parseIdentifier($item->key); - if (str_starts_with($key, self::LITERAL_STRINGS)) { - $key = "{$key}.toStdString()"; - } elseif ($key === '0L') { - $key = 'php::zero'; - } + $key = $this->parseArrayKey($item->key); $this->context->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.set(' . $key . ', ' . $value . ');'; } else { $this->context->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.append(' . $value . ');'; diff --git a/tests/aot/array_001.phpt b/tests/aot/array/001.phpt similarity index 100% rename from tests/aot/array_001.phpt rename to tests/aot/array/001.phpt diff --git a/tests/aot/array_002.phpt b/tests/aot/array/002.phpt similarity index 100% rename from tests/aot/array_002.phpt rename to tests/aot/array/002.phpt diff --git a/tests/aot/array/003.phpt b/tests/aot/array/003.phpt new file mode 100644 index 00000000..1d9b2915 --- /dev/null +++ b/tests/aot/array/003.phpt @@ -0,0 +1,22 @@ +--TEST-- +Array 003 +--FILE-- + 'foo', + 1000 => 'bar', + 0 => 'baz', +]; +var_dump($array2); +?> +--EXPECT-- +array(3) { + [100]=> + string(3) "foo" + [1000]=> + string(3) "bar" + [0]=> + string(3) "baz" +} \ No newline at end of file diff --git a/tests/aot/array/004.phpt b/tests/aot/array/004.phpt new file mode 100644 index 00000000..26eb095b --- /dev/null +++ b/tests/aot/array/004.phpt @@ -0,0 +1,18 @@ +--TEST-- +Array 003 +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "bar" + [2]=> + string(3) "baz" +} \ No newline at end of file diff --git a/tests/aot/array/005.phpt b/tests/aot/array/005.phpt new file mode 100644 index 00000000..eedd9aa2 --- /dev/null +++ b/tests/aot/array/005.phpt @@ -0,0 +1,18 @@ +--TEST-- +Array 003 +--FILE-- + 100, 'bar' => 'php', 'baz' => true, +]; +var_dump($array2); +?> +--EXPECT-- +array(3) { + ["foo"]=> + int(100) + ["bar"]=> + string(3) "php" + ["baz"]=> + bool(true) +} \ No newline at end of file diff --git a/tests/aot/array_003.phpt b/tests/aot/array_003.phpt deleted file mode 100644 index 070c22cc..00000000 --- a/tests/aot/array_003.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -Array 003 ---FILE-- - 'foo', - 1000 => 'bar', -]; -var_dump(count($array2)); -?> ---EXPECT-- -int(2) \ No newline at end of file