Skip to content

Commit b90b37c

Browse files
committed
Fix spec handler for zend_vm_call_opcode_handler
1 parent c8e8970 commit b90b37c

File tree

7 files changed

+64
-70
lines changed

7 files changed

+64
-70
lines changed

Zend/Optimizer/zend_optimizer.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,13 +1222,7 @@ static void zend_redo_pass_two(zend_op_array *op_array)
12221222
}
12231223
break;
12241224
}
1225-
/* INIT_FCALL with IS_PTR *must* use the PTR specialization, because the default spec doesn't
1226-
* handle IS_PTR. */
1227-
if (opline->opcode == ZEND_INIT_FCALL && Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) == IS_PTR) {
1228-
zend_vm_set_opcode_handler_ex(opline, IS_UNUSED, IS_CONST, IS_UNUSED);
1229-
} else {
1230-
ZEND_VM_SET_OPCODE_HANDLER(opline);
1231-
}
1225+
ZEND_VM_SET_OPCODE_HANDLER(opline);
12321226
opline++;
12331227
}
12341228

Zend/zend_compile.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4837,12 +4837,16 @@ static void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{
48374837
}
48384838

48394839
zval_ptr_dtor(&name_node.u.constant);
4840-
if ((CG(compiler_options) & ZEND_COMPILE_WITH_INIT_FCALL_PTR)) {
4840+
#if ZEND_VM_SPEC && !defined(ZEND_WIN32)
4841+
if (!(CG(compiler_options) & ZEND_COMPILE_WITH_FILE_CACHE)) {
48414842
zend_string_release_ex(lcname, 0);
48424843
ZVAL_PTR(&name_node.u.constant, fbc);
48434844
} else {
48444845
ZVAL_NEW_STR(&name_node.u.constant, lcname);
48454846
}
4847+
#else
4848+
ZVAL_NEW_STR(&name_node.u.constant, lcname);
4849+
#endif
48464850

48474851
opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node);
48484852
opline->result.num = zend_alloc_cache_slot();

Zend/zend_compile.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,9 +1230,6 @@ END_EXTERN_C()
12301230
/* ignore observer notifications, e.g. to manually notify afterwards in a post-processing step after compilation */
12311231
#define ZEND_COMPILE_IGNORE_OBSERVER (1<<18)
12321232

1233-
/* Allow storing IS_PTR to function in INIT_ICALL op2. */
1234-
#define ZEND_COMPILE_WITH_INIT_FCALL_PTR (1<<19)
1235-
12361233
/* The default value for CG(compiler_options) */
12371234
#define ZEND_COMPILE_DEFAULT ZEND_COMPILE_HANDLE_OP_ARRAY
12381235

Zend/zend_vm_execute.h

Lines changed: 29 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Zend/zend_vm_gen.php

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2832,14 +2832,21 @@ function gen_vm($def, $skel) {
28322832
out($f, "\treturn (spec & SPEC_START_MASK) + offset;\n");
28332833
}
28342834
out($f, "}\n\n");
2835+
2836+
out($f, "static zend_always_inline uint32_t zend_vm_get_opcode_handler_spec_ex(uint8_t opcode, zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info, bool swap_operands);\n\n");
2837+
2838+
// Generate zend_vm_get_opcode_handler_spec() function
2839+
out($f, "static zend_always_inline uint32_t zend_vm_get_opcode_handler_spec(uint8_t opcode, zend_op* op, bool swap_operands)\n");
2840+
out($f, "{\n");
2841+
out($f, "\tuint32_t all_types = MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_UNDEF;\n");
2842+
out($f, "\treturn zend_vm_get_opcode_handler_spec_ex(opcode, op, all_types, all_types, all_types, swap_operands);\n");
2843+
out($f, "}\n\n");
2844+
28352845
out($f, "#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n");
28362846
out($f, "static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)\n");
28372847
out($f, "{\n");
2838-
if (!ZEND_VM_SPEC) {
2839-
out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
2840-
} else {
2841-
out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)];\n");
2842-
}
2848+
out($f, "\t/* Casting away const is safe, as we're not swapping operands. */\n");
2849+
out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_spec(opcode, (zend_op*)op, false)];\n");
28432850
out($f, "}\n");
28442851
out($f, "#endif\n\n");
28452852

