mirror of
https://github.com/php/php-src.git
synced 2024-11-23 01:44:06 +08:00
[RFC] Convert exit (and die) from language constructs to functions (#13483)
RFC: https://wiki.php.net/rfc/exit-as-function
This commit is contained in:
parent
02177848e4
commit
a79c70f574
@ -868,7 +868,6 @@ optimize_const_unary_op:
|
||||
break;
|
||||
|
||||
case ZEND_RETURN:
|
||||
case ZEND_EXIT:
|
||||
if (opline->op1_type == IS_TMP_VAR) {
|
||||
src = VAR_SOURCE(opline->op1);
|
||||
if (src && src->opcode == ZEND_QM_ASSIGN) {
|
||||
@ -1221,8 +1220,7 @@ static void zend_jmp_optimization(zend_basic_block *block, zend_op_array *op_arr
|
||||
target = op_array->opcodes + target_block->start;
|
||||
if ((target->opcode == ZEND_RETURN ||
|
||||
target->opcode == ZEND_RETURN_BY_REF ||
|
||||
target->opcode == ZEND_GENERATOR_RETURN ||
|
||||
target->opcode == ZEND_EXIT) &&
|
||||
target->opcode == ZEND_GENERATOR_RETURN) &&
|
||||
!(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
|
||||
/* JMP L, L: RETURN to immediate RETURN */
|
||||
*last_op = *target;
|
||||
|
@ -331,7 +331,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_GENERATOR_RETURN:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_THROW:
|
||||
case ZEND_MATCH_ERROR:
|
||||
case ZEND_CATCH:
|
||||
|
@ -88,8 +88,7 @@ void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
MAKE_NOP(opline);
|
||||
} else if ((target->opcode == ZEND_RETURN ||
|
||||
target->opcode == ZEND_RETURN_BY_REF ||
|
||||
target->opcode == ZEND_GENERATOR_RETURN ||
|
||||
target->opcode == ZEND_EXIT) &&
|
||||
target->opcode == ZEND_GENERATOR_RETURN) &&
|
||||
!(op_array->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
|
||||
/* JMP L, L: RETURN to immediate RETURN */
|
||||
*opline = *target;
|
||||
|
@ -162,10 +162,6 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
|
||||
call_info->send_unpack = 1;
|
||||
}
|
||||
break;
|
||||
case ZEND_EXIT:
|
||||
/* In this case the DO_CALL opcode may have been dropped
|
||||
* and caller_call_opline will be NULL. */
|
||||
break;
|
||||
}
|
||||
opline++;
|
||||
}
|
||||
|
@ -302,7 +302,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
|
||||
}
|
||||
break;
|
||||
case ZEND_MATCH_ERROR:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_THROW:
|
||||
/* Don't treat THROW as terminator if it's used in expression context,
|
||||
* as we may lose live ranges when eliminating unreachable code. */
|
||||
@ -506,7 +505,6 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
|
||||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_GENERATOR_RETURN:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_THROW:
|
||||
case ZEND_MATCH_ERROR:
|
||||
case ZEND_VERIFY_NEVER_TYPE:
|
||||
|
@ -6,6 +6,9 @@ function skipFunction($function): bool {
|
||||
|| $function === 'readline'
|
||||
|| $function === 'readline_read_history'
|
||||
|| $function === 'readline_write_history'
|
||||
/* terminates script */
|
||||
|| $function === 'exit'
|
||||
|| $function === 'die'
|
||||
/* intentionally violate invariants */
|
||||
|| $function === 'zend_create_unterminated_string'
|
||||
|| $function === 'zend_test_array_return'
|
||||
|
@ -1,13 +0,0 @@
|
||||
--TEST--
|
||||
Bug #79777: String cast exception during die should be handled gracefully
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
die(new stdClass);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Object of class stdClass could not be converted to string in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
16
Zend/tests/exit/ast_print_assert_die_const.phpt
Normal file
16
Zend/tests/exit/ast_print_assert_die_const.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Printing AST of die "constant" via assert
|
||||
--INI--
|
||||
zend.assertions=1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
assert(0 && die);
|
||||
} catch (Throwable $e) {
|
||||
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
AssertionError: assert(0 && \exit())
|
16
Zend/tests/exit/ast_print_assert_die_function.phpt
Normal file
16
Zend/tests/exit/ast_print_assert_die_function.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Printing AST of die function via assert
|
||||
--INI--
|
||||
zend.assertions=1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
assert(0 && die());
|
||||
} catch (Throwable $e) {
|
||||
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
AssertionError: assert(0 && \exit())
|
16
Zend/tests/exit/ast_print_assert_exit_const.phpt
Normal file
16
Zend/tests/exit/ast_print_assert_exit_const.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Printing AST of exit "constant" via assert
|
||||
--INI--
|
||||
zend.assertions=1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
assert(0 && exit);
|
||||
} catch (Throwable $e) {
|
||||
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
AssertionError: assert(0 && \exit())
|
16
Zend/tests/exit/ast_print_assert_exit_function.phpt
Normal file
16
Zend/tests/exit/ast_print_assert_exit_function.phpt
Normal file
@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
Printing AST of exit function via assert
|
||||
--INI--
|
||||
zend.assertions=1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
assert(0 && exit());
|
||||
} catch (Throwable $e) {
|
||||
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
AssertionError: assert(0 && \exit())
|
37
Zend/tests/exit/define_class_members_exit_die.phpt
Normal file
37
Zend/tests/exit/define_class_members_exit_die.phpt
Normal file
@ -0,0 +1,37 @@
|
||||
--TEST--
|
||||
Can define die and exit as class methods, constants and property
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo {
|
||||
public $exit;
|
||||
public $die;
|
||||
|
||||
const die = 5;
|
||||
const exit = 10;
|
||||
|
||||
public function exit() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
public function die() {
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
|
||||
var_dump(Foo::die);
|
||||
var_dump(Foo::exit);
|
||||
$o = new Foo();
|
||||
var_dump($o->exit);
|
||||
var_dump($o->die);
|
||||
var_dump($o->exit());
|
||||
var_dump($o->die());
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
int(5)
|
||||
int(10)
|
||||
NULL
|
||||
NULL
|
||||
int(20)
|
||||
int(15)
|
12
Zend/tests/exit/define_die_constant.phpt
Normal file
12
Zend/tests/exit/define_die_constant.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Attempting to define die constant
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
const die = 5;
|
||||
|
||||
var_dump(die);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d
|
14
Zend/tests/exit/define_die_constant_namespace.phpt
Normal file
14
Zend/tests/exit/define_die_constant_namespace.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Attempting to define die constant in a namespace
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace Foo;
|
||||
|
||||
const die = 5;
|
||||
|
||||
var_dump(die);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d
|
10
Zend/tests/exit/define_die_function.phpt
Normal file
10
Zend/tests/exit/define_die_function.phpt
Normal file
@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
Attempting to define die() function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function die() { }
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d
|
14
Zend/tests/exit/define_die_function_namespace.phpt
Normal file
14
Zend/tests/exit/define_die_function_namespace.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Attempting to define die() function in a namespace
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace Foo;
|
||||
|
||||
function die() { }
|
||||
|
||||
var_dump(die());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d
|
12
Zend/tests/exit/define_exit_constant.phpt
Normal file
12
Zend/tests/exit/define_exit_constant.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Attempting to define exit constant
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
const exit = 5;
|
||||
|
||||
var_dump(exit);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d
|
14
Zend/tests/exit/define_exit_constant_namespace.phpt
Normal file
14
Zend/tests/exit/define_exit_constant_namespace.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Attempting to define exit constant in a namespace
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace Foo;
|
||||
|
||||
const exit = 5;
|
||||
|
||||
var_dump(exit);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d
|
10
Zend/tests/exit/define_exit_function.phpt
Normal file
10
Zend/tests/exit/define_exit_function.phpt
Normal file
@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
Attempting to define exit() function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function exit() { }
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d
|
12
Zend/tests/exit/define_exit_function_namespace.phpt
Normal file
12
Zend/tests/exit/define_exit_function_namespace.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Attempting to define exit() function in a namespace
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
namespace Foo;
|
||||
|
||||
function exit() { }
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting "(" in %s on line %d
|
14
Zend/tests/exit/define_goto_label_die.phpt
Normal file
14
Zend/tests/exit/define_goto_label_die.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Attempting to define a goto label called die
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
echo "Before\n";
|
||||
|
||||
echo "In between\n";
|
||||
die:
|
||||
echo "After\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token ":" in %s on line %d
|
14
Zend/tests/exit/define_goto_label_die_with_jump.phpt
Normal file
14
Zend/tests/exit/define_goto_label_die_with_jump.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Attempting to define a goto label called die and jump to it
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
echo "Before\n";
|
||||
goto die;
|
||||
echo "In between\n";
|
||||
die:
|
||||
echo "After\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d
|
14
Zend/tests/exit/define_goto_label_exit.phpt
Normal file
14
Zend/tests/exit/define_goto_label_exit.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Attempting to define a goto label called exit
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
echo "Before\n";
|
||||
|
||||
echo "In between\n";
|
||||
exit:
|
||||
echo "After\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token ":" in %s on line %d
|
14
Zend/tests/exit/define_goto_label_exit_with_jump.phpt
Normal file
14
Zend/tests/exit/define_goto_label_exit_with_jump.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Attempting to define a goto label called exit and jump to it
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
echo "Before\n";
|
||||
goto exit;
|
||||
echo "In between\n";
|
||||
exit:
|
||||
echo "After\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parse error: syntax error, unexpected token "exit", expecting identifier in %s on line %d
|
14
Zend/tests/exit/die_string_cast_exception.phpt
Normal file
14
Zend/tests/exit/die_string_cast_exception.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug #79777: String cast exception during die should be handled gracefully
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
die(new stdClass);
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
exit(): Argument #1 ($code) must be of type string|int, stdClass given
|
12
Zend/tests/exit/disabling_die.phpt
Normal file
12
Zend/tests/exit/disabling_die.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Using disable_functions INI to remove die
|
||||
--INI--
|
||||
disable_functions=die
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
die();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Warning: Cannot disable function die() in Unknown on line 0
|
12
Zend/tests/exit/disabling_exit.phpt
Normal file
12
Zend/tests/exit/disabling_exit.phpt
Normal file
@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Using disable_functions INI to remove exit
|
||||
--INI--
|
||||
disable_functions=exit
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
exit();
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Warning: Cannot disable function exit() in Unknown on line 0
|
42
Zend/tests/exit/exit_as_function.phpt
Normal file
42
Zend/tests/exit/exit_as_function.phpt
Normal file
@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
exit() as function
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function foo(callable $fn) {
|
||||
var_dump($fn);
|
||||
}
|
||||
|
||||
$values = [
|
||||
'exit',
|
||||
'die',
|
||||
exit(...),
|
||||
die(...),
|
||||
];
|
||||
|
||||
foreach ($values as $value) {
|
||||
foo($value);
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
string(4) "exit"
|
||||
string(3) "die"
|
||||
object(Closure)#1 (2) {
|
||||
["function"]=>
|
||||
string(4) "exit"
|
||||
["parameter"]=>
|
||||
array(1) {
|
||||
["$code"]=>
|
||||
string(10) "<optional>"
|
||||
}
|
||||
}
|
||||
object(Closure)#2 (2) {
|
||||
["function"]=>
|
||||
string(4) "exit"
|
||||
["parameter"]=>
|
||||
array(1) {
|
||||
["$code"]=>
|
||||
string(10) "<optional>"
|
||||
}
|
||||
}
|
46
Zend/tests/exit/exit_statements.phpt
Normal file
46
Zend/tests/exit/exit_statements.phpt
Normal file
@ -0,0 +1,46 @@
|
||||
--TEST--
|
||||
Using exit/die as a statement/constant
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
const FILE_PATH = __DIR__ . '/exit_statements.php';
|
||||
const FILE_CONTENT = <<<'TEMPLATE'
|
||||
<?php
|
||||
echo "Before FUNCTION";
|
||||
try {
|
||||
FUNCTION;
|
||||
} catch (\Throwable $e) {
|
||||
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
TEMPLATE;
|
||||
|
||||
|
||||
$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED');
|
||||
$command = $php . ' ' . escapeshellarg(FILE_PATH);
|
||||
|
||||
foreach (['exit', 'die'] as $value) {
|
||||
echo 'Using ', $value, ' as value:', PHP_EOL;
|
||||
$output = [];
|
||||
$content = str_replace('FUNCTION', $value, FILE_CONTENT);
|
||||
file_put_contents(FILE_PATH, $content);
|
||||
exec($command, $output, $exit_status);
|
||||
echo 'Exit status is: ', $exit_status, PHP_EOL,
|
||||
'Output is:', PHP_EOL, join($output), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
const FILE_PATH = __DIR__ . '/exit_statements.php';
|
||||
@unlink(FILE_PATH);
|
||||
?>
|
||||
--EXPECT--
|
||||
Using exit as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
Before exit
|
||||
Using die as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
Before die
|
23
Zend/tests/exit/exit_string_with_buffer_output.phpt
Normal file
23
Zend/tests/exit/exit_string_with_buffer_output.phpt
Normal file
@ -0,0 +1,23 @@
|
||||
--TEST--
|
||||
Throwing output buffer with exit("Message")
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
ob_start(function ($text) {
|
||||
fwrite(STDOUT, "Handler: " . $text);
|
||||
throw new Exception('test');
|
||||
}, chunk_size: 10);
|
||||
|
||||
try {
|
||||
exit("Hello world!\n");
|
||||
} catch (Throwable $e) {
|
||||
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
echo "After?\n";
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Handler: Hello world!
|
||||
Hello world!
|
||||
Exception: test
|
||||
After?
|
183
Zend/tests/exit/exit_values.phpt
Normal file
183
Zend/tests/exit/exit_values.phpt
Normal file
@ -0,0 +1,183 @@
|
||||
--TEST--
|
||||
exit(false);
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function zend_test_var_export($value) {
|
||||
if ($value === PHP_INT_MIN) {
|
||||
return "PHP_INT_MIN";
|
||||
}
|
||||
if ($value === PHP_INT_MAX) {
|
||||
return "PHP_INT_MAX";
|
||||
}
|
||||
if (is_array($value)) {
|
||||
return "[]";
|
||||
}
|
||||
if (is_resource($value)) {
|
||||
return "STDERR";
|
||||
}
|
||||
if ($value instanceof stdClass) {
|
||||
return "new stdClass()";
|
||||
}
|
||||
return var_export($value, true);
|
||||
}
|
||||
|
||||
$values = [
|
||||
null,
|
||||
false,
|
||||
true,
|
||||
0,
|
||||
1,
|
||||
20,
|
||||
10.0,
|
||||
15.5,
|
||||
"Hello world",
|
||||
[],
|
||||
STDERR,
|
||||
new stdClass(),
|
||||
];
|
||||
|
||||
const FILE_PATH = __DIR__ . '/exit_values_test.php';
|
||||
const FILE_CONTENT = <<<'TEMPLATE'
|
||||
<?php
|
||||
try {
|
||||
exit(VALUE);
|
||||
} catch (\Throwable $e) {
|
||||
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
|
||||
}
|
||||
|
||||
TEMPLATE;
|
||||
|
||||
$php = getenv('TEST_PHP_EXECUTABLE_ESCAPED');
|
||||
$command = $php . ' ' . escapeshellarg(FILE_PATH);
|
||||
|
||||
foreach ([FILE_CONTENT, str_replace('exit', 'die', FILE_CONTENT)] as $code) {
|
||||
foreach ($values as $value) {
|
||||
echo 'Using ', zend_test_var_export($value), ' as value:', PHP_EOL;
|
||||
$output = [];
|
||||
$content = str_replace('VALUE', zend_test_var_export($value), $code);
|
||||
file_put_contents(FILE_PATH, $content);
|
||||
exec($command, $output, $exit_status);
|
||||
echo 'Exit status is: ', $exit_status, PHP_EOL,
|
||||
'Output is:', PHP_EOL, join($output), PHP_EOL;
|
||||
}
|
||||
|
||||
echo 'As a statement:', PHP_EOL;
|
||||
$output = [];
|
||||
$content = str_replace('(VALUE)', '', $code);
|
||||
exec($command, $output, $exit_status);
|
||||
echo 'Exit status is: ', $exit_status, PHP_EOL,
|
||||
'Output is:', PHP_EOL, join($output), PHP_EOL;
|
||||
}
|
||||
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
const FILE_PATH = __DIR__ . '/exit_values_test.php';
|
||||
@unlink(FILE_PATH);
|
||||
?>
|
||||
--EXPECTF--
|
||||
Using NULL as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
Deprecated: exit(): Passing null to parameter #1 ($code) of type string|int is deprecated in %s on line %d
|
||||
Using false as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
|
||||
Using true as value:
|
||||
Exit status is: 1
|
||||
Output is:
|
||||
|
||||
Using 0 as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
|
||||
Using 1 as value:
|
||||
Exit status is: 1
|
||||
Output is:
|
||||
|
||||
Using 20 as value:
|
||||
Exit status is: 20
|
||||
Output is:
|
||||
|
||||
Using 10.0 as value:
|
||||
Exit status is: 10
|
||||
Output is:
|
||||
|
||||
Using 15.5 as value:
|
||||
Exit status is: 15
|
||||
Output is:
|
||||
Deprecated: Implicit conversion from float 15.5 to int loses precision in %s on line %d
|
||||
Using 'Hello world' as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
Hello world
|
||||
Using [] as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
TypeError: exit(): Argument #1 ($code) must be of type string|int, array given
|
||||
Using STDERR as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
TypeError: exit(): Argument #1 ($code) must be of type string|int, resource given
|
||||
Using new stdClass() as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given
|
||||
As a statement:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given
|
||||
Using NULL as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
Deprecated: exit(): Passing null to parameter #1 ($code) of type string|int is deprecated in %s on line %d
|
||||
Using false as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
|
||||
Using true as value:
|
||||
Exit status is: 1
|
||||
Output is:
|
||||
|
||||
Using 0 as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
|
||||
Using 1 as value:
|
||||
Exit status is: 1
|
||||
Output is:
|
||||
|
||||
Using 20 as value:
|
||||
Exit status is: 20
|
||||
Output is:
|
||||
|
||||
Using 10.0 as value:
|
||||
Exit status is: 10
|
||||
Output is:
|
||||
|
||||
Using 15.5 as value:
|
||||
Exit status is: 15
|
||||
Output is:
|
||||
Deprecated: Implicit conversion from float 15.5 to int loses precision in %s on line %d
|
||||
Using 'Hello world' as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
Hello world
|
||||
Using [] as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
TypeError: exit(): Argument #1 ($code) must be of type string|int, array given
|
||||
Using STDERR as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
TypeError: exit(): Argument #1 ($code) must be of type string|int, resource given
|
||||
Using new stdClass() as value:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given
|
||||
As a statement:
|
||||
Exit status is: 0
|
||||
Output is:
|
||||
TypeError: exit(): Argument #1 ($code) must be of type string|int, stdClass given
|
@ -3605,6 +3605,13 @@ ZEND_API zend_result zend_set_hash_symbol(zval *symbol, const char *name, size_t
|
||||
|
||||
static void zend_disable_function(const char *function_name, size_t function_name_length)
|
||||
{
|
||||
if (UNEXPECTED(
|
||||
(function_name_length == strlen("exit") && !memcmp(function_name, "exit", strlen("exit")))
|
||||
|| (function_name_length == strlen("die") && !memcmp(function_name, "die", strlen("die")))
|
||||
)) {
|
||||
zend_error(E_WARNING, "Cannot disable function %s()", function_name);
|
||||
return;
|
||||
}
|
||||
zend_hash_str_del(CG(function_table), function_name, function_name_length);
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,33 @@ zend_result zend_startup_builtin_functions(void) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_FUNCTION(exit)
|
||||
{
|
||||
zend_string *str = NULL;
|
||||
zend_long code = 0;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(0, 1)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_STR_OR_LONG(str, code)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (str) {
|
||||
size_t len = ZSTR_LEN(str);
|
||||
if (len != 0) {
|
||||
/* An exception might be emitted by an output handler */
|
||||
zend_write(ZSTR_VAL(str), len);
|
||||
if (EG(exception)) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
EG(exit_status) = code;
|
||||
}
|
||||
|
||||
ZEND_ASSERT(!EG(exception));
|
||||
zend_throw_unwind_exit();
|
||||
}
|
||||
|
||||
/* {{{ Get the version of the Zend Engine */
|
||||
ZEND_FUNCTION(zend_version)
|
||||
{
|
||||
|
@ -7,6 +7,11 @@ class stdClass
|
||||
{
|
||||
}
|
||||
|
||||
function exit(string|int $code = 0): never {}
|
||||
|
||||
/** @alias exit */
|
||||
function die(string|int $code = 0): never {}
|
||||
|
||||
/** @refcount 1 */
|
||||
function zend_version(): string {}
|
||||
|
||||
|
11
Zend/zend_builtin_functions_arginfo.h
generated
11
Zend/zend_builtin_functions_arginfo.h
generated
@ -1,5 +1,11 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: c3bec3b17079456ef17e5c992995dcfbe62c6fe0 */
|
||||
* Stub hash: a6d7e59d6b7875ddc28ce828ae240c7dfd852023 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_exit, 0, 0, IS_NEVER, 0)
|
||||
ZEND_ARG_TYPE_MASK(0, code, MAY_BE_STRING|MAY_BE_LONG, "0")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_die arginfo_exit
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_version, 0, 0, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
@ -232,6 +238,7 @@ static const zend_frameless_function_info frameless_function_infos_class_exists[
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
ZEND_FUNCTION(exit);
|
||||
ZEND_FUNCTION(zend_version);
|
||||
ZEND_FUNCTION(func_num_args);
|
||||
ZEND_FUNCTION(func_get_arg);
|
||||
@ -292,6 +299,8 @@ ZEND_FUNCTION(gc_disable);
|
||||
ZEND_FUNCTION(gc_status);
|
||||
|
||||
static const zend_function_entry ext_functions[] = {
|
||||
ZEND_FE(exit, arginfo_exit)
|
||||
ZEND_RAW_FENTRY("die", zif_exit, arginfo_die, 0, NULL, NULL)
|
||||
ZEND_FE(zend_version, arginfo_zend_version)
|
||||
ZEND_FE(func_num_args, arginfo_func_num_args)
|
||||
ZEND_FE(func_get_arg, arginfo_func_get_arg)
|
||||
|
@ -10376,27 +10376,6 @@ static void zend_compile_print(znode *result, zend_ast *ast) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_compile_exit(znode *result, zend_ast *ast) /* {{{ */
|
||||
{
|
||||
zend_ast *expr_ast = ast->child[0];
|
||||
znode expr_node;
|
||||
|
||||
if (expr_ast) {
|
||||
zend_compile_expr(&expr_node, expr_ast);
|
||||
} else {
|
||||
expr_node.op_type = IS_UNUSED;
|
||||
}
|
||||
|
||||
zend_op *opline = zend_emit_op(NULL, ZEND_EXIT, &expr_node, NULL);
|
||||
if (result) {
|
||||
/* Mark this as an "expression throw" for opcache. */
|
||||
opline->extended_value = ZEND_THROW_IS_EXPR;
|
||||
result->op_type = IS_CONST;
|
||||
ZVAL_TRUE(&result->u.constant);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
|
||||
{
|
||||
zend_ast *value_ast = ast->child[0];
|
||||
@ -11366,7 +11345,6 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
|
||||
zend_compile_halt_compiler(ast);
|
||||
break;
|
||||
case ZEND_AST_THROW:
|
||||
case ZEND_AST_EXIT:
|
||||
zend_compile_expr(NULL, ast);
|
||||
break;
|
||||
default:
|
||||
@ -11469,9 +11447,6 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */
|
||||
case ZEND_AST_PRINT:
|
||||
zend_compile_print(result, ast);
|
||||
return;
|
||||
case ZEND_AST_EXIT:
|
||||
zend_compile_exit(result, ast);
|
||||
return;
|
||||
case ZEND_AST_YIELD:
|
||||
zend_compile_yield(result, ast);
|
||||
return;
|
||||
|
@ -258,7 +258,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
|
||||
%type <ast> absolute_trait_method_reference trait_method_reference property echo_expr
|
||||
%type <ast> new_dereferenceable new_non_dereferenceable anonymous_class class_name class_name_reference simple_variable
|
||||
%type <ast> internal_functions_in_yacc
|
||||
%type <ast> exit_expr scalar backticks_expr lexical_var function_call member_name property_name
|
||||
%type <ast> scalar backticks_expr lexical_var function_call member_name property_name
|
||||
%type <ast> variable_class_name dereferenceable_scalar constant class_constant
|
||||
%type <ast> fully_dereferenceable array_object_dereferenceable
|
||||
%type <ast> callable_expr callable_variable static_member new_variable
|
||||
@ -1304,7 +1304,11 @@ expr:
|
||||
| T_OBJECT_CAST expr { $$ = zend_ast_create_cast(IS_OBJECT, $2); }
|
||||
| T_BOOL_CAST expr { $$ = zend_ast_create_cast(_IS_BOOL, $2); }
|
||||
| T_UNSET_CAST expr { $$ = zend_ast_create_cast(IS_NULL, $2); }
|
||||
| T_EXIT exit_expr { $$ = zend_ast_create(ZEND_AST_EXIT, $2); }
|
||||
| T_EXIT ctor_arguments {
|
||||
zend_ast *name = zend_ast_create_zval_from_str(ZSTR_KNOWN(ZEND_STR_EXIT));
|
||||
name->attr = ZEND_NAME_FQ;
|
||||
$$ = zend_ast_create(ZEND_AST_CALL, name, $2);
|
||||
}
|
||||
| '@' expr { $$ = zend_ast_create(ZEND_AST_SILENCE, $2); }
|
||||
| scalar { $$ = $1; }
|
||||
| '`' backticks_expr '`' { $$ = zend_ast_create(ZEND_AST_SHELL_EXEC, $2); }
|
||||
@ -1407,11 +1411,6 @@ class_name_reference:
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
exit_expr:
|
||||
%empty { $$ = NULL; }
|
||||
| '(' optional_expr ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
backticks_expr:
|
||||
%empty
|
||||
{ $$ = zend_ast_create_zval_from_str(ZSTR_EMPTY_ALLOC()); }
|
||||
|
@ -572,6 +572,7 @@ EMPTY_SWITCH_DEFAULT_CASE()
|
||||
_(ZEND_STR_ARGS, "args") \
|
||||
_(ZEND_STR_UNKNOWN, "unknown") \
|
||||
_(ZEND_STR_UNKNOWN_CAPITALIZED, "Unknown") \
|
||||
_(ZEND_STR_EXIT, "exit") \
|
||||
_(ZEND_STR_EVAL, "eval") \
|
||||
_(ZEND_STR_INCLUDE, "include") \
|
||||
_(ZEND_STR_REQUIRE, "require") \
|
||||
|
@ -7610,38 +7610,6 @@ ZEND_VM_C_LABEL(array_key_exists_array):
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
ZEND_VM_COLD_HANDLER(79, ZEND_EXIT, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (OP1_TYPE != IS_UNUSED) {
|
||||
zval *ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
do {
|
||||
if (Z_TYPE_P(ptr) == IS_LONG) {
|
||||
EG(exit_status) = Z_LVAL_P(ptr);
|
||||
} else {
|
||||
if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) {
|
||||
ptr = Z_REFVAL_P(ptr);
|
||||
if (Z_TYPE_P(ptr) == IS_LONG) {
|
||||
EG(exit_status) = Z_LVAL_P(ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
zend_print_zval(ptr, 0);
|
||||
}
|
||||
} while (0);
|
||||
FREE_OP1();
|
||||
}
|
||||
|
||||
if (!EG(exception)) {
|
||||
zend_throw_unwind_exit();
|
||||
}
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
429
Zend/zend_vm_execute.h
generated
429
Zend/zend_vm_execute.h
generated
@ -3013,37 +3013,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_EXIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (opline->op1_type != IS_UNUSED) {
|
||||
zval *ptr = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R);
|
||||
|
||||
do {
|
||||
if (Z_TYPE_P(ptr) == IS_LONG) {
|
||||
EG(exit_status) = Z_LVAL_P(ptr);
|
||||
} else {
|
||||
if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_ISREF_P(ptr)) {
|
||||
ptr = Z_REFVAL_P(ptr);
|
||||
if (Z_TYPE_P(ptr) == IS_LONG) {
|
||||
EG(exit_status) = Z_LVAL_P(ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
zend_print_zval(ptr, 0);
|
||||
}
|
||||
} while (0);
|
||||
FREE_OP(opline->op1_type, opline->op1.var);
|
||||
}
|
||||
|
||||
if (!EG(exception)) {
|
||||
zend_throw_unwind_exit();
|
||||
}
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -7930,7 +7899,6 @@ array_key_exists_array:
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -10307,7 +10275,6 @@ array_key_exists_array:
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -12788,7 +12755,6 @@ array_key_exists_array:
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -16950,7 +16916,6 @@ array_key_exists_array:
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -18417,7 +18382,6 @@ array_key_exists_array:
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -19824,7 +19788,6 @@ array_key_exists_array:
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -45235,7 +45198,6 @@ array_key_exists_array:
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -48963,7 +48925,6 @@ array_key_exists_array:
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -54527,7 +54488,6 @@ array_key_exists_array:
|
||||
ZEND_VM_SMART_BRANCH(result, 1);
|
||||
}
|
||||
|
||||
/* No specialization for op_types (CONST|TMPVAR|UNUSED|CV, ANY) */
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
@ -56322,7 +56282,6 @@ ZEND_API void execute_ex(zend_execute_data *ex)
|
||||
(void*)&&ZEND_NULL_LABEL,
|
||||
(void*)&&ZEND_FE_RESET_R_SPEC_CV_LABEL,
|
||||
(void*)&&ZEND_FE_FETCH_R_SPEC_VAR_LABEL,
|
||||
(void*)&&ZEND_EXIT_SPEC_LABEL,
|
||||
(void*)&&ZEND_FETCH_R_SPEC_CONST_UNUSED_LABEL,
|
||||
(void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL,
|
||||
(void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL,
|
||||
@ -58572,11 +58531,6 @@ zend_leave_helper_SPEC_LABEL:
|
||||
ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC)
|
||||
HYBRID_BREAK();
|
||||
HYBRID_CASE(ZEND_EXIT_SPEC):
|
||||
VM_TRACE(ZEND_EXIT_SPEC)
|
||||
ZEND_EXIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
VM_TRACE_OP_END(ZEND_EXIT_SPEC)
|
||||
HYBRID_BREAK();
|
||||
HYBRID_CASE(ZEND_BEGIN_SILENCE_SPEC):
|
||||
VM_TRACE(ZEND_BEGIN_SILENCE_SPEC)
|
||||
ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
@ -65515,7 +65469,6 @@ void zend_vm_init(void)
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_FE_RESET_R_SPEC_CV_HANDLER,
|
||||
ZEND_FE_FETCH_R_SPEC_VAR_HANDLER,
|
||||
ZEND_EXIT_SPEC_HANDLER,
|
||||
ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER,
|
||||
ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER,
|
||||
ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER,
|
||||
@ -67460,7 +67413,7 @@ void zend_vm_init(void)
|
||||
1255,
|
||||
1256 | SPEC_RULE_OP1,
|
||||
1261 | SPEC_RULE_OP1,
|
||||
3487,
|
||||
3486,
|
||||
1266 | SPEC_RULE_OP1,
|
||||
1271 | SPEC_RULE_OP1,
|
||||
1276 | SPEC_RULE_OP2,
|
||||
@ -67494,100 +67447,101 @@ void zend_vm_init(void)
|
||||
1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1584 | SPEC_RULE_OP1,
|
||||
1589,
|
||||
1590,
|
||||
1591 | SPEC_RULE_OP1,
|
||||
1596 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1621 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1646 | SPEC_RULE_OP1,
|
||||
1651 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1676 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1701 | SPEC_RULE_OP1,
|
||||
1706 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1731 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1756 | SPEC_RULE_OP1,
|
||||
1761 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1786 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1811 | SPEC_RULE_OP1,
|
||||
1816 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1841 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1866 | SPEC_RULE_OP1,
|
||||
1871 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1896 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1921 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1946,
|
||||
1947 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG,
|
||||
3486,
|
||||
1590 | SPEC_RULE_OP1,
|
||||
1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1645 | SPEC_RULE_OP1,
|
||||
1650 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1675 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1700 | SPEC_RULE_OP1,
|
||||
1705 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1730 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1755 | SPEC_RULE_OP1,
|
||||
1760 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1785 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1810 | SPEC_RULE_OP1,
|
||||
1815 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1840 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1865 | SPEC_RULE_OP1,
|
||||
1870 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1895 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1920 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
1945,
|
||||
1946 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG,
|
||||
1956,
|
||||
1957,
|
||||
1958,
|
||||
1959,
|
||||
1960,
|
||||
1961,
|
||||
1962 | SPEC_RULE_OP2,
|
||||
1967,
|
||||
1968 | SPEC_RULE_OP1,
|
||||
1973 | SPEC_RULE_OP2,
|
||||
1978 | SPEC_RULE_OP1,
|
||||
1983 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
|
||||
1993 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2018 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2043 | SPEC_RULE_OP1,
|
||||
2048 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2073 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG,
|
||||
2123 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2148 | SPEC_RULE_OP2,
|
||||
2153,
|
||||
2154 | SPEC_RULE_OP1,
|
||||
2159 | SPEC_RULE_OP1,
|
||||
2164,
|
||||
2165 | SPEC_RULE_OP1,
|
||||
2170 | SPEC_RULE_OP1,
|
||||
2175 | SPEC_RULE_OP1,
|
||||
1961 | SPEC_RULE_OP2,
|
||||
1966,
|
||||
1967 | SPEC_RULE_OP1,
|
||||
1972 | SPEC_RULE_OP2,
|
||||
1977 | SPEC_RULE_OP1,
|
||||
1982 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
|
||||
1992 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2017 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2042 | SPEC_RULE_OP1,
|
||||
2047 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2072 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_QUICK_ARG,
|
||||
2122 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2147 | SPEC_RULE_OP2,
|
||||
2152,
|
||||
2153 | SPEC_RULE_OP1,
|
||||
2158 | SPEC_RULE_OP1,
|
||||
2163,
|
||||
2164 | SPEC_RULE_OP1,
|
||||
2169 | SPEC_RULE_OP1,
|
||||
2174 | SPEC_RULE_OP1,
|
||||
2179,
|
||||
2180,
|
||||
2181,
|
||||
2182 | SPEC_RULE_OP2,
|
||||
2187 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2191 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2195 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2199 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2199 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2224 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2224 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2249 | SPEC_RULE_OP1,
|
||||
2254,
|
||||
2255 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2280,
|
||||
2281 | SPEC_RULE_OP1,
|
||||
2181 | SPEC_RULE_OP2,
|
||||
2186 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2190 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2194 | SPEC_RULE_RETVAL | SPEC_RULE_OBSERVER,
|
||||
2198 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2198 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2223 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2223 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2248 | SPEC_RULE_OP1,
|
||||
2253,
|
||||
2254 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2279,
|
||||
2280 | SPEC_RULE_OP1,
|
||||
2285,
|
||||
2286,
|
||||
2287,
|
||||
2288,
|
||||
2289,
|
||||
2290,
|
||||
2291,
|
||||
2292,
|
||||
2293 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2292 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2317,
|
||||
2318,
|
||||
2319,
|
||||
2320,
|
||||
2321 | SPEC_RULE_OP1,
|
||||
2326,
|
||||
2327 | SPEC_RULE_ISSET,
|
||||
2329 | SPEC_RULE_OP2,
|
||||
2334,
|
||||
2335 | SPEC_RULE_OP1,
|
||||
2340 | SPEC_RULE_OBSERVER,
|
||||
2342,
|
||||
2343 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2368 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
|
||||
2320 | SPEC_RULE_OP1,
|
||||
2325,
|
||||
2326 | SPEC_RULE_ISSET,
|
||||
2328 | SPEC_RULE_OP2,
|
||||
2333,
|
||||
2334 | SPEC_RULE_OP1,
|
||||
2339 | SPEC_RULE_OBSERVER,
|
||||
2341,
|
||||
2342 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2367 | SPEC_RULE_OP1 | SPEC_RULE_OBSERVER,
|
||||
2377,
|
||||
2378,
|
||||
2379,
|
||||
2380,
|
||||
2381,
|
||||
2382 | SPEC_RULE_OP1,
|
||||
2381 | SPEC_RULE_OP1,
|
||||
2386,
|
||||
2387,
|
||||
2388,
|
||||
2389 | SPEC_RULE_OP1,
|
||||
2394 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2419,
|
||||
2420 | SPEC_RULE_OP1,
|
||||
2388 | SPEC_RULE_OP1,
|
||||
2393 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2418,
|
||||
2419 | SPEC_RULE_OP1,
|
||||
2424,
|
||||
2425,
|
||||
2426,
|
||||
2427,
|
||||
@ -67595,82 +67549,81 @@ void zend_vm_init(void)
|
||||
2429,
|
||||
2430,
|
||||
2431,
|
||||
2432,
|
||||
2433 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2432 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2457,
|
||||
2458,
|
||||
2459,
|
||||
2460,
|
||||
2461 | SPEC_RULE_OP2,
|
||||
2466,
|
||||
2467 | SPEC_RULE_OP1,
|
||||
2472 | SPEC_RULE_OP1,
|
||||
2477 | SPEC_RULE_OP1,
|
||||
2482 | SPEC_RULE_OP1,
|
||||
2487 | SPEC_RULE_OP1,
|
||||
2492,
|
||||
2493 | SPEC_RULE_OP1,
|
||||
2498 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2523 | SPEC_RULE_OP1,
|
||||
2528 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2553 | SPEC_RULE_OP1,
|
||||
2558 | SPEC_RULE_OP1,
|
||||
2460 | SPEC_RULE_OP2,
|
||||
2465,
|
||||
2466 | SPEC_RULE_OP1,
|
||||
2471 | SPEC_RULE_OP1,
|
||||
2476 | SPEC_RULE_OP1,
|
||||
2481 | SPEC_RULE_OP1,
|
||||
2486 | SPEC_RULE_OP1,
|
||||
2491,
|
||||
2492 | SPEC_RULE_OP1,
|
||||
2497 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2522 | SPEC_RULE_OP1,
|
||||
2527 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
|
||||
2552 | SPEC_RULE_OP1,
|
||||
2557 | SPEC_RULE_OP1,
|
||||
2562,
|
||||
2563,
|
||||
2564,
|
||||
2565,
|
||||
2566,
|
||||
2567,
|
||||
2568 | SPEC_RULE_OBSERVER,
|
||||
2570 | SPEC_RULE_OBSERVER,
|
||||
2572 | SPEC_RULE_OBSERVER,
|
||||
2574 | SPEC_RULE_OBSERVER,
|
||||
2567 | SPEC_RULE_OBSERVER,
|
||||
2569 | SPEC_RULE_OBSERVER,
|
||||
2571 | SPEC_RULE_OBSERVER,
|
||||
2573 | SPEC_RULE_OBSERVER,
|
||||
2575,
|
||||
2576,
|
||||
2577,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3487,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
3486,
|
||||
};
|
||||
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
|
||||
zend_opcode_handler_funcs = labels;
|
||||
@ -67843,7 +67796,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2586 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2585 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
}
|
||||
@ -67851,7 +67804,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2611 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2610 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
}
|
||||
@ -67859,7 +67812,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2636 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2635 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
if (op->op1_type < op->op2_type) {
|
||||
zend_swap_operands(op);
|
||||
}
|
||||
@ -67870,17 +67823,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2661 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
spec = 2660 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2686 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
spec = 2685 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2711 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
spec = 2710 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
}
|
||||
break;
|
||||
case ZEND_MUL:
|
||||
@ -67891,17 +67844,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2736 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2735 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2761 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2760 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2786 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2785 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_IDENTICAL:
|
||||
@ -67912,14 +67865,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2810 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2885 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
|
||||
spec = 3111 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 3110 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_NOT_IDENTICAL:
|
||||
@ -67930,14 +67883,14 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2960 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 3035 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
|
||||
spec = 3116 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 3115 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_EQUAL:
|
||||
@ -67948,12 +67901,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2810 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2885 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_NOT_EQUAL:
|
||||
@ -67964,12 +67917,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 2960 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
spec = 3035 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_SMALLER:
|
||||
@ -67977,12 +67930,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3121 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
spec = 3120 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3196 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
spec = 3195 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
}
|
||||
break;
|
||||
case ZEND_IS_SMALLER_OR_EQUAL:
|
||||
@ -67990,79 +67943,79 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3271 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
spec = 3270 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3346 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
spec = 3345 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
|
||||
}
|
||||
break;
|
||||
case ZEND_QM_ASSIGN:
|
||||
if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3433 | SPEC_RULE_OP1;
|
||||
spec = 3432 | SPEC_RULE_OP1;
|
||||
} else if (op1_info == MAY_BE_DOUBLE) {
|
||||
spec = 3438 | SPEC_RULE_OP1;
|
||||
spec = 3437 | SPEC_RULE_OP1;
|
||||
} else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) {
|
||||
spec = 3443 | SPEC_RULE_OP1;
|
||||
spec = 3442 | SPEC_RULE_OP1;
|
||||
}
|
||||
break;
|
||||
case ZEND_PRE_INC:
|
||||
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
|
||||
spec = 3421 | SPEC_RULE_RETVAL;
|
||||
spec = 3420 | SPEC_RULE_RETVAL;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3423 | SPEC_RULE_RETVAL;
|
||||
spec = 3422 | SPEC_RULE_RETVAL;
|
||||
}
|
||||
break;
|
||||
case ZEND_PRE_DEC:
|
||||
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
|
||||
spec = 3425 | SPEC_RULE_RETVAL;
|
||||
spec = 3424 | SPEC_RULE_RETVAL;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3427 | SPEC_RULE_RETVAL;
|
||||
spec = 3426 | SPEC_RULE_RETVAL;
|
||||
}
|
||||
break;
|
||||
case ZEND_POST_INC:
|
||||
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
|
||||
spec = 3429;
|
||||
spec = 3428;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3430;
|
||||
spec = 3429;
|
||||
}
|
||||
break;
|
||||
case ZEND_POST_DEC:
|
||||
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
|
||||
spec = 3431;
|
||||
spec = 3430;
|
||||
} else if (op1_info == MAY_BE_LONG) {
|
||||
spec = 3432;
|
||||
spec = 3431;
|
||||
}
|
||||
break;
|
||||
case ZEND_JMP:
|
||||
if (OP_JMP_ADDR(op, op->op1) > op) {
|
||||
spec = 2585;
|
||||
spec = 2584;
|
||||
}
|
||||
break;
|
||||
case ZEND_INIT_FCALL:
|
||||
if (Z_EXTRA_P(RT_CONSTANT(op, op->op2)) != 0) {
|
||||
spec = 2578;
|
||||
spec = 2577;
|
||||
}
|
||||
break;
|
||||
case ZEND_RECV:
|
||||
if (op->op2.num == MAY_BE_ANY) {
|
||||
spec = 2579;
|
||||
spec = 2578;
|
||||
}
|
||||
break;
|
||||
case ZEND_SEND_VAL:
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
|
||||
spec = 3483;
|
||||
spec = 3482;
|
||||
}
|
||||
break;
|
||||
case ZEND_SEND_VAR_EX:
|
||||
if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
|
||||
spec = 3478 | SPEC_RULE_OP1;
|
||||
spec = 3477 | SPEC_RULE_OP1;
|
||||
}
|
||||
break;
|
||||
case ZEND_FE_FETCH_R:
|
||||
if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) {
|
||||
spec = 3485 | SPEC_RULE_RETVAL;
|
||||
spec = 3484 | SPEC_RULE_RETVAL;
|
||||
}
|
||||
break;
|
||||
case ZEND_FETCH_DIM_R:
|
||||
@ -68070,22 +68023,22 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
|
||||
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
|
||||
break;
|
||||
}
|
||||
spec = 3448 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
spec = 3447 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
|
||||
}
|
||||
break;
|
||||
case ZEND_SEND_VAL_EX:
|
||||
if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
|
||||
spec = 3484;
|
||||
spec = 3483;
|
||||
}
|
||||
break;
|
||||
case ZEND_SEND_VAR:
|
||||
if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
|
||||
spec = 3473 | SPEC_RULE_OP1;
|
||||
spec = 3472 | SPEC_RULE_OP1;
|
||||
}
|
||||
break;
|
||||
case ZEND_COUNT:
|
||||
if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY) {
|
||||
spec = 2580 | SPEC_RULE_OP1;
|
||||
spec = 2579 | SPEC_RULE_OP1;
|
||||
}
|
||||
break;
|
||||
case ZEND_BW_OR:
|
||||
|
1935
Zend/zend_vm_handlers.h
generated
1935
Zend/zend_vm_handlers.h
generated
File diff suppressed because it is too large
Load Diff
2
Zend/zend_vm_opcodes.c
generated
2
Zend/zend_vm_opcodes.c
generated
@ -102,7 +102,7 @@ static const char *zend_vm_opcodes_names[210] = {
|
||||
"ZEND_UNSET_OBJ",
|
||||
"ZEND_FE_RESET_R",
|
||||
"ZEND_FE_FETCH_R",
|
||||
"ZEND_EXIT",
|
||||
NULL,
|
||||
"ZEND_FETCH_R",
|
||||
"ZEND_FETCH_DIM_R",
|
||||
"ZEND_FETCH_OBJ_R",
|
||||
|
1
Zend/zend_vm_opcodes.h
generated
1
Zend/zend_vm_opcodes.h
generated
@ -161,7 +161,6 @@ END_EXTERN_C()
|
||||
#define ZEND_UNSET_OBJ 76
|
||||
#define ZEND_FE_RESET_R 77
|
||||
#define ZEND_FE_FETCH_R 78
|
||||
#define ZEND_EXIT 79
|
||||
#define ZEND_FETCH_R 80
|
||||
#define ZEND_FETCH_DIM_R 81
|
||||
#define ZEND_FETCH_OBJ_R 82
|
||||
|
@ -83,9 +83,15 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
|
||||
}
|
||||
}
|
||||
|
||||
/* As exit() and die() are proper token/keywords an need to hack-around */
|
||||
$hasSpecialExitAsFunctionHandling = str_ends_with($stubFile, 'zend_builtin_functions.stub.php');
|
||||
if (!$fileInfo = $context->parsedFiles[$stubFile] ?? null) {
|
||||
initPhpParser();
|
||||
$fileInfo = parseStubFile($stubCode ?? file_get_contents($stubFile));
|
||||
$stubContent = $stubCode ?? file_get_contents($stubFile);
|
||||
if ($hasSpecialExitAsFunctionHandling) {
|
||||
$stubContent = str_replace(['exit', 'die'], ['exit_dummy', 'die_dummy'], $stubContent);
|
||||
}
|
||||
$fileInfo = parseStubFile($stubContent);
|
||||
$context->parsedFiles[$stubFile] = $fileInfo;
|
||||
|
||||
foreach ($fileInfo->dependencies as $dependency) {
|
||||
@ -118,6 +124,9 @@ function processStubFile(string $stubFile, Context $context, bool $includeOnly =
|
||||
$context->allConstInfos,
|
||||
$stubHash
|
||||
);
|
||||
if ($hasSpecialExitAsFunctionHandling) {
|
||||
$arginfoCode = str_replace(['exit_dummy', 'die_dummy'], ['exit', 'die'], $arginfoCode);
|
||||
}
|
||||
if (($context->forceRegeneration || $stubHash !== $oldStubHash) && file_put_contents($arginfoFile, $arginfoCode)) {
|
||||
echo "Saved $arginfoFile\n";
|
||||
}
|
||||
|
@ -2557,7 +2557,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
|
||||
case ZEND_GENERATOR_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
case ZEND_RETURN:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_MATCH_ERROR:
|
||||
/* switch through trampoline */
|
||||
case ZEND_YIELD:
|
||||
@ -3470,7 +3469,6 @@ ZEND_EXT_API int zend_jit_check_support(void)
|
||||
/* JIT has no effect on these opcodes */
|
||||
case ZEND_BEGIN_SILENCE:
|
||||
case ZEND_END_SILENCE:
|
||||
case ZEND_EXIT:
|
||||
break;
|
||||
default:
|
||||
if (zend_get_user_opcode_handler(i) != NULL) {
|
||||
|
@ -16450,8 +16450,7 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr
|
||||
} else {
|
||||
ir_GUARD(ir_GE(ref, ir_CONST_I32(0)), jit_STUB_ADDR(jit, jit_stub_trace_halt));
|
||||
}
|
||||
} else if (opline->opcode == ZEND_EXIT ||
|
||||
opline->opcode == ZEND_GENERATOR_RETURN ||
|
||||
} else if (opline->opcode == ZEND_GENERATOR_RETURN ||
|
||||
opline->opcode == ZEND_YIELD ||
|
||||
opline->opcode == ZEND_YIELD_FROM) {
|
||||
ir_IJMP(jit_STUB_ADDR(jit, jit_stub_trace_halt));
|
||||
|
@ -314,7 +314,6 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op
|
||||
case ZEND_FAST_RET:
|
||||
case ZEND_GENERATOR_CREATE:
|
||||
case ZEND_GENERATOR_RETURN:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_YIELD:
|
||||
case ZEND_YIELD_FROM:
|
||||
case ZEND_INCLUDE_OR_EVAL:
|
||||
|
@ -9,7 +9,7 @@ opcache.jit=function
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.show_output=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_opcode_in_user_handler=ZEND_EXIT, ZEND_BEGIN_SILENCE, ZEND_END_SILENCE
|
||||
zend_test.observer.show_opcode_in_user_handler=ZEND_BEGIN_SILENCE, ZEND_END_SILENCE
|
||||
--EXTENSIONS--
|
||||
opcache
|
||||
zend_test
|
||||
@ -27,6 +27,9 @@ exit(@test());
|
||||
<file '%s'>
|
||||
<!-- opcode: 'ZEND_BEGIN_SILENCE' in user handler -->
|
||||
<!-- opcode: 'ZEND_END_SILENCE' in user handler -->
|
||||
<!-- opcode: 'ZEND_EXIT' in user handler -->
|
||||
<!-- init exit() -->
|
||||
<exit>
|
||||
<!-- Exception: UnwindExit -->
|
||||
</exit>
|
||||
<!-- Exception: UnwindExit -->
|
||||
</file '%s'>
|
||||
|
@ -23,9 +23,9 @@ try {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
// using language construct 'exit' as 'callback'
|
||||
// using language construct 'isset' as 'callback'
|
||||
try {
|
||||
var_dump( array_filter($input, 'exit') );
|
||||
var_dump( array_filter($input, 'isset') );
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
@ -63,5 +63,5 @@ array(6) {
|
||||
int(1000)
|
||||
}
|
||||
array_filter(): Argument #2 ($callback) must be a valid callback or null, function "echo" not found or invalid function name
|
||||
array_filter(): Argument #2 ($callback) must be a valid callback or null, function "exit" not found or invalid function name
|
||||
array_filter(): Argument #2 ($callback) must be a valid callback or null, function "isset" not found or invalid function name
|
||||
Done
|
||||
|
@ -2,32 +2,24 @@
|
||||
Test array_map() function : usage variations - failing built-in functions & language constructs
|
||||
--FILE--
|
||||
<?php
|
||||
/*
|
||||
* Test array_map() by passing non-permmited built-in functions and language constructs i.e.
|
||||
* echo(), array(), empty(), eval(), exit(), isset(), list(), print()
|
||||
*/
|
||||
|
||||
echo "*** Testing array_map() : non-permmited built-in functions ***\n";
|
||||
|
||||
// array to be passed as arguments
|
||||
$arr1 = array(1, 2);
|
||||
$arg = [1, 2];
|
||||
|
||||
// built-in functions & language constructs
|
||||
$callback_names = array(
|
||||
/*1*/ 'echo',
|
||||
'array',
|
||||
'empty',
|
||||
/*4*/ 'eval',
|
||||
'exit',
|
||||
'isset',
|
||||
'list',
|
||||
/*8*/ 'print'
|
||||
);
|
||||
for($count = 0; $count < count($callback_names); $count++)
|
||||
$callbacks = [
|
||||
'echo',
|
||||
'array',
|
||||
'empty',
|
||||
'eval',
|
||||
'isset',
|
||||
'list',
|
||||
'print',
|
||||
];
|
||||
|
||||
foreach($callbacks as $callback)
|
||||
{
|
||||
echo "-- Iteration ".($count + 1)." --\n";
|
||||
try {
|
||||
var_dump( array_map($callback_names[$count], $arr1) );
|
||||
var_dump( array_map($callback, $arg) );
|
||||
} catch (TypeError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
@ -36,21 +28,11 @@ for($count = 0; $count < count($callback_names); $count++)
|
||||
echo "Done";
|
||||
?>
|
||||
--EXPECT--
|
||||
*** Testing array_map() : non-permmited built-in functions ***
|
||||
-- Iteration 1 --
|
||||
array_map(): Argument #1 ($callback) must be a valid callback or null, function "echo" not found or invalid function name
|
||||
-- Iteration 2 --
|
||||
array_map(): Argument #1 ($callback) must be a valid callback or null, function "array" not found or invalid function name
|
||||
-- Iteration 3 --
|
||||
array_map(): Argument #1 ($callback) must be a valid callback or null, function "empty" not found or invalid function name
|
||||
-- Iteration 4 --
|
||||
array_map(): Argument #1 ($callback) must be a valid callback or null, function "eval" not found or invalid function name
|
||||
-- Iteration 5 --
|
||||
array_map(): Argument #1 ($callback) must be a valid callback or null, function "exit" not found or invalid function name
|
||||
-- Iteration 6 --
|
||||
array_map(): Argument #1 ($callback) must be a valid callback or null, function "isset" not found or invalid function name
|
||||
-- Iteration 7 --
|
||||
array_map(): Argument #1 ($callback) must be a valid callback or null, function "list" not found or invalid function name
|
||||
-- Iteration 8 --
|
||||
array_map(): Argument #1 ($callback) must be a valid callback or null, function "print" not found or invalid function name
|
||||
Done
|
||||
|
@ -608,7 +608,6 @@ int phpdbg_skip_line_helper(void) /* {{{ */ {
|
||||
|| opline->opcode == ZEND_RETURN
|
||||
|| opline->opcode == ZEND_FAST_RET
|
||||
|| opline->opcode == ZEND_GENERATOR_RETURN
|
||||
|| opline->opcode == ZEND_EXIT
|
||||
|| opline->opcode == ZEND_YIELD
|
||||
|| opline->opcode == ZEND_YIELD_FROM
|
||||
) {
|
||||
@ -652,7 +651,6 @@ static void phpdbg_seek_to_end(void) /* {{{ */ {
|
||||
case ZEND_RETURN:
|
||||
case ZEND_FAST_RET:
|
||||
case ZEND_GENERATOR_RETURN:
|
||||
case ZEND_EXIT:
|
||||
case ZEND_YIELD:
|
||||
case ZEND_YIELD_FROM:
|
||||
zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline);
|
||||
|
Loading…
Reference in New Issue
Block a user