1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix zend_vm_call_opcode_handler (e.g. Generators throwing exceptions) with IP/FP registers

This commit is contained in:
Bob Weinand
2015-08-26 00:25:25 +01:00
parent 9d31b29705
commit c1e9bd27fe
3 changed files with 38 additions and 4 deletions

View File

@@ -49636,11 +49636,16 @@ ZEND_API int zend_vm_call_opcode_handler(zend_execute_data* ex)
LOAD_OPLINE();
#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)
((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
ret = opline? ((execute_data != ex)? (int)(execute_data->prev_execute_data != ex) + 1 : 0) : -1;
if (EXPECTED(opline)) {
ret = execute_data != ex ? (int)(execute_data->prev_execute_data != ex) + 1 : 0;
SAVE_OPLINE();
} else {
ret = -1;
}
#else
ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#endif
SAVE_OPLINE();
#endif
#ifdef ZEND_VM_FP_GLOBAL_REG
execute_data = orig_execute_data;
#endif

View File

@@ -1618,11 +1618,16 @@ function gen_vm($def, $skel) {
out($f, "\tLOAD_OPLINE();\n");
out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
out($f, "\t((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
out($f, "\tret = opline? ((execute_data != ex)? (int)(execute_data->prev_execute_data != ex) + 1 : 0) : -1;\n");
out($f, "\tif (EXPECTED(opline)) {\n");
out($f, "\t\tret = execute_data != ex ? (int)(execute_data->prev_execute_data != ex) + 1 : 0;\n");
out($f, "\t\tSAVE_OPLINE();\n");
out($f, "\t} else {\n");
out($f, "\t\tret = -1;\n");
out($f, "\t}\n");
out($f, "#else\n");
out($f, "\tret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
out($f, "#endif\n");
out($f, "\tSAVE_OPLINE();\n");
out($f, "#endif\n");
out($f, "#ifdef ZEND_VM_FP_GLOBAL_REG\n");
out($f, "\texecute_data = orig_execute_data;\n");
out($f, "#endif\n");

View File

@@ -0,0 +1,24 @@
--TEST--
Ensure proper saving of EX(opline)
--PHPDBG--
r
q
--EXPECTF--
[Successful compilation of %s]
prompt> caught Generator exception
[Script ended normally]
prompt>
--FILE--
<?php
function gen() {
try {
throw new Exception;
} catch(Exception $e) {
yield "caught Generator exception";
}
}
foreach (gen() as $v) {
print $v;
}