Skip to content

test ZEND_RECV_CE #124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Zend/Optimizer/compact_literals.c
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
Z_CACHE_SLOT_P(val) = op_array->cache_size;
op_array->cache_size += sizeof(zval);
}
} else if (opline->opcode != ZEND_RECV) {
} else if (opline->opcode != ZEND_RECV && opline->opcode != ZEND_RECV_CE) {
break;
}
opline++;
Expand Down
1 change: 1 addition & 0 deletions Zend/Optimizer/dce.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ static inline bool may_have_side_effects(
/* For now assume all calls have side effects */
return 1;
case ZEND_RECV:
case ZEND_RECV_CE:
case ZEND_RECV_INIT:
/* Even though RECV_INIT can be side-effect free, these cannot be simply dropped
* due to the prologue skipping code. */
Expand Down
4 changes: 3 additions & 1 deletion Zend/Optimizer/zend_cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
}
if ((cfg->flags & ZEND_CFG_RECV_ENTRY)) {
if (opcode == ZEND_RECV ||
opcode == ZEND_RECV_INIT) {
opcode == ZEND_RECV_INIT ||
opcode == ZEND_RECV_CE) {
succ->flags |= ZEND_BB_RECV_ENTRY;
}
}
Expand Down Expand Up @@ -292,6 +293,7 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
zend_op *opline = op_array->opcodes + i;
switch (opline->opcode) {
case ZEND_RECV:
case ZEND_RECV_CE:
case ZEND_RECV_INIT:
if (build_flags & ZEND_CFG_RECV_ENTRY) {
BB_START(i + 1);
Expand Down
3 changes: 2 additions & 1 deletion Zend/Optimizer/zend_dfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ static zend_always_inline void _zend_dfg_add_use_def_op(const zend_op_array *op_
}
if ((build_flags & ZEND_SSA_USE_CV_RESULTS)
&& opline->result_type == IS_CV
&& opline->opcode != ZEND_RECV) {
&& opline->opcode != ZEND_RECV
&& opline->opcode != ZEND_RECV_CE) {
var_num = EX_VAR_TO_NUM(opline->result.var);
if (!zend_bitset_in(def, var_num)) {
zend_bitset_incl(use, var_num);
Expand Down
2 changes: 2 additions & 0 deletions Zend/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -3300,6 +3300,7 @@ static zend_always_inline zend_result _zend_update_type_info(
UPDATE_SSA_TYPE(MAY_BE_STRING|MAY_BE_RC1|MAY_BE_RCN, ssa_op->result_def);
break;
case ZEND_RECV:
case ZEND_RECV_CE:
case ZEND_RECV_INIT:
case ZEND_RECV_VARIADIC:
{
Expand Down Expand Up @@ -4759,6 +4760,7 @@ static void zend_mark_cv_references(const zend_op_array *op_array, const zend_sc
if (ssa->ops[def].result_def == var) {
switch (opline->opcode) {
case ZEND_RECV:
case ZEND_RECV_CE:
case ZEND_RECV_INIT:
arg_info = &op_array->arg_info[opline->op1.num-1];
if (!ZEND_ARG_SEND_MODE(arg_info)) {
Expand Down
3 changes: 2 additions & 1 deletion Zend/Optimizer/zend_ssa.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,8 @@ static zend_always_inline int _zend_ssa_rename_op(const zend_op_array *op_array,
}
if ((build_flags & ZEND_SSA_USE_CV_RESULTS)
&& opline->result_type == IS_CV
&& opline->opcode != ZEND_RECV) {
&& opline->opcode != ZEND_RECV
&& opline->opcode != ZEND_RECV_CE) {
ssa_ops[k].result_use = var[EX_VAR_TO_NUM(opline->result.var)];
//USE_SSA_VAR(op_array->last_var + opline->result.var)
}
Expand Down
23 changes: 19 additions & 4 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -7747,13 +7747,28 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
zval_ptr_dtor(&default_node.u.constant);
}

opline = zend_emit_op(NULL, opcode, NULL, &default_node);
SET_NODE(opline->result, &var_node);
opline->op1.num = i + 1;

uint32_t arg_info_flags = _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic, /* is_tentative */ 0)
| (is_promoted ? _ZEND_IS_PROMOTED_BIT : 0);
ZEND_TYPE_FULL_MASK(arg_info->type) |= arg_info_flags;

if (opcode == ZEND_RECV
&& type_ast
&& ZEND_TYPE_IS_COMPLEX(arg_info->type)
&& !ZEND_TYPE_HAS_LIST(arg_info->type)
&& ZEND_TYPE_HAS_NAME(arg_info->type)
&& !ZEND_TYPE_HAS_LITERAL_NAME(arg_info->type) // TODO: necessary?
&& ZEND_TYPE_PURE_MASK(arg_info->type) == 0) {
znode ce_name;
ce_name.op_type = IS_CONST;
ZVAL_STR_COPY(&ce_name.u.constant, ZEND_TYPE_NAME(arg_info->type));
opcode = ZEND_RECV_CE;
opline = zend_emit_op(NULL, opcode, NULL, &ce_name);
} else {
opline = zend_emit_op(NULL, opcode, NULL, &default_node);
}
SET_NODE(opline->result, &var_node);
opline->op1.num = i + 1;

if (opcode == ZEND_RECV) {
opline->op2.num = type_ast ?
ZEND_TYPE_FULL_MASK(arg_info->type) : MAY_BE_ANY;
Expand Down
14 changes: 10 additions & 4 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -1099,10 +1099,9 @@ static zend_always_inline bool zend_value_instanceof_static(const zval *zv) {
return instanceof_function(Z_OBJCE_P(zv), called_scope);
}

static zend_always_inline zend_class_entry *zend_fetch_ce_from_type(
const zend_type *type)
static zend_always_inline zend_class_entry *zend_fetch_ce_from_type_name(
zend_string *name)
{
zend_string *name = ZEND_TYPE_NAME(*type);
zend_class_entry *ce;
if (ZSTR_HAS_CE_CACHE(name)) {
ce = ZSTR_GET_CE_CACHE(name);
Expand All @@ -1123,6 +1122,13 @@ static zend_always_inline zend_class_entry *zend_fetch_ce_from_type(
return ce;
}

static zend_always_inline zend_class_entry *zend_fetch_ce_from_type(
const zend_type *type)
{
zend_string *name = ZEND_TYPE_NAME(*type);
return zend_fetch_ce_from_type_name(name);
}

static bool zend_check_intersection_type_from_list(
const zend_type_list *intersection_type_list,
zend_class_entry *arg_ce)
Expand Down Expand Up @@ -5510,7 +5516,7 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal
ZVAL_COPY(arg, default_value);
}
} else {
ZEND_ASSERT(opline->opcode == ZEND_RECV);
ZEND_ASSERT(opline->opcode == ZEND_RECV);//TODO
zend_execute_data *old = start_fake_frame(call, opline);
zend_argument_error(zend_ce_argument_count_error, i + 1, "not passed");
end_fake_frame(call, old);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ static ZEND_COLD zend_string *zend_get_function_declaration(

++idx;
while (op < end) {
if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT)
if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT || op->opcode == ZEND_RECV_CE)
&& op->op1.num == (zend_ulong)idx)
{
precv = op;
Expand Down
22 changes: 22 additions & 0 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -5695,6 +5695,28 @@ ZEND_VM_HOT_HANDLER(63, ZEND_RECV, NUM, UNUSED)
ZEND_VM_NEXT_OPCODE();
}

ZEND_VM_HOT_HANDLER(210, ZEND_RECV_CE, NUM, CONST)
{
USE_OPLINE
uint32_t arg_num = opline->op1.num;
zend_string *ce_name = Z_STR_P(RT_CONSTANT(opline, opline->op2));
zval *param;
zend_class_entry *ce;

if (UNEXPECTED(arg_num > EX_NUM_ARGS())) {
ZEND_VM_DISPATCH_TO_HELPER(zend_missing_arg_helper);
}

param = EX_VAR(opline->result.var);
// fprintf(stderr,"ce_name=%s %x\n", ZSTR_VAL(ce_name), ZSTR_GET_CE_CACHE(ce_name));

if (EXPECTED(Z_TYPE_P(param) == IS_OBJECT && (ce = zend_fetch_ce_from_type_name(ce_name)) && instanceof_function(Z_OBJCE_P(param), ce))) {
ZEND_VM_NEXT_OPCODE();
} else {
ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper, op_1, param);
}
}

ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_RECV, op->op2.num == MAY_BE_ANY, ZEND_RECV_NOTYPE, NUM, NUM)
{
USE_OPLINE
Expand Down
Loading
Loading