Skip to content

Commit 2068a9d

Browse files
committed
zend_compile: Support static methods for array_map() optimization
1 parent cff8da5 commit 2068a9d

File tree

2 files changed

+104
-8
lines changed

2 files changed

+104
-8
lines changed

Zend/zend_compile.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5037,19 +5037,24 @@ static zend_result zend_compile_func_array_map(znode *result, zend_ast_list *arg
50375037
zend_ast *callback = args->child[0];
50385038

50395039
/* Bail out if the callback is not a FCC/PFA. */
5040-
if (callback->kind != ZEND_AST_CALL) {
5041-
return FAILURE;
5042-
}
5040+
zend_ast *args_ast;
5041+
switch (callback->kind) {
5042+
case ZEND_AST_CALL:
5043+
case ZEND_AST_STATIC_CALL:
5044+
args_ast = zend_ast_call_get_args(callback);
5045+
if (args_ast->kind != ZEND_AST_CALLABLE_CONVERT) {
5046+
return FAILURE;
5047+
}
50435048

5044-
zend_ast *args_ast = zend_ast_call_get_args(callback);
5045-
if (args_ast->kind != ZEND_AST_CALLABLE_CONVERT) {
5046-
return FAILURE;
5049+
break;
5050+
default:
5051+
return FAILURE;
50475052
}
50485053

50495054
/* Bail out if the callback is assert() due to the AST stringification logic
50505055
* breaking for the generated call.
50515056
*/
5052-
if (zend_string_equals_literal_ci(zend_ast_get_str(callback->child[0]), "assert")) {
5057+
if (callback->kind == ZEND_AST_CALL && zend_string_equals_literal_ci(zend_ast_get_str(callback->child[0]), "assert")) {
50535058
return FAILURE;
50545059
}
50555060

@@ -5104,7 +5109,14 @@ static zend_result zend_compile_func_array_map(znode *result, zend_ast_list *arg
51045109

51055110
/* loop body */
51065111
znode call_result;
5107-
zend_compile_expr(&call_result, zend_ast_create(ZEND_AST_CALL, callback->child[0], call_args));
5112+
switch (callback->kind) {
5113+
case ZEND_AST_CALL:
5114+
zend_compile_expr(&call_result, zend_ast_create(ZEND_AST_CALL, callback->child[0], call_args));
5115+
break;
5116+
case ZEND_AST_STATIC_CALL:
5117+
zend_compile_expr(&call_result, zend_ast_create(ZEND_AST_STATIC_CALL, callback->child[0], callback->child[1], call_args));
5118+
break;
5119+
}
51085120
opline = zend_emit_op(NULL, ZEND_ADD_ARRAY_ELEMENT, &call_result, &key);
51095121
SET_NODE(opline->result, result);
51105122
/* end loop body */
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
--TEST--
2+
array_map(): foreach optimization - static call
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.opt_debug_level=0x20000
9+
--FILE--
10+
<?php
11+
12+
class Adder {
13+
static function plus1($x) {
14+
return $x + 1;
15+
}
16+
}
17+
18+
$array = range(1, 10);
19+
20+
$foo = array_map(Adder::plus1(...), $array);
21+
22+
var_dump($foo);
23+
24+
?>
25+
--EXPECTF--
26+
$_main:
27+
; (lines=%d, args=0, vars=%d, tmps=%d)
28+
; (after optimizer)
29+
; %s
30+
0000 INIT_FCALL 2 %d string("range")
31+
0001 SEND_VAL int(1) 1
32+
0002 SEND_VAL int(10) 2
33+
0003 V2 = DO_ICALL
34+
0004 ASSIGN CV0($array) V2
35+
0005 TYPE_ASSERT 131079 string("array_map") CV0($array)
36+
0006 T2 = INIT_ARRAY 0 (packed) NEXT
37+
0007 V3 = FE_RESET_R CV0($array) 0014
38+
0008 T5 = FE_FETCH_R V3 T4 0014
39+
0009 INIT_STATIC_METHOD_CALL 1 string("Adder") string("plus1")
40+
0010 SEND_VAL T4 1
41+
0011 V4 = DO_UCALL
42+
0012 T2 = ADD_ARRAY_ELEMENT V4 T5
43+
0013 JMP 0008
44+
0014 FE_FREE V3
45+
0015 ASSIGN CV1($foo) T2
46+
0016 INIT_FCALL 1 %d string("var_dump")
47+
0017 SEND_VAR CV1($foo) 1
48+
0018 DO_ICALL
49+
0019 RETURN int(1)
50+
LIVE RANGES:
51+
2: 0007 - 0015 (tmp/var)
52+
3: 0008 - 0014 (loop)
53+
4: 0009 - 0010 (tmp/var)
54+
5: 0009 - 0012 (tmp/var)
55+
56+
Adder::plus1:
57+
; (lines=3, args=1, vars=1, tmps=1)
58+
; (after optimizer)
59+
; %s
60+
0000 CV0($x) = RECV 1
61+
0001 T1 = ADD CV0($x) int(1)
62+
0002 RETURN T1
63+
array(10) {
64+
[0]=>
65+
int(2)
66+
[1]=>
67+
int(3)
68+
[2]=>
69+
int(4)
70+
[3]=>
71+
int(5)
72+
[4]=>
73+
int(6)
74+
[5]=>
75+
int(7)
76+
[6]=>
77+
int(8)
78+
[7]=>
79+
int(9)
80+
[8]=>
81+
int(10)
82+
[9]=>
83+
int(11)
84+
}

0 commit comments

Comments
 (0)