Skip to content

Commit 5c30acd

Browse files
committed
Refactoring
1 parent 1e1c94a commit 5c30acd

File tree

6 files changed

+44
-74
lines changed

6 files changed

+44
-74
lines changed

Zend/Optimizer/sccp.c

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -789,14 +789,10 @@ static bool can_ct_eval_func_call(zend_function *func, zend_string *name, uint32
789789
/* The functions chosen here are simple to implement and either likely to affect a branch,
790790
* or just happened to be commonly used with constant operands in WP (need to test other
791791
* applications as well, of course). */
792-
static inline zend_result ct_eval_func_call(
793-
zend_op_array *op_array, zval *result, zend_string *name, uint32_t num_args, zval **args) {
792+
static inline zend_result ct_eval_func_call_ex(
793+
zend_op_array *op_array, zval *result, zend_function *func, uint32_t num_args, zval **args) {
794794
uint32_t i;
795-
zend_function *func = zend_hash_find_ptr(CG(function_table), name);
796-
if (!func || func->type != ZEND_INTERNAL_FUNCTION) {
797-
return FAILURE;
798-
}
799-
795+
zend_string *name = func->common.function_name;
800796
if (num_args == 1 && Z_TYPE_P(args[0]) == IS_STRING &&
801797
zend_optimizer_eval_special_func_call(result, name, Z_STR_P(args[0])) == SUCCESS) {
802798
return SUCCESS;
@@ -855,6 +851,15 @@ static inline zend_result ct_eval_func_call(
855851
return retval;
856852
}
857853

854+
static inline zend_result ct_eval_func_call(
855+
zend_op_array *op_array, zval *result, zend_string *name, uint32_t num_args, zval **args) {
856+
zend_function *func = zend_hash_find_ptr(CG(function_table), name);
857+
if (!func || func->type != ZEND_INTERNAL_FUNCTION) {
858+
return FAILURE;
859+
}
860+
return ct_eval_func_call_ex(op_array, result, func, num_args, args);
861+
}
862+
858863
#define SET_RESULT(op, zv) do { \
859864
if (ssa_op->op##_def >= 0) { \
860865
set_value(scdf, ctx, ssa_op->op##_def, zv); \
@@ -1713,32 +1718,22 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
17131718
case ZEND_FRAMELESS_ICALL_2:
17141719
case ZEND_FRAMELESS_ICALL_3: {
17151720
zval *args[3] = {NULL};
1716-
uint32_t num_args = opline->opcode - ZEND_FRAMELESS_ICALL_0;
1717-
zend_function **funcs;
17181721
switch (opline->opcode) {
1719-
case ZEND_FRAMELESS_ICALL_0:
1720-
funcs = zend_frameless_function_0_functions;
1721-
break;
1722-
case ZEND_FRAMELESS_ICALL_1:
1723-
args[0] = get_op1_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1724-
funcs = zend_frameless_function_1_functions;
1725-
break;
1726-
case ZEND_FRAMELESS_ICALL_2:
1727-
args[0] = get_op1_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1728-
args[1] = get_op2_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1729-
funcs = zend_frameless_function_2_functions;
1730-
break;
17311722
case ZEND_FRAMELESS_ICALL_3: {
17321723
zend_op *op_data = opline + 1;
1733-
args[0] = get_op1_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1734-
args[1] = get_op2_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
17351724
args[2] = get_op2_value(ctx, op_data, &ctx->scdf.ssa->ops[op_data - ctx->scdf.op_array->opcodes]);
1736-
funcs = zend_frameless_function_3_functions;
1737-
break;
1725+
ZEND_FALLTHROUGH;
17381726
}
1727+
case ZEND_FRAMELESS_ICALL_2:
1728+
args[1] = get_op2_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1729+
ZEND_FALLTHROUGH;
1730+
case ZEND_FRAMELESS_ICALL_1:
1731+
args[0] = get_op1_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1732+
break;
17391733
}
1740-
zend_function *func = funcs[opline->extended_value];
1741-
if (ct_eval_func_call(scdf->op_array, &zv, func->common.function_name, num_args, args) == SUCCESS) {
1734+
uint32_t num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
1735+
zend_function *func = (*zend_frameless_function_0_functions_lists[num_args])[opline->extended_value];
1736+
if (ct_eval_func_call_ex(scdf->op_array, &zv, func, num_args, args) == SUCCESS) {
17421737
SET_RESULT(result, &zv);
17431738
zval_ptr_dtor_nogc(&zv);
17441739
break;

Zend/zend_builtin_functions.c

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,31 +1804,14 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
18041804
/* For frameless calls we add an additional frame for the call itself. */
18051805
if (ZEND_USER_CODE(call->func->type)) {
18061806
const zend_op *opline = call->opline;
1807-
zend_function **functions;
1808-
int arity;
1809-
switch (opline->opcode) {
1810-
case ZEND_FRAMELESS_ICALL_0:
1811-
functions = zend_frameless_function_0_functions;
1812-
arity = 0;
1813-
break;
1814-
case ZEND_FRAMELESS_ICALL_1:
1815-
functions = zend_frameless_function_1_functions;
1816-
arity = 1;
1817-
break;
1818-
case ZEND_FRAMELESS_ICALL_2:
1819-
functions = zend_frameless_function_2_functions;
1820-
arity = 2;
1821-
break;
1822-
case ZEND_FRAMELESS_ICALL_3:;
1823-
functions = zend_frameless_function_3_functions;
1824-
arity = 3;
1825-
break;
1826-
default:
1827-
goto not_frameless_call;
1807+
if (!ZEND_OP_IS_FRAMELESS_ICALL(opline->opcode)) {
1808+
goto not_frameless_call;
18281809
}
1810+
int num_args = ZEND_FLF_NUM_ARGS(opline->opcode);
18291811
stack_frame = zend_new_array(8);
18301812
zend_hash_real_init_mixed(stack_frame);
1831-
zend_string *name = functions[opline->extended_value]->common.function_name;
1813+
zend_function *func = (*zend_frameless_function_0_functions_lists[num_args])[opline->extended_value];
1814+
zend_string *name = func->common.function_name;
18321815
ZVAL_STRINGL(&tmp, ZSTR_VAL(name), ZSTR_LEN(name));
18331816
_zend_hash_append_ex(stack_frame, ZSTR_KNOWN(ZEND_STR_FUNCTION), &tmp, 1);
18341817
/* Steal file and line from the previous frame. */
@@ -1849,17 +1832,17 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
18491832
if ((options & DEBUG_BACKTRACE_IGNORE_ARGS) == 0) {
18501833
HashTable *args = zend_new_array(8);
18511834
zend_hash_real_init_mixed(args);
1852-
if (arity >= 1) {
1835+
if (num_args >= 1) {
18531836
zval *arg = zend_get_zval_ptr(opline, opline->op1_type, &opline->op1, call);
18541837
Z_TRY_ADDREF_P(arg);
18551838
zend_hash_next_index_insert_new(args, arg);
18561839
}
1857-
if (arity >= 2) {
1840+
if (num_args >= 2) {
18581841
zval *arg = zend_get_zval_ptr(opline, opline->op2_type, &opline->op2, call);
18591842
Z_TRY_ADDREF_P(arg);
18601843
zend_hash_next_index_insert_new(args, arg);
18611844
}
1862-
if (arity >= 3) {
1845+
if (num_args >= 3) {
18631846
const zend_op *op_data = opline + 1;
18641847
zval *arg = zend_get_zval_ptr(op_data, op_data->op1_type, &op_data->op1, call);
18651848
Z_TRY_ADDREF_P(arg);

Zend/zend_compile.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4576,20 +4576,17 @@ static zend_result zend_compile_frameless_icall(znode *result, zend_ast_list *ar
45764576
if (offset == (uint32_t)-1) {
45774577
continue;
45784578
}
4579-
uint8_t opcode = ZEND_FRAMELESS_ICALL_0;
45804579
znode arg1, arg2, arg3;
45814580
if (args->children >= 1) {
4582-
opcode = ZEND_FRAMELESS_ICALL_1;
45834581
zend_compile_expr(&arg1, args->child[0]);
45844582
}
45854583
if (args->children >= 2) {
4586-
opcode = ZEND_FRAMELESS_ICALL_2;
45874584
zend_compile_expr(&arg2, args->child[1]);
45884585
}
45894586
if (args->children >= 3) {
4590-
opcode = ZEND_FRAMELESS_ICALL_3;
45914587
zend_compile_expr(&arg3, args->child[2]);
45924588
}
4589+
uint8_t opcode = ZEND_FRAMELESS_ICALL_0 + args->children;
45934590
zend_op *opline = zend_emit_op_tmp(result, opcode, NULL, NULL);
45944591
if (args->children >= 1) {
45954592
SET_NODE(opline->op1, &arg1);

Zend/zend_execute_API.c

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -568,26 +568,11 @@ ZEND_API zend_function *zend_active_function_ex(zend_execute_data *execute_data)
568568
/* Resolve function if op is a frameless call. */
569569
if (ZEND_USER_CODE(func->type)) {
570570
const zend_op *op = EX(opline);
571-
zend_function **functions;
572-
switch (op->opcode) {
573-
case ZEND_FRAMELESS_ICALL_0:
574-
functions = zend_frameless_function_0_functions;
575-
break;
576-
case ZEND_FRAMELESS_ICALL_1:
577-
functions = zend_frameless_function_1_functions;
578-
break;
579-
case ZEND_FRAMELESS_ICALL_2:
580-
functions = zend_frameless_function_2_functions;
581-
break;
582-
case ZEND_FRAMELESS_ICALL_3:
583-
functions = zend_frameless_function_3_functions;
584-
break;
585-
default:
586-
goto not_frameless_call;
571+
if (ZEND_OP_IS_FRAMELESS_ICALL(op->opcode)) {
572+
uint32_t num_args = ZEND_FLF_NUM_ARGS(op->opcode);
573+
func = (*zend_frameless_function_0_functions_lists[num_args])[op->extended_value];
587574
}
588-
func = functions[op->extended_value];
589575
}
590-
not_frameless_call:
591576

592577
return func;
593578
}

Zend/zend_frameless_function.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,10 @@ zend_function **zend_frameless_function_0_functions = NULL;
3737
zend_function **zend_frameless_function_1_functions = NULL;
3838
zend_function **zend_frameless_function_2_functions = NULL;
3939
zend_function **zend_frameless_function_3_functions = NULL;
40+
41+
zend_function ** const* zend_frameless_function_0_functions_lists[] = {
42+
&zend_frameless_function_0_functions,
43+
&zend_frameless_function_1_functions,
44+
&zend_frameless_function_2_functions,
45+
&zend_frameless_function_3_functions,
46+
};

Zend/zend_frameless_function.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#define DIRECT_FUNCTION_PARAMETERS_3 zval *return_value, zval *arg1, zval *arg2, zval *arg3
2727

2828
#define ZEND_FRAMELESS_FUNCTION_NAME(name, arity) zdc_##name##_##arity
29+
#define ZEND_OP_IS_FRAMELESS_ICALL(opcode) ((opcode) >= ZEND_FRAMELESS_ICALL_0 && (opcode) <= ZEND_FRAMELESS_ICALL_3)
30+
#define ZEND_FLF_NUM_ARGS(opcode) ((opcode) - ZEND_FRAMELESS_ICALL_0)
2931

3032
#define ZEND_FRAMELESS_FUNCTION(name, arity) \
3133
void ZEND_FRAMELESS_FUNCTION_NAME(name, arity)(DIRECT_FUNCTION_PARAMETERS_##arity)
@@ -92,6 +94,7 @@ extern zend_function **zend_frameless_function_0_functions;
9294
extern zend_function **zend_frameless_function_1_functions;
9395
extern zend_function **zend_frameless_function_2_functions;
9496
extern zend_function **zend_frameless_function_3_functions;
97+
extern zend_function ** const* zend_frameless_function_0_functions_lists[];
9598

9699
typedef struct {
97100
void *handler;

0 commit comments

Comments
 (0)