@@ -2848,11 +2855,11 @@ function gen_vm($def, $skel) {
28482855
out($f, "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID\n");
28492856
out($f,"static const void *zend_vm_get_opcode_handler_func(uint8_t opcode, const zend_op* op)\n");
28502857
out($f, "{\n");
2851-
out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
28522858
if (!ZEND_VM_SPEC) {
2853-
out($f, "\treturn zend_opcode_handler_funcs[spec];\n");
2859+
out($f, "\treturn zend_opcode_handler_funcs[zend_spec_handlers[opcode]];\n");
28542860
} else {
2855-
out($f, "\treturn zend_opcode_handler_funcs[zend_vm_get_opcode_handler_idx(spec, op)];\n");
2861+
out($f, "\t/* Casting away const is safe, as we're not swapping operands. */\n");
2862+
out($f, "\treturn zend_opcode_handler_funcs[zend_vm_get_opcode_handler_spec(opcode, (zend_op*)op, false)];\n");
28562863
}
28572864
out($f, "}\n\n");
28582865
out($f, "#endif\n\n");
@@ -2861,26 +2868,20 @@ function gen_vm($def, $skel) {
28612868
// Generate zend_vm_get_opcode_handler() function
28622869
out($f, "ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler(zend_op* op)\n");
28632870
out($f, "{\n");
2864-
out($f, "\tuint8_t opcode = zend_user_opcodes[op->opcode];\n");
2865-
if (!ZEND_VM_SPEC) {
2866-
out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
2867-
} else {
2868-
out($f, "\n");
2869-
out($f, "\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {\n");
2870-
out($f, "\t\tif (op->op1_type < op->op2_type) {\n");
2871-
out($f, "\t\t\tzend_swap_operands(op);\n");
2872-
out($f, "\t\t}\n");
2873-
out($f, "\t}\n");
2874-
out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)];\n");
2875-
}
2871+
out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_spec(zend_user_opcodes[op->opcode], op, true)];\n");
28762872
out($f, "}\n\n");
28772873

