Skip to content

Commit c1e9bd2

Browse files
committed
Fix zend_vm_call_opcode_handler (e.g. Generators throwing exceptions) with IP/FP registers
1 parent 9d31b29 commit c1e9bd2

File tree

3 files changed

+38
-4
lines changed

3 files changed

+38
-4
lines changed

Zend/zend_vm_execute.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -49636,11 +49636,16 @@ ZEND_API int zend_vm_call_opcode_handler(zend_execute_data* ex)
4963649636
LOAD_OPLINE();
4963749637
#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)
4963849638
((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
49639-
ret = opline? ((execute_data != ex)? (int)(execute_data->prev_execute_data != ex) + 1 : 0) : -1;
49639+
if (EXPECTED(opline)) {
49640+
ret = execute_data != ex ? (int)(execute_data->prev_execute_data != ex) + 1 : 0;
49641+
SAVE_OPLINE();
49642+
} else {
49643+
ret = -1;
49644+
}
4964049645
#else
4964149646
ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
49642-
#endif
4964349647
SAVE_OPLINE();
49648+
#endif
4964449649
#ifdef ZEND_VM_FP_GLOBAL_REG
4964549650
execute_data = orig_execute_data;
4964649651
#endif

Zend/zend_vm_gen.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -1618,11 +1618,16 @@ function gen_vm($def, $skel) {
16181618
out($f, "\tLOAD_OPLINE();\n");
16191619
out($f,"#if defined(ZEND_VM_FP_GLOBAL_REG) && defined(ZEND_VM_IP_GLOBAL_REG)\n");
16201620
out($f, "\t((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
1621-
out($f, "\tret = opline? ((execute_data != ex)? (int)(execute_data->prev_execute_data != ex) + 1 : 0) : -1;\n");
1621+
out($f, "\tif (EXPECTED(opline)) {\n");
1622+
out($f, "\t\tret = execute_data != ex ? (int)(execute_data->prev_execute_data != ex) + 1 : 0;\n");
1623+
out($f, "\t\tSAVE_OPLINE();\n");
1624+
out($f, "\t} else {\n");
1625+
out($f, "\t\tret = -1;\n");
1626+
out($f, "\t}\n");
16221627
out($f, "#else\n");
16231628
out($f, "\tret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n");
1624-
out($f, "#endif\n");
16251629
out($f, "\tSAVE_OPLINE();\n");
1630+
out($f, "#endif\n");
16261631
out($f, "#ifdef ZEND_VM_FP_GLOBAL_REG\n");
16271632
out($f, "\texecute_data = orig_execute_data;\n");
16281633
out($f, "#endif\n");

sapi/phpdbg/tests/generator_run.phpt

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Ensure proper saving of EX(opline)
3+
--PHPDBG--
4+
r
5+
q
6+
--EXPECTF--
7+
[Successful compilation of %s]
8+
prompt> caught Generator exception
9+
[Script ended normally]
10+
prompt>
11+
--FILE--
12+
<?php
13+
14+
function gen() {
15+
try {
16+
throw new Exception;
17+
} catch(Exception $e) {
18+
yield "caught Generator exception";
19+
}
20+
}
21+
22+
foreach (gen() as $v) {
23+
print $v;
24+
}

0 commit comments

Comments
 (0)