diff --git a/examples/micro_bench.php b/examples/micro_bench.php index be713990..b20d0d53 100644 --- a/examples/micro_bench.php +++ b/examples/micro_bench.php @@ -18,7 +18,7 @@ function hallo2() { function simpleicall($n) { for ($i = 0; $i < $n; $i++) - function_exists('hallo'); + $ret = function_exists('hallo'); } class Foo { @@ -287,74 +287,74 @@ function main() empty_loop(N); $t = end_test($t, 'empty_loop'); $overhead = $last_time; - simpleucall(N); - $t = end_test($t, 'func()', $overhead); - simpleudcall(N); - $t = end_test($t, 'undef_func()', $overhead); +// simpleucall(N); +// $t = end_test($t, 'func()', $overhead); +// simpleudcall(N); +// $t = end_test($t, 'undef_func()', $overhead); simpleicall(N); $t = end_test($t, 'int_func()', $overhead); - Foo::read_static(N); - $t = end_test($t, '$x = self::$x', $overhead); - Foo::write_static(N); - $t = end_test($t, 'self::$x = 0', $overhead); - Foo::isset_static(N); - $t = end_test($t, 'isset(self::$x)', $overhead); - Foo::empty_static(N); - $t = end_test($t, 'empty(self::$x)', $overhead); - read_static(N); - $t = end_test($t, '$x = Foo::$x', $overhead); - write_static(N); - $t = end_test($t, 'Foo::$x = 0', $overhead); - isset_static(N); - $t = end_test($t, 'isset(Foo::$x)', $overhead); - empty_static(N); - $t = end_test($t, 'empty(Foo::$x)', $overhead); - Foo::call_static(N); - $t = end_test($t, 'self::f()', $overhead); - call_static(N); - $t = end_test($t, 'Foo::f()', $overhead); - $x = new Foo(); - $x->read_prop(N); - $t = end_test($t, '$x = $this->x', $overhead); - $x->write_prop(N); - $t = end_test($t, '$this->x = 0', $overhead); - $x->assign_add_prop(N); - $t = end_test($t, '$this->x += 2', $overhead); - $x->pre_inc_prop(N); - $t = end_test($t, '++$this->x', $overhead); - $x->pre_dec_prop(N); - $t = end_test($t, '--$this->x', $overhead); - $x->post_inc_prop(N); - $t = end_test($t, '$this->x++', $overhead); - $x->post_dec_prop(N); - $t = end_test($t, '$this->x--', $overhead); - $x->isset_prop(N); - $t = end_test($t, 'isset($this->x)', $overhead); - $x->empty_prop(N); - $t = end_test($t, 'empty($this->x)', $overhead); - $x->call(N); - $t = end_test($t, '$this->f()', $overhead); - $x->read_const(N); - $t = end_test($t, '$x = Foo::TEST', $overhead); - create_object(N); - $t = end_test($t, 'new Foo()', $overhead); - read_const(N); - $t = end_test($t, '$x = TEST', $overhead); - read_auto_global(N); - $t = end_test($t, '$x = $_GET', $overhead); - read_global_var(N); - $t = end_test($t, '$x = $GLOBALS[\'v\']', $overhead); - read_hash(N); - $t = end_test($t, '$x = $hash[\'v\']', $overhead); - read_str_offset(N); - $t = end_test($t, '$x = $str[0]', $overhead); - issetor(N); - $t = end_test($t, '$x = $a ?: null', $overhead); - issetor2(N); - $t = end_test($t, '$x = $f ?: tmp', $overhead); - ternary(N); - $t = end_test($t, '$x = $f ? $f : $a', $overhead); - ternary2(N); - $t = end_test($t, '$x = $f ? $f : tmp', $overhead); +// Foo::read_static(N); +// $t = end_test($t, '$x = self::$x', $overhead); +// Foo::write_static(N); +// $t = end_test($t, 'self::$x = 0', $overhead); +// Foo::isset_static(N); +// $t = end_test($t, 'isset(self::$x)', $overhead); +// Foo::empty_static(N); +// $t = end_test($t, 'empty(self::$x)', $overhead); +// read_static(N); +// $t = end_test($t, '$x = Foo::$x', $overhead); +// write_static(N); +// $t = end_test($t, 'Foo::$x = 0', $overhead); +// isset_static(N); +// $t = end_test($t, 'isset(Foo::$x)', $overhead); +// empty_static(N); +// $t = end_test($t, 'empty(Foo::$x)', $overhead); +// Foo::call_static(N); +// $t = end_test($t, 'self::f()', $overhead); +// call_static(N); +// $t = end_test($t, 'Foo::f()', $overhead); +// $x = new Foo(); +// $x->read_prop(N); +// $t = end_test($t, '$x = $this->x', $overhead); +// $x->write_prop(N); +// $t = end_test($t, '$this->x = 0', $overhead); +// $x->assign_add_prop(N); +// $t = end_test($t, '$this->x += 2', $overhead); +// $x->pre_inc_prop(N); +// $t = end_test($t, '++$this->x', $overhead); +// $x->pre_dec_prop(N); +// $t = end_test($t, '--$this->x', $overhead); +// $x->post_inc_prop(N); +// $t = end_test($t, '$this->x++', $overhead); +// $x->post_dec_prop(N); +// $t = end_test($t, '$this->x--', $overhead); +// $x->isset_prop(N); +// $t = end_test($t, 'isset($this->x)', $overhead); +// $x->empty_prop(N); +// $t = end_test($t, 'empty($this->x)', $overhead); +// $x->call(N); +// $t = end_test($t, '$this->f()', $overhead); +// $x->read_const(N); +// $t = end_test($t, '$x = Foo::TEST', $overhead); +// create_object(N); +// $t = end_test($t, 'new Foo()', $overhead); +// read_const(N); +// $t = end_test($t, '$x = TEST', $overhead); +// read_auto_global(N); +// $t = end_test($t, '$x = $_GET', $overhead); +// read_global_var(N); +// $t = end_test($t, '$x = $GLOBALS[\'v\']', $overhead); +// read_hash(N); +// $t = end_test($t, '$x = $hash[\'v\']', $overhead); +// read_str_offset(N); +// $t = end_test($t, '$x = $str[0]', $overhead); +// issetor(N); +// $t = end_test($t, '$x = $a ?: null', $overhead); +// issetor2(N); +// $t = end_test($t, '$x = $f ?: tmp', $overhead); +// ternary(N); +// $t = end_test($t, '$x = $f ? $f : $a', $overhead); +// ternary2(N); +// $t = end_test($t, '$x = $f ? $f : tmp', $overhead); total(); } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0b03f07b..d17b0ced 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -607,11 +607,11 @@ class CompilerBase extends \PhpAot\Core\Translator if (isset($this->classMap[$className])) { $id = $this->classMap[$className]; } else { - $id = $this->classIndex++; + $id = $this->classIndex++; $this->classMap[$className] = $id; } - return 'php_get_class(' . $id . ', "' . $this->escapeString($className) . '")'; + return 'php_get_class(' . $id . ', ' . $this->getLiteralString($className) . ')'; } protected function getFuncPtr(string $funcName): string @@ -622,7 +622,7 @@ class CompilerBase extends \PhpAot\Core\Translator $id = $this->funcIndex++; $this->funcMap[$funcName] = $id; } - return $id . ', "' . $this->escapeString($funcName) . '"'; + return $id . ', ' . $this->getLiteralString($funcName); } protected function parseFunctionDeclaration(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef @@ -712,7 +712,16 @@ class CompilerBase extends \PhpAot\Core\Translator } } - protected function parseScalar(Node $expr) + protected function getLiteralString(string $string): string + { + if ($this->noLiteralStrings) { + return '"' . $this->escapeString($string) . '"'; + } + $index = $this->literalStrings[$string] ?? $this->addLiteralString($string); + return self::LITERAL_STRINGS . '[' . $index . ']'; + } + + protected function parseScalar(Node\Scalar $expr) { $type = $expr->getType(); switch ($type) { @@ -721,13 +730,7 @@ class CompilerBase extends \PhpAot\Core\Translator case 'Scalar_Float': return $this->parseScalarFloat($expr); case 'Scalar_String': - if ($this->noLiteralStrings) { - return '"' . $this->escapeString($expr->value) . '"'; - } - $index = $this->literalStrings[$expr->value] ?? $this->addLiteralString($expr->value); - - return self::LITERAL_STRINGS . '[' . $index . ']'; - + return $this->getLiteralString($expr->value); default: abort($expr); } diff --git a/src/Php/FuncCallOptimizer.php b/src/Php/FuncCallOptimizer.php index e9c3cf3c..f1f95807 100644 --- a/src/Php/FuncCallOptimizer.php +++ b/src/Php/FuncCallOptimizer.php @@ -44,6 +44,9 @@ trait FuncCallOptimizer if ($name === 'abs') { return 'php::math::abs(' . $this->parseIdentifier($expr->args[0]->value) . ')'; } + if ($name === 'function_exists') { + return 'php::fn::function_exists(' . $this->parseIdentifier($expr->args[0]->value) . ')'; + } return false; } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 7b553775..e2a64956 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -197,7 +197,7 @@ class Translator extends Preprocessor } $literalStringsCount = count($this->literalStrings); - $lines[] = 'extern php::Var ' . self::LITERAL_STRINGS . '[' . $literalStringsCount . '];' . PHP_EOL; + $lines[] = 'extern ' . self::TYPE_STR . ' ' . self::LITERAL_STRINGS . '[' . $literalStringsCount . '];' . PHP_EOL; $classCount = count($this->classMap); $lines[] = 'extern zend_class_entry *' . self::PREFIX . self::CLASS_MAP . '[' . $classCount . '];' . PHP_EOL; diff --git a/src/cpp/php_aot_helper.h b/src/cpp/php_aot_helper.h index 76136713..2a38e580 100644 --- a/src/cpp/php_aot_helper.h +++ b/src/cpp/php_aot_helper.h @@ -1,20 +1,20 @@ #include -extern zend_class_entry *php_get_class(int class_id, const char *class_name); -extern zend_function *php_get_func(int func_id, const char *func_name); +extern zend_class_entry *php_get_class(int class_id, const php::String &class_name); +extern zend_function *php_get_func(int func_id, const php::String &func_name); -static inline php::Variant CALL(int func_id, const char *func_name, const std::initializer_list &args) { +static inline php::Variant CALL(int func_id, const php::String &func_name, const std::initializer_list &args) { return php::call(php_get_func(func_id, func_name), args); } -static inline php::Variant CALL(int func_id, const char *func_name) { +static inline php::Variant CALL(int func_id, const php::String &func_name) { return php::call(php_get_func(func_id, func_name)); } -static inline php::Variant CALL_SILENT(int func_id, const char *func_name, const std::initializer_list &args) { +static inline php::Variant CALL_SILENT(int func_id, const php::String &func_name, const std::initializer_list &args) { return php::silentCall(php_get_func(func_id, func_name), args); } -static inline php::Variant CALL_SILENT(int func_id, const char *func_name) { +static inline php::Variant CALL_SILENT(int func_id, const php::String &func_name) { return php::silentCall(php_get_func(func_id, func_name)); } diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index 43750218..5f3d0a7e 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -27,14 +27,14 @@ zend_class_entry *funcMap) . ']' ?>; -zend_class_entry *php_get_class(int class_id, const char *class_name) { +zend_class_entry *php_get_class(int class_id, const php::String &class_name) { if (UNEXPECTED([class_id] == nullptr)) { [class_id] = php::getClassEntrySafe(class_name); } return [class_id]; } -zend_function *php_get_func(int func_id, const char *func_name) { +zend_function *php_get_func(int func_id, const php::String &func_name) { if (UNEXPECTED([func_id] == nullptr)) { [func_id] = php::getFunction(func_name); } @@ -42,7 +42,7 @@ zend_function *php_get_func(int func_id, const char *func_name) { } // literal strings -php::Var [] = { +php::Str [] = { literalStrings as $str => $index): ?>