Skip to content

Commit 7f7b3cd

Browse files
committed
Introduce zend_vm_opcode_handler_t / zend_vm_opcode_handler_func_t
This reduces the chances of confusion between opcode handlers used by the VM, and opcode handler functions used for tracing or debugging. Depending on the VM, zend_vm_opcode_handler_t may not be a function. For instance in the HYBRID VM this is a label pointer. Closes GH-19006
1 parent 747ecce commit 7f7b3cd

File tree

10 files changed

+130
-99
lines changed

10 files changed

+130
-99
lines changed

Zend/zend_compile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "zend_types.h"
2525
#include "zend_map_ptr.h"
2626
#include "zend_alloc.h"
27+
#include "zend_vm_opcodes.h"
2728

2829
#include <stdarg.h>
2930
#include <stdint.h>
@@ -135,7 +136,7 @@ void zend_const_expr_to_zval(zval *result, zend_ast **ast_ptr, bool allow_dynami
135136
typedef int (*user_opcode_handler_t) (zend_execute_data *execute_data);
136137

137138
struct _zend_op {
138-
const void *handler;
139+
zend_vm_opcode_handler_t handler;
139140
znode_op op1;
140141
znode_op op2;
141142
znode_op result;

Zend/zend_vm_execute.h

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

Zend/zend_vm_execute.skl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op)
126126
}
127127
zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
128128
ZEND_ASSERT(zv != NULL);
129-
op->handler = (const void *)(uintptr_t)Z_LVAL_P(zv);
129+
op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv);
130130
}
131131

132132
ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op)

