Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 466e7a4

Browse files
iluuu1994dstogov
andcommitted
Compile static frameless calls before emitting opcodes
Co-authored-by: Dmitry Stogov <dmitry@zend.com>
1 parent 7be62b7 commit 466e7a4

File tree

1 file changed

+36
-44
lines changed

1 file changed

+36
-44
lines changed

‎Zend/zend_compile.c

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,6 @@
5959

6060
#define FC(member) (CG(file_context).member)
6161

62-
#define ZEND_OP1_LITERAL(opline) (op_array)->literals[(opline)->op1.constant]
63-
#define ZEND_OP2_LITERAL(opline) (op_array)->literals[(opline)->op2.constant]
64-
#define literal_dtor(zv) do { \
65-
zval_ptr_dtor_nogc(zv); \
66-
ZVAL_NULL(zv); \
67-
} while (0)
68-
6962
typedef struct _zend_loop_var {
7063
uint8_t opcode;
7164
uint8_t var_type;
@@ -5336,29 +5329,11 @@ static void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type
53365329
}
53375330
}
53385331

5339-
uint32_t init_opnum = get_next_op_number();
5340-
opline = get_next_op();
5341-
opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
5342-
5343-
zend_set_class_name_op1(opline, &class_node);
5344-
5345-
if (method_node.op_type == IS_CONST) {
5346-
opline->op2_type = IS_CONST;
5347-
opline->op2.constant = zend_add_func_name_literal(
5348-
Z_STR(method_node.u.constant));
5349-
opline->result.num = zend_alloc_cache_slots(2);
5350-
} else {
5351-
if (opline->op1_type == IS_CONST) {
5352-
opline->result.num = zend_alloc_cache_slot();
5353-
}
5354-
SET_NODE(opline->op2, &method_node);
5355-
}
5356-
53575332
/* Check if we already know which method we're calling */
5358-
if (opline->op2_type == IS_CONST) {
5333+
if (method_node.op_type == IS_CONST) {
53595334
zend_class_entry *ce = NULL;
5360-
if (opline->op1_type == IS_CONST) {
5361-
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op1) +1);
5335+
if (class_node.op_type == IS_CONST) {
5336+
zend_string *lcname = zend_string_tolower(Z_STR(class_node.u.constant));
53625337
ce = zend_hash_find_ptr(CG(class_table), lcname);
53635338
if (ce) {
53645339
if (zend_compile_ignore_class(ce, CG(active_op_array)->filename)) {
@@ -5368,31 +5343,48 @@ static void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type
53685343
&& zend_string_equals_ci(CG(active_class_entry)->name, lcname)) {
53695344
ce = CG(active_class_entry);
53705345
}
5371-
} else if (opline->op1_type == IS_UNUSED
5372-
&& (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF
5346+
zend_string_release(lcname);
5347+
} else if (class_node.op_type == IS_UNUSED
5348+
&& (class_node.u.op.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF
53735349
&& zend_is_scope_known()) {
53745350
ce = CG(active_class_entry);
53755351
}
53765352
if (ce) {
5377-
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) +1);
5353+
zend_string *lcname = zend_string_tolower(Z_STR(method_node.u.constant));
53785354
fbc = zend_get_compatible_func_or_null(ce, lcname);
5355+
zend_string_release(lcname);
5356+
5357+
if (fbc
5358+
&& !(CG(compiler_options) & ZEND_COMPILE_NO_BUILTINS)
5359+
&& (fbc->type == ZEND_INTERNAL_FUNCTION)
5360+
&& zend_ast_is_list(args_ast)
5361+
&& !zend_args_contain_unpack_or_named(zend_ast_get_list(args_ast))) {
5362+
if (zend_compile_frameless_icall(result, zend_ast_get_list(args_ast), fbc, type) != (uint32_t)-1) {
5363+
zval_ptr_dtor(&method_node.u.constant);
5364+
if (class_node.op_type == IS_CONST) {
5365+
zval_ptr_dtor(&class_node.u.constant);
5366+
}
5367+
return;
5368+
}
5369+
}
53795370
}
53805371
}
53815372

5382-
if (!(CG(compiler_options) &ZEND_COMPILE_NO_BUILTINS)
5383-
&&fbc
5384-
&& (fbc->type==ZEND_INTERNAL_FUNCTION)
5385-
&&zend_ast_is_list(args_ast)
5386-
&& !zend_args_contain_unpack_or_named(zend_ast_get_list(args_ast))) {
5387-
if (zend_compile_frameless_icall(result, zend_ast_get_list(args_ast), fbc, type) != (uint32_t)-1) {
5388-
/* Update opline in case it got invalidated. */
5389-
zend_op_array*op_array=CG(active_op_array);
5390-
opline=&op_array->opcodes[init_opnum];
5391-
literal_dtor(&ZEND_OP1_LITERAL(opline));
5392-
literal_dtor(&ZEND_OP2_LITERAL(opline));
5393-
MAKE_NOP(opline);
5394-
return;
5373+
opline=get_next_op();
5374+
opline->opcode=ZEND_INIT_STATIC_METHOD_CALL;
5375+
5376+
zend_set_class_name_op1(opline, &class_node);
5377+
5378+
if (method_node.op_type==IS_CONST) {
5379+
opline->op2_type=IS_CONST;
5380+
opline->op2.constant=zend_add_func_name_literal(
5381+
Z_STR(method_node.u.constant));
5382+
opline->result.num=zend_alloc_cache_slots(2);
5383+
} else {
5384+
if(opline->op1_type==IS_CONST) {
5385+
opline->result.num=zend_alloc_cache_slot();
53955386
}
5387+
SET_NODE(opline->op2, &method_node);
53965388
}
53975389

53985390
zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast));

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /