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 ba9092a

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

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;
@@ -5343,29 +5336,11 @@ static void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type
53435336
}
53445337
}
53455338

5346-
uint32_t init_opnum = get_next_op_number();
5347-
opline = get_next_op();
5348-
opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
5349-
5350-
zend_set_class_name_op1(opline, &class_node);
5351-
5352-
if (method_node.op_type == IS_CONST) {
5353-
opline->op2_type = IS_CONST;
5354-
opline->op2.constant = zend_add_func_name_literal(
5355-
Z_STR(method_node.u.constant));
5356-
opline->result.num = zend_alloc_cache_slots(2);
5357-
} else {
5358-
if (opline->op1_type == IS_CONST) {
5359-
opline->result.num = zend_alloc_cache_slot();
5360-
}
5361-
SET_NODE(opline->op2, &method_node);
5362-
}
5363-
53645339
/* Check if we already know which method we're calling */
5365-
if (opline->op2_type == IS_CONST) {
5340+
if (method_node.op_type == IS_CONST) {
53665341
zend_class_entry *ce = NULL;
5367-
if (opline->op1_type == IS_CONST) {
5368-
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op1) +1);
5342+
if (class_node.op_type == IS_CONST) {
5343+
zend_string *lcname = zend_string_tolower(Z_STR(class_node.u.constant));
53695344
ce = zend_hash_find_ptr(CG(class_table), lcname);
53705345
if (ce) {
53715346
if (zend_compile_ignore_class(ce, CG(active_op_array)->filename)) {
@@ -5375,31 +5350,48 @@ static void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type
53755350
&& zend_string_equals_ci(CG(active_class_entry)->name, lcname)) {
53765351
ce = CG(active_class_entry);
53775352
}
5378-
} else if (opline->op1_type == IS_UNUSED
5379-
&& (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF
5353+
zend_string_release(lcname);
5354+
} else if (class_node.op_type == IS_UNUSED
5355+
&& (class_node.u.op.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF
53805356
&& zend_is_scope_known()) {
53815357
ce = CG(active_class_entry);
53825358
}
53835359
if (ce) {
5384-
zend_string *lcname = Z_STR_P(CT_CONSTANT(opline->op2) +1);
5360+
zend_string *lcname = zend_string_tolower(Z_STR(method_node.u.constant));
53855361
fbc = zend_get_compatible_func_or_null(ce, lcname);
5362+
zend_string_release(lcname);
5363+
5364+
if (fbc
5365+
&& !(CG(compiler_options) & ZEND_COMPILE_NO_BUILTINS)
5366+
&& (fbc->type == ZEND_INTERNAL_FUNCTION)
5367+
&& zend_ast_is_list(args_ast)
5368+
&& !zend_args_contain_unpack_or_named(zend_ast_get_list(args_ast))) {
5369+
if (zend_compile_frameless_icall(result, zend_ast_get_list(args_ast), fbc, type) != (uint32_t)-1) {
5370+
zval_ptr_dtor(&method_node.u.constant);
5371+
if (class_node.op_type == IS_CONST) {
5372+
zval_ptr_dtor(&class_node.u.constant);
5373+
}
5374+
return;
5375+
}
5376+
}
53865377
}
53875378
}
53885379

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

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

0 commit comments

Comments
(0)

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