Zend/zend_vm_gen.php

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,7 @@ function gen_null_label($f, $kind, $prolog) {
11861186
out($f,$prolog."ZEND_NULL_HANDLER,\n");
11871187
break;
11881188
case ZEND_VM_KIND_SWITCH:
1189-
out($f,$prolog."(void*)(uintptr_t)-1,\n");
1189+
out($f,$prolog."-1,\n");
11901190
break;
11911191
case ZEND_VM_KIND_GOTO:
11921192
out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
@@ -1388,7 +1388,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
13881388
out($f,"$prolog{$spec_name}_HANDLER,\n");
13891389
break;
13901390
case ZEND_VM_KIND_SWITCH:
1391-
out($f,$prolog."(void*)(uintptr_t)$switch_labels[$spec_name],\n");
1391+
out($f,$prolog."$switch_labels[$spec_name],\n");
13921392
break;
13931393
case ZEND_VM_KIND_GOTO:
13941394
out($f,$prolog."(void*)&&{$spec_name}_LABEL,\n");
@@ -1436,7 +1436,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
14361436
out($f,$prolog."ZEND_NULL_HANDLER,\n");
14371437
break;
14381438
case ZEND_VM_KIND_SWITCH:
1439-
out($f,$prolog."(void*)(uintptr_t)-1,\n");
1439+
out($f,$prolog."-1,\n");
14401440
break;
14411441
case ZEND_VM_KIND_GOTO:
14421442
out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
@@ -1467,7 +1467,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
14671467
out($f,$prolog.$dsc["op"]."_HANDLER,\n");
14681468
break;
14691469
case ZEND_VM_KIND_SWITCH:
1470-
out($f,$prolog."(void*)(uintptr_t)".((string)$num).",\n");
1470+
out($f,$prolog.((string)$num).",\n");
14711471
break;
14721472
case ZEND_VM_KIND_GOTO:
14731473
out($f,$prolog."(void*)&&".$dsc["op"]."_LABEL,\n");
@@ -1480,7 +1480,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
14801480
out($f,$prolog."ZEND_NULL_HANDLER,\n");
14811481
break;
14821482
case ZEND_VM_KIND_SWITCH:
1483-
out($f,$prolog."(void*)(uintptr_t)-1,\n");
1483+
out($f,$prolog."-1,\n");
14841484
break;
14851485
case ZEND_VM_KIND_GOTO:
14861486
out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
@@ -1497,7 +1497,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
14971497
out($f,$prolog."ZEND_NULL_HANDLER\n");
14981498
break;
14991499
case ZEND_VM_KIND_SWITCH:
1500-
out($f,$prolog."(void*)(uintptr_t)-1\n");
1500+
out($f,$prolog."-1\n");
15011501
break;
15021502
case ZEND_VM_KIND_GOTO:
15031503
out($f,$prolog."(void*)&&ZEND_NULL_LABEL\n");
@@ -1813,16 +1813,16 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
18131813
out($f,"#define SPEC_RULE_OBSERVER 0x02000000\n");
18141814
out($f,"\n");
18151815
out($f,"static const uint32_t *zend_spec_handlers;\n");
1816-
out($f,"static const void * const *zend_opcode_handlers;\n");
1816+
out($f,"static zend_vm_opcode_handler_t const *zend_opcode_handlers;\n");
18171817
out($f,"static int zend_handlers_count;\n");
18181818
if ($kind == ZEND_VM_KIND_HYBRID) {
18191819
out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
1820-
out($f,"static const void * const * zend_opcode_handler_funcs;\n");
1820+
out($f,"static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;\n");
18211821
out($f,"static zend_op hybrid_halt_op;\n");
18221822
out($f,"#endif\n");
18231823
}
18241824
out($f,"#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n");
1825-
out($f,"static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n");
1825+
out($f,"static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n");
18261826
out($f,"#endif\n\n");
18271827
if ($kind == ZEND_VM_KIND_HYBRID) {
18281828
out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
@@ -2040,7 +2040,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
20402040
break;
20412041
case "HELPER_VARS":
20422042
if ($kind == ZEND_VM_KIND_SWITCH) {
2043-
out($f,$m[1]."const void *dispatch_handler;\n");
2043+
out($f,$m[1]."zend_vm_opcode_handler_t dispatch_handler;\n");
20442044
}
20452045
if ($kind != ZEND_VM_KIND_CALL && count($params)) {
20462046
if ($kind == ZEND_VM_KIND_HYBRID) {
@@ -2097,8 +2097,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
20972097
out($f,$prolog."\tstatic const void * const labels[] = {\n");
20982098
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_GOTO : $kind, $prolog."\t\t", $specs);
20992099
out($f,$prolog."\t};\n");
2100-
out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n");
2101-
out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
2100+
out($f,$prolog."\tzend_opcode_handlers = (zend_vm_opcode_handler_t*) labels;\n");
2101+
out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(labels[0]);\n");
21022102
if ($kind == ZEND_VM_KIND_HYBRID) {
21032103
out($f,$prolog."\tmemset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op));\n");
21042104
out($f,$prolog."\thybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL;\n");
@@ -2212,7 +2212,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
22122212
out($f,$prolog."zend_spec_handlers = specs;\n");
22132213
out($f,$prolog.$executor_name."_ex(NULL);\n");
22142214
} else {
2215-
out($f,$prolog."static const void * const labels[] = {\n");
2215+
out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
2216+
out($f,$prolog."static zend_vm_opcode_handler_func_t const labels[] = {\n");
2217+
out($f,"#else\n");
2218+
out($f,$prolog."static zend_vm_opcode_handler_t const labels[] = {\n");
2219+
out($f,"#endif\n");
22162220
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_CALL : $kind, $prolog."\t", $specs, $switch_labels);
22172221
out($f,$prolog."};\n");
22182222
out($f,$prolog."static const uint32_t specs[] = {\n");
@@ -2226,7 +2230,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
22262230
out($f,"#else\n");
22272231
}
22282232
out($f,$prolog."zend_opcode_handlers = labels;\n");
2229-
out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(void*);\n");
2233+
out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(labels[0]);\n");
22302234
out($f,$prolog."zend_spec_handlers = specs;\n");
22312235
if ($kind == ZEND_VM_KIND_HYBRID) {
22322236
out($f,"#endif\n");
@@ -2359,6 +2363,20 @@ function gen_vm_opcodes_header(
23592363
$str .= "# endif\n";
23602364
$str .= "#endif\n";
23612365
$str .= "\n";
2366+
$str .= "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID\n";
2367+
$str .= "typedef const void* zend_vm_opcode_handler_t;\n";
2368+
$str .= "typedef void (ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(void);\n";
2369+
$str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL\n";
2370+
$str .= "typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);\n";
2371+
$str .= "typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);\n";
2372+
$str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_SWITCH\n";
2373+
$str .= "typedef int zend_vm_opcode_handler_t;\n";
2374+
$str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_GOTO\n";
2375+
$str .= "typedef const void* zend_vm_opcode_handler_t;\n";
2376+
$str .= "#else\n";
2377+
$str .= "# error\n";
2378+
$str .= "#endif\n";
2379+
$str .= "\n";
23622380
foreach ($vm_op_flags as $name => $val) {
23632381
$str .= sprintf("#define %-24s 0x%08x\n", $name, $val);
23642382
}
@@ -2840,7 +2858,7 @@ function gen_vm($def, $skel) {
28402858
}
28412859
out($f, "}\n\n");
28422860
out($f, "#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n");
2843-
out($f, "static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)\n");
2861+
out($f, "static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)\n");
28442862
out($f, "{\n");
28452863
if (!ZEND_VM_SPEC) {
28462864
out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");

Zend/zend_vm_opcodes.h

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

ext/opcache/jit/zend_jit.c

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ static size_t dasm_size = 0;
9090

9191
static zend_long jit_bisect_pos = 0;
9292

93-
static const void *zend_jit_runtime_jit_handler = NULL;
94-
static const void *zend_jit_profile_jit_handler = NULL;
95-
static const void *zend_jit_func_hot_counter_handler = NULL;
96-
static const void *zend_jit_loop_hot_counter_handler = NULL;
97-
static const void *zend_jit_func_trace_counter_handler = NULL;
98-
static const void *zend_jit_ret_trace_counter_handler = NULL;
99-
static const void *zend_jit_loop_trace_counter_handler = NULL;
93+
static zend_vm_opcode_handler_t zend_jit_runtime_jit_handler = NULL;
94+
static zend_vm_opcode_handler_t zend_jit_profile_jit_handler = NULL;
95+
static zend_vm_opcode_handler_t zend_jit_func_hot_counter_handler = NULL;
96+
static zend_vm_opcode_handler_t zend_jit_loop_hot_counter_handler = NULL;
97+
static zend_vm_opcode_handler_t zend_jit_func_trace_counter_handler = NULL;
98+
static zend_vm_opcode_handler_t zend_jit_ret_trace_counter_handler = NULL;
99+
static zend_vm_opcode_handler_t zend_jit_loop_trace_counter_handler = NULL;
100100

101101
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS);
102102

@@ -1417,7 +1417,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
14171417
zend_jit_ctx ctx;
14181418
zend_jit_ctx *jit = &ctx;
14191419
zend_jit_reg_var *ra = NULL;
1420-
void *handler;
1420+
zend_vm_opcode_handler_t handler;
14211421
int call_level = 0;
14221422
void *checkpoint = NULL;
14231423
bool recv_emitted = 0; /* emitted at least one RECV opcode */
@@ -3213,7 +3213,7 @@ static void zend_jit_setup_hot_counters_ex(zend_op_array *op_array, zend_cfg *cf
32133213
}
32143214
}
32153215

3216-
opline->handler = (const void*)zend_jit_func_hot_counter_handler;
3216+
opline->handler = zend_jit_func_hot_counter_handler;
32173217
}
32183218

32193219
if (JIT_G(hot_loop)) {
@@ -3223,7 +3223,7 @@ static void zend_jit_setup_hot_counters_ex(zend_op_array *op_array, zend_cfg *cf
32233223
if ((cfg->blocks[i].flags & ZEND_BB_REACHABLE) &&
32243224
(cfg->blocks[i].flags & ZEND_BB_LOOP_HEADER)) {
32253225
op_array->opcodes[cfg->blocks[i].start].handler =
3226-
(const void*)zend_jit_loop_hot_counter_handler;
3226+
zend_jit_loop_hot_counter_handler;
32273227
}
32283228
}
32293229
}
@@ -3316,7 +3316,7 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
33163316
jit_extension->op_array = op_array;
33173317
jit_extension->orig_handler = (void*)opline->handler;
33183318
ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension);
3319-
opline->handler = (const void*)zend_jit_runtime_jit_handler;
3319+
opline->handler = zend_jit_runtime_jit_handler;
33203320
zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension);
33213321

