Skip to content

Commit 39a4a33

Browse files
committed
Re-use trampoline call frame, use an opcode-based trampoline
Like __call trampolines, we can use an opcode-based trampoline to reduce recursion/reentering, and reuse the call frame of the trampoline. Also: Rebase fixes, update tests, add tests.
1 parent 652a058 commit 39a4a33

File tree

74 files changed

+2125
-1255
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+2125
-1255
lines changed

Zend/Optimizer/compact_literals.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
734734
case ZEND_SEND_VAR_NO_REF_EX:
735735
case ZEND_SEND_REF:
736736
case ZEND_SEND_FUNC_ARG:
737+
case ZEND_SEND_PLACEHOLDER:
737738
case ZEND_CHECK_FUNC_ARG:
738739
if (opline->op2_type == IS_CONST) {
739740
opline->result.num = cache_size;

Zend/Optimizer/optimize_func_calls.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
193193
case ZEND_DO_UCALL:
194194
case ZEND_DO_FCALL_BY_NAME:
195195
case ZEND_CALLABLE_CONVERT:
196+
case ZEND_CALLABLE_CONVERT_PARTIAL:
196197
call--;
197198
if (call_stack[call].func && call_stack[call].opline) {
198199
zend_op *fcall = call_stack[call].opline;
@@ -225,13 +226,14 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
225226
* At this point we also know whether or not the result of
226227
* the DO opcode is used, allowing to optimize calls to
227228
* ZEND_ACC_NODISCARD functions. */
228-
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
229+
if (opline->opcode != ZEND_CALLABLE_CONVERT && opline->opcode != ZEND_CALLABLE_CONVERT_PARTIAL) {
229230
opline->opcode = zend_get_call_op(fcall, call_stack[call].func, !RESULT_UNUSED(opline));
230231
}
231232

232233
if ((ZEND_OPTIMIZER_PASS_16 & ctx->optimization_level)
233234
&& call_stack[call].try_inline
234-
&& opline->opcode != ZEND_CALLABLE_CONVERT) {
235+
&& opline->opcode != ZEND_CALLABLE_CONVERT
236+
&& opline->opcode != ZEND_CALLABLE_CONVERT_PARTIAL) {
235237
zend_try_inline_call(op_array, fcall, opline, call_stack[call].func);
236238
}
237239
}

Zend/Optimizer/zend_call_graph.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ ZEND_API void zend_analyze_calls(zend_arena **arena, zend_script *script, uint32
128128
case ZEND_DO_UCALL:
129129
case ZEND_DO_FCALL_BY_NAME:
130130
case ZEND_CALLABLE_CONVERT:
131-
case ZEND_DO_FCALL_PARTIAL:
131+
case ZEND_CALLABLE_CONVERT_PARTIAL:
132132
func_info->flags |= ZEND_FUNC_HAS_CALLS;
133133
if (call_info) {
134134
call_info->caller_call_opline = opline;

Zend/Optimizer/zend_inference.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3901,6 +3901,7 @@ static zend_always_inline zend_result _zend_update_type_info(
39013901
}
39023902
break;
39033903
case ZEND_CALLABLE_CONVERT:
3904+
case ZEND_CALLABLE_CONVERT_PARTIAL:
39043905
UPDATE_SSA_TYPE(MAY_BE_OBJECT | MAY_BE_RC1 | MAY_BE_RCN, ssa_op->result_def);
39053906
UPDATE_SSA_OBJ_TYPE(zend_ce_closure, /* is_instanceof */ false, ssa_op->result_def);
39063907
break;

Zend/tests/partial_application/compile_errors_003.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ Partial application compile errors: named arguments must come after placeholder
55
foo(n: 5, ?);
66
?>
77
--EXPECTF--
8-
Fatal error: Named arguments must come after all placeholders in %s on line %d
8+
Fatal error: Cannot use positional argument after named argument in %s on line %d
99

Zend/tests/partial_application/compile_errors_004.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ Partial application compile errors: named arguments must come after variadic pla
55
foo(n: 5, ...);
66
?>
77
--EXPECTF--
8-
Fatal error: Named arguments must come after all placeholders in %s on line %d
8+
Fatal error: Cannot use positional argument after named argument in %s on line %d

Zend/tests/partial_application/compile_errors_006.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@ Partial application compile errors: mix application with unpack (placeholder aft
55
foo(...["foo" => "bar"], ...);
66
?>
77
--EXPECTF--
8-
Fatal error: Cannot combine partial application and unpacking %s on line %d
8+
Fatal error: Cannot use positional argument after argument unpacking %s on line %d
99

Zend/tests/partial_application/errors_003.phpt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ try {
1919
$foo = foo(?, ?);
2020

2121
try {
22-
$foo(1);
22+
$foo(1);
2323
} catch (Error $ex) {
2424
printf("%s\n", $ex->getMessage());
2525
}
@@ -46,10 +46,10 @@ try {
4646
printf("%s\n", $ex->getMessage());
4747
}
4848

49-
$usleep = usleep(...);
49+
$repeat = str_repeat('a', ...);
5050

5151
try {
52-
$usleep();
52+
$repeat();
5353
} catch (Error $ex) {
5454
printf("%s\n", $ex->getMessage());
5555
}
@@ -71,8 +71,8 @@ try {
7171
--EXPECTF--
7272
not enough arguments for application of foo, 0 given and exactly 1 expected, declared in %s on line 8
7373
not enough arguments for application of foo, 1 given and exactly 2 expected, declared in %s on line 16
74-
not enough arguments for application of bar, 1 given and at least 2 expected, declared in %s on line 24
74+
not enough arguments for application of bar, 1 given and at least 3 expected, declared in %s on line 24
7575
not enough arguments for application of Foo::bar, 0 given and exactly 1 expected, declared in %s on line 38
76-
not enough arguments for implementation of usleep, 0 given and exactly 1 expected
77-
not enough arguments for application of usleep, 0 given and exactly 1 expected
78-
too many arguments for application of usleep, 2 given and a maximum of 1 expected
76+
not enough arguments for application of str_repeat, 0 given and at least 1 expected, declared in %s on line 46
77+
not enough arguments for application of usleep, 0 given and exactly 1 expected, declared in %s on line 54
78+
too many arguments for application of usleep, 2 given and a maximum of 1 expected, declared in %s on line 54

Zend/tests/partial_application/export_001.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ assert.exception=1
55
--FILE--
66
<?php
77
try {
8-
assert(0 && foo(?) && foo(...));
8+
assert(0 && foo(?) && foo(new stdClass, ...));
99
} catch (Error $ex) {
1010
printf("%s\n", $ex->getMessage());
1111
}
1212
?>
1313
--EXPECT--
14-
assert(0 && foo(?) && foo(...))
14+
assert(0 && foo(?) && foo(new stdClass(), ...))

Zend/tests/partial_application/factory_001.phpt

Lines changed: 0 additions & 24 deletions
This file was deleted.

0 commit comments

Comments
 (0)