Skip to content

Commit 33ee486

Browse files
committed
Implement sccp ct eval
1 parent 792a6d3 commit 33ee486

File tree

6 files changed

+69
-9
lines changed

6 files changed

+69
-9
lines changed

Zend/Optimizer/sccp.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,44 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
17081708
SET_RESULT_BOT(result);
17091709
break;
17101710
}
1711+
case ZEND_FRAMELESS_ICALL_0:
1712+
case ZEND_FRAMELESS_ICALL_1:
1713+
case ZEND_FRAMELESS_ICALL_2:
1714+
case ZEND_FRAMELESS_ICALL_3: {
1715+
zval *args[3] = {NULL};
1716+
uint32_t num_args = opline->opcode - ZEND_FRAMELESS_ICALL_0;
1717+
zend_function **funcs;
1718+
switch (opline->opcode) {
1719+
case ZEND_FRAMELESS_ICALL_0:
1720+
funcs = zend_frameless_function_0_functions;
1721+
break;
1722+
case ZEND_FRAMELESS_ICALL_1:
1723+
args[0] = get_op1_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1724+
funcs = zend_frameless_function_1_functions;
1725+
break;
1726+
case ZEND_FRAMELESS_ICALL_2:
1727+
args[0] = get_op1_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1728+
args[1] = get_op2_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1729+
funcs = zend_frameless_function_2_functions;
1730+
break;
1731+
case ZEND_FRAMELESS_ICALL_3: {
1732+
zend_op *op_data = opline + 1;
1733+
args[0] = get_op1_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1734+
args[1] = get_op2_value(ctx, opline, &ctx->scdf.ssa->ops[opline - ctx->scdf.op_array->opcodes]);
1735+
args[2] = get_op2_value(ctx, op_data, &ctx->scdf.ssa->ops[op_data - ctx->scdf.op_array->opcodes]);
1736+
funcs = zend_frameless_function_3_functions;
1737+
break;
1738+
}
1739+
}
1740+
zend_function *func = funcs[opline->extended_value];
1741+
if (ct_eval_func_call(scdf->op_array, &zv, func->common.function_name, num_args, args) == SUCCESS) {
1742+
SET_RESULT(result, &zv);
1743+
zval_ptr_dtor_nogc(&zv);
1744+
break;
1745+
}
1746+
SET_RESULT_BOT(result);
1747+
break;
1748+
}
17111749
default:
17121750
{
17131751
/* If we have no explicit implementation return BOT */

Zend/zend_API.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ typedef struct _zend_fcall_info_cache {
9393
#define ZEND_ABSTRACT_ME_WITH_FLAGS(classname, name, arg_info, flags) ZEND_RAW_FENTRY(#name, NULL, arg_info, flags, NULL)
9494
#define ZEND_MALIAS(classname, name, alias, arg_info, flags) ZEND_RAW_FENTRY(#name, zim_##classname##_##alias, arg_info, flags, NULL)
9595
#define ZEND_ME_MAPPING(name, func_name, arg_info, flags) ZEND_RAW_FENTRY(#name, zif_##func_name, arg_info, flags, NULL)
96-
#define ZEND_DIRECT_FE(name, arg_info, frameless_function_infos) { #name, zif_##name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), 0, frameless_function_infos },
96+
#define ZEND_FRAMELESS_FE(name, arg_info, flags, frameless_function_infos) \
97+
{ #name, zif_##name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags, frameless_function_infos },
9798

9899
#define ZEND_NS_FENTRY(ns, zend_name, name, arg_info, flags) ZEND_RAW_FENTRY(ZEND_NS_NAME(ns, #zend_name), name, arg_info, flags, NULL)
99100

Zend/zend_builtin_functions_arginfo.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/gen_stub.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,10 +1402,10 @@ public function getFunctionEntry(): string {
14021402
if ($this->alias) {
14031403
die('Aliased direct calls are not supported yet');
14041404
}
1405-
// FIXME: Missing options for CTE
1405+
$flags = $this->supportsCompileTimeEval ? 'ZEND_ACC_COMPILE_TIME_EVAL' : '0';
14061406
return sprintf(
1407-
"\tZEND_DIRECT_FE(%s, %s, %s)\n",
1408-
$functionName, $this->getArgInfoName(), $this->getFramelessFunctionInfosName()
1407+
"\tZEND_FRAMELESS_FE(%s, %s, %s, %s)\n",
1408+
$functionName, $this->getArgInfoName(), $flags, $this->getFramelessFunctionInfosName()
14091409
);
14101410
}
14111411

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Test ct eval of frameless function
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
opcache.opt_debug_level=0x20000
8+
--EXTENSIONS--
9+
opcache
10+
--FILE--
11+
<?php
12+
echo dirname(__DIR__);
13+
?>
14+
--EXPECTF--
15+
$_main:
16+
; (lines=2, args=0, vars=0, tmps=0)
17+
; (after optimizer)
18+
; %sct_eval_frameless.php:1-4
19+
0000 ECHO string("%sopcache")
20+
0001 RETURN int(1)
21+
%sopcache

ext/standard/basic_functions_arginfo.h

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)