33223322
return SUCCESS;
@@ -3346,7 +3346,7 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
33463346
jit_extension->op_array = op_array;
33473347
jit_extension->orig_handler = (void*)opline->handler;
33483348
ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension);
3349-
opline->handler = (const void*)zend_jit_profile_jit_handler;
3349+
opline->handler = zend_jit_profile_jit_handler;
33503350
zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension);
33513351
}
33523352

@@ -3566,23 +3566,23 @@ void zend_jit_protect(void)
35663566

35673567
static void zend_jit_init_handlers(void)
35683568
{
3569-
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
3570-
zend_jit_runtime_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit];
3571-
zend_jit_profile_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_profile_jit];
3572-
zend_jit_func_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter];
3573-
zend_jit_loop_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter];
3574-
zend_jit_func_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter];
3575-
zend_jit_ret_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter];
3576-
zend_jit_loop_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter];
3577-
} else {
3578-
zend_jit_runtime_jit_handler = (const void*)zend_runtime_jit;
3579-
zend_jit_profile_jit_handler = (const void*)zend_jit_profile_helper;
3580-
zend_jit_func_hot_counter_handler = (const void*)zend_jit_func_counter_helper;
3581-
zend_jit_loop_hot_counter_handler = (const void*)zend_jit_loop_counter_helper;
3582-
zend_jit_func_trace_counter_handler = (const void*)zend_jit_func_trace_helper;
3583-
zend_jit_ret_trace_counter_handler = (const void*)zend_jit_ret_trace_helper;
3584-
zend_jit_loop_trace_counter_handler = (const void*)zend_jit_loop_trace_helper;
3585-
}
3569+
#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID
3570+
zend_jit_runtime_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit];
3571+
zend_jit_profile_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_profile_jit];
3572+
zend_jit_func_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter];
3573+
zend_jit_loop_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter];
3574+
zend_jit_func_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter];
3575+
zend_jit_ret_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter];
3576+
zend_jit_loop_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter];
3577+
#else
3578+
zend_jit_runtime_jit_handler = zend_runtime_jit;
3579+
zend_jit_profile_jit_handler = zend_jit_profile_helper;
3580+
zend_jit_func_hot_counter_handler = zend_jit_func_counter_helper;
3581+
zend_jit_loop_hot_counter_handler = zend_jit_loop_counter_helper;
3582+
zend_jit_func_trace_counter_handler = zend_jit_func_trace_helper;
3583+
zend_jit_ret_trace_counter_handler = zend_jit_ret_trace_helper;
3584+
zend_jit_loop_trace_counter_handler = zend_jit_loop_trace_helper;
3585+
#endif
35863586
}
35873587

35883588
static void zend_jit_globals_ctor(zend_jit_globals *jit_globals)
@@ -3945,9 +3945,9 @@ static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array)
39453945
}
39463946
}
39473947
if (func_info->flags & ZEND_FUNC_JIT_ON_FIRST_EXEC) {
3948-
opline->handler = (const void*)zend_jit_runtime_jit_handler;
3948+
opline->handler = zend_jit_runtime_jit_handler;
39493949
} else {
3950-
opline->handler = (const void*)zend_jit_profile_jit_handler;
3950+
opline->handler = zend_jit_profile_jit_handler;
39513951
}
39523952
#endif
39533953
}

0 commit comments

Comments
 (0)