28782874
// Generate zend_vm_set_opcode_handler_ex() function
28792875
out($f, "ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info)\n");
28802876
out($f, "{\n");
2881-
out($f, "\tuint8_t opcode = zend_user_opcodes[op->opcode];\n");
2877+
out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_spec_ex(zend_user_opcodes[op->opcode], op, op1_info, op2_info, res_info, true)];\n");
2878+
out($f, "}\n\n");
2879+
2880+
// Generate zend_vm_get_opcode_handler_spec_ex() function
2881+
out($f, "static zend_always_inline uint32_t zend_vm_get_opcode_handler_spec_ex(uint8_t opcode, zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info, bool swap_operands)\n");
2882+
out($f, "{\n");
28822883
if (!ZEND_VM_SPEC) {
2883-
out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
2884+
out($f, "\treturn zend_vm_get_opcode_handler_idx(opcode, op);\n");
28842885
} else {
28852886
out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
28862887
if (isset($used_extra_spec["TYPE"])) {
@@ -2890,7 +2891,7 @@ function gen_vm($def, $skel) {
28902891
$orig_op = $dsc['op'];
28912892
out($f, "\t\tcase $orig_op:\n");
28922893
if (isset($dsc["spec"]["COMMUTATIVE"])) {
2893-
out($f, "\t\t\tif (op->op1_type < op->op2_type) {\n");
2894+
out($f, "\t\t\tif (swap_operands && op->op1_type < op->op2_type) {\n");
28942895
out($f, "\t\t\t\tzend_swap_operands(op);\n");
28952896
out($f, "\t\t\t}\n");
28962897
}
@@ -2911,7 +2912,7 @@ function gen_vm($def, $skel) {
29112912
}
29122913
out($f, "\t\t\t\tspec = {$spec_dsc['spec_code']};\n");
29132914
if (isset($spec_dsc["spec"]["COMMUTATIVE"]) && !isset($dsc["spec"]["COMMUTATIVE"])) {
2914-
out($f, "\t\t\t\tif (op->op1_type < op->op2_type) {\n");
2915+
out($f, "\t\t\t\tif (swap_operands && op->op1_type < op->op2_type) {\n");
29152916
out($f, "\t\t\t\t\tzend_swap_operands(op);\n");
29162917
out($f, "\t\t\t\t}\n");
29172918
}
@@ -2933,13 +2934,13 @@ function gen_vm($def, $skel) {
29332934
}
29342935
}
29352936
if ($has_commutative) {
2936-
out($f, "\t\t\tif (op->op1_type < op->op2_type) {\n");
2937+
out($f, "\t\t\tif (swap_operands && op->op1_type < op->op2_type) {\n");
29372938
out($f, "\t\t\t\tzend_swap_operands(op);\n");
29382939
out($f, "\t\t\t}\n");
29392940
out($f, "\t\t\tbreak;\n");
29402941
out($f, "\t\tcase ZEND_USER_OPCODE:\n");
29412942
out($f, "\t\t\tif (zend_spec_handlers[op->opcode] & SPEC_RULE_COMMUTATIVE) {\n");
2942-
out($f, "\t\t\t\tif (op->op1_type < op->op2_type) {\n");
2943+
out($f, "\t\t\t\tif (swap_operands && op->op1_type < op->op2_type) {\n");
29432944
out($f, "\t\t\t\t\tzend_swap_operands(op);\n");
29442945
out($f, "\t\t\t\t}\n");
29452946
out($f, "\t\t\t}\n");
@@ -2949,7 +2950,7 @@ function gen_vm($def, $skel) {
29492950
out($f, "\t\t\tbreak;\n");
29502951
out($f, "\t}\n");
29512952
}
2952-
out($f, "\top->handler = zend_opcode_handlers[zend_vm_get_opcode_handler_idx(spec, op)];\n");
2953+
out($f, "\treturn zend_vm_get_opcode_handler_idx(spec, op);\n");
29532954
}
29542955
out($f, "}\n\n");
29552956

ext/opcache/ZendAccelerator.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,10 +1558,6 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
15581558
orig_compiler_options = CG(compiler_options);
15591559
if (ZCG(accel_directives).file_cache) {
15601560
CG(compiler_options) |= ZEND_COMPILE_WITH_FILE_CACHE;
1561-
#ifndef ZEND_WIN32
1562-
} else {
1563-
CG(compiler_options) |= ZEND_COMPILE_WITH_INIT_FCALL_PTR;
1564-
#endif
15651561
}
15661562
zend_optimize_script(&new_persistent_script->script, ZCG(accel_directives).optimization_level, ZCG(accel_directives).opt_debug_level);
15671563
zend_accel_finalize_delayed_early_binding_list(new_persistent_script);
@@ -1817,10 +1813,6 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl
18171813
CG(compiler_options) |= ZEND_COMPILE_IGNORE_OBSERVER;
18181814
if (ZCG(accel_directives).file_cache) {
18191815
CG(compiler_options) |= ZEND_COMPILE_WITH_FILE_CACHE;
1820-
#ifndef ZEND_WIN32
1821-
} else {
1822-
CG(compiler_options) |= ZEND_COMPILE_WITH_INIT_FCALL_PTR;
1823-
#endif
18241816
}
18251817
op_array = *op_array_p = accelerator_orig_compile_file(file_handle, type);
18261818
CG(compiler_options) = orig_compiler_options;

sapi/phpdbg/tests/print_001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ L0018 0001 DO_FCALL
4949
L0018 0002 INIT_METHOD_CALL 1 V0 string("Foo")
5050
L0018 0003 SEND_VAL_EX string("test \"quotes\"") 1
5151
L0018 0004 DO_FCALL
52-
L0019 0005 INIT_FCALL %d %d string("foo")
52+
L0019 0005 INIT_FCALL %d %d %s
5353
L0019 0006 SEND_VAL string("test") 1
5454
L0019 0007 DO_FCALL
5555
L0021 0008 RETURN int(1)

0 commit comments

Comments
 (0)