Fix other typos & add test script

This commit is contained in:
Xinchen Hui 2013-04-19 11:06:38 +08:00
parent 580d6fe94d
commit 676e737f5b
2 changed files with 136 additions and 6 deletions

View File

@ -81,7 +81,7 @@ static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script
case ZEND_FETCH_OBJ_FUNC_ARG: case ZEND_FETCH_OBJ_FUNC_ARG:
case ZEND_FETCH_DIM_FUNC_ARG: case ZEND_FETCH_DIM_FUNC_ARG:
if (call_stack[call - 1].func) { if (call_stack[call - 1].func) {
if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call].func, (opline->extended_value & ZEND_FETCH_ARG_MASK))) { if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
opline->extended_value = 0; opline->extended_value = 0;
opline->opcode -= 9; opline->opcode -= 9;
} else { } else {
@ -92,9 +92,9 @@ static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script
break; break;
case ZEND_SEND_VAL: case ZEND_SEND_VAL:
if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && call_stack[call - 1].func) { if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && call_stack[call - 1].func) {
if (ARG_MUST_BE_SENT_BY_REF(call_stack[call].func, opline->op2.num)) { if (ARG_MUST_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
/* We won't convert it into_DO_FCALL to emit error at run-time */ /* We won't convert it into_DO_FCALL to emit error at run-time */
call_stack[call].opline = NULL; call_stack[call - 1].opline = NULL;
} else { } else {
opline->extended_value = ZEND_DO_FCALL; opline->extended_value = ZEND_DO_FCALL;
} }
@ -102,7 +102,7 @@ static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script
break; break;
case ZEND_SEND_VAR: case ZEND_SEND_VAR:
if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && call_stack[call - 1].func) { if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && call_stack[call - 1].func) {
if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call].func, opline->op2.num)) { if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
opline->opcode = ZEND_SEND_REF; opline->opcode = ZEND_SEND_REF;
} }
opline->extended_value = ZEND_DO_FCALL; opline->extended_value = ZEND_DO_FCALL;
@ -110,7 +110,7 @@ static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script
break; break;
case ZEND_SEND_VAR_NO_REF: case ZEND_SEND_VAR_NO_REF:
if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) && call_stack[call - 1].func) { if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) && call_stack[call - 1].func) {
if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call].func, opline->op2.num)) { if (ARG_SHOULD_BE_SENT_BY_REF(call_stack[call - 1].func, opline->op2.num)) {
opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND | ZEND_ARG_SEND_BY_REF; opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND | ZEND_ARG_SEND_BY_REF;
} else if (opline->extended_value) { } else if (opline->extended_value) {
opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND; opline->extended_value |= ZEND_ARG_COMPILE_TIME_BOUND;
@ -123,7 +123,7 @@ static void optimize_func_calls(zend_op_array *op_array, zend_persistent_script
case ZEND_SEND_REF: case ZEND_SEND_REF:
if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && call_stack[call - 1].func) { if (opline->extended_value == ZEND_DO_FCALL_BY_NAME && call_stack[call - 1].func) {
/* We won't handle run-time pass by reference */ /* We won't handle run-time pass by reference */
call_stack[call].opline = NULL; call_stack[call - 1].opline = NULL;
} }
break; break;

View File

@ -0,0 +1,130 @@
--TEST--
Test with optimization of function calls
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.optimization_level=-1
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
class A {
public $obj;
public function test($a) {
}
}
function a(&$b) {
$b = "changed";
return "done";
}
$a = "a";
$b = "b";
$c = "c";
$f = "a";
/*
* INIT_FCALL_BY_NAME
* SEND_VAR
* DO_FCALL
* DO_FCALL_BY_NAME
*/
foo(a($a));
var_dump($a);
$a = "a";
/*
* INIT_FCALL_BY_NAME
* INIT_FCALL_BY_NAME -- un-optimizable
* DO_FCALL_BY_NAME -- un-optimizable
* DO_FCALL_BY_NAME
*/
foo($f($a));
var_dump($a);
/*
* INIT_FCALL_BY_NAME
* ZEND_NEW
* DO_FCALL_BY_NAME
* DO_FCALL_BY_NAME
*/
foo(new A());
/*
* INIT_FCALL_BY_NAME
* FETCH_OBJ_FUNC_ARG
* ZEND_SEND_VAR
* DO_FCALL_BY_NAME
*/
foo((new A)->obj);
$obj = new A;
ref($obj->obj);
var_dump($obj->obj);
ref(retarray()[0]);
$a = "a";
foo(a($a), $a, ref($b, $c), $obj);
var_dump($a);
var_dump($b);
/*
* INIT_FCALL_BY_NAME
* SEND_VAL
* DO_FCALL_BY_NAME
*/
ref("xxx");
function retarray() {
return array("retarray");
}
function foo($a) {
print_r(func_get_args());
}
function ref(&$b) {
$b = "changed";
return "ref";
}
--EXPECTF--
Array
(
[0] => done
)
string(7) "changed"
Array
(
[0] => done
)
string(7) "changed"
Array
(
[0] => A Object
(
[obj] =>
)
)
Array
(
[0] =>
)
string(7) "changed"
Array
(
[0] => done
[1] => changed
[2] => ref
[3] => A Object
(
[obj] => changed
)
)
string(7) "changed"
string(7) "changed"
Fatal error: Cannot pass parameter 1 by reference in %soptimize_func_calls.php on line %d