summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-04-08 01:41:48 +0200
committerNikita Popov <nikic@php.net>2016-04-27 17:10:44 +0200
commit4f54c15cb10dfd668538ae225fef59c82c66e96e (patch)
tree6592ba1551f755c16dab290f2e5fe5984b6637ca /ext
parent480c5ed2be6bbd6d8f7e55b33e77e141f9d9d08f (diff)
downloadphp-git-4f54c15cb10dfd668538ae225fef59c82c66e96e.tar.gz
Ct bind private/final $this method call args
The test covers two edge-cases wrt opcache support.
Diffstat (limited to 'ext')
-rw-r--r--ext/opcache/Optimizer/optimize_func_calls.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c
index 55612d7fa0..c3c519ab4c 100644
--- a/ext/opcache/Optimizer/optimize_func_calls.c
+++ b/ext/opcache/Optimizer/optimize_func_calls.c
@@ -86,10 +86,28 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
call_stack[call].func = zend_hash_find_ptr(&ce->function_table, func_name);
}
}
+ call_stack[call].opline = opline;
+ call++;
+ break;
+ case ZEND_INIT_METHOD_CALL:
+ if (opline->op1_type == IS_UNUSED && ZEND_OP2_IS_CONST_STRING(opline)
+ && op_array->scope && !(op_array->scope->ce_flags & ZEND_ACC_TRAIT)) {
+ zend_string *method_name = Z_STR_P(&ZEND_OP2_LITERAL(opline) + 1);
+ zend_function *fbc = zend_hash_find_ptr(
+ &op_array->scope->function_table, method_name);
+ if (fbc) {
+ zend_bool is_private = (fbc->common.fn_flags & ZEND_ACC_PRIVATE) != 0;
+ zend_bool is_final = (fbc->common.fn_flags & ZEND_ACC_FINAL) != 0;
+ zend_bool same_scope = fbc->common.scope == op_array->scope;
+ if ((is_private && same_scope)
+ || (is_final && (!is_private || same_scope))) {
+ call_stack[call].func = fbc;
+ }
+ }
+ }
/* break missing intentionally */
case ZEND_NEW:
case ZEND_INIT_DYNAMIC_CALL:
- case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_FCALL:
case ZEND_INIT_USER_CALL:
call_stack[call].opline = opline;
@@ -118,7 +136,8 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
literal_dtor(&op_array->literals[fcall->op2.constant + 2]);
fcall->op2.constant = fcall->op2.constant + 1;
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
- } else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL) {
+ } else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL
+ || fcall->opcode == ZEND_INIT_METHOD_CALL) {
/* We don't have specialized opcodes for this, do nothing */
} else {
ZEND_ASSERT(0);