Skip to content

Commit 642f965

Browse files
committed
Dummy
1 parent 51bdab2 commit 642f965

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

Zend/zend_compile.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4956,6 +4956,79 @@ static zend_result zend_compile_func_sprintf(znode *result, zend_ast_list *args)
49564956
return SUCCESS;
49574957
}
49584958

4959+
static zend_op_array *zend_compile_func_decl(znode *result, zend_ast *ast, bool toplevel);
4960+
4961+
static zend_result zend_compile_func_array_map(znode *result, zend_ast_list *args) /* {{{ */
4962+
{
4963+
/* Bail out if we do not have exactly two parameters. */
4964+
if (args->children != 2) {
4965+
return FAILURE;
4966+
}
4967+
4968+
zend_eval_const_expr(&args->child[0]);
4969+
/* Bail out if the first parameter is not a Closure. */
4970+
if (args->child[0]->kind != ZEND_AST_CLOSURE) {
4971+
printf("!closure\n");
4972+
return FAILURE;
4973+
}
4974+
zend_ast_decl *closure_ast = (zend_ast_decl *) args->child[0];
4975+
zend_ast *uses_ast = closure_ast->child[1];
4976+
/* Bail out if the Closure is not static. */
4977+
if (!(closure_ast->flags & ZEND_ACC_STATIC)) {
4978+
printf("!static\n");
4979+
return FAILURE;
4980+
}
4981+
/* Bail out if the Closure imports stuff from the outer scope. */
4982+
if (uses_ast) {
4983+
printf("uses\n");
4984+
return FAILURE;
4985+
}
4986+
4987+
znode closure;
4988+
zend_compile_func_decl(&closure, args->child[0], 0);
4989+
4990+
znode expr_node, reset_node, value_node, key_node;
4991+
zend_op *opline;
4992+
uint32_t opnum_reset, opnum_fetch;
4993+
zend_compile_expr(&expr_node, args->child[1]);
4994+
4995+
opnum_reset = get_next_op_number();
4996+
opline = zend_emit_op(&reset_node, ZEND_FE_RESET_R, &expr_node, NULL);
4997+
4998+
zend_begin_loop(ZEND_FE_FREE, &reset_node, 0);
4999+
5000+
opnum_fetch = get_next_op_number();
5001+
opline = zend_emit_op(NULL, ZEND_FE_FETCH_R, &reset_node, NULL);
5002+
5003+
opline->op2_type = IS_VAR;
5004+
opline->op2.var = get_temporary_variable();
5005+
GET_NODE(&value_node, opline->op2);
5006+
zend_emit_op(NULL, ZEND_INIT_DYNAMIC_CALL, NULL, &closure);
5007+
uint32_t opnum_init = get_next_op_number() - 1;
5008+
opline = &CG(active_op_array)->opcodes[opnum_init];
5009+
opline->extended_value = 1;
5010+
opline = zend_emit_op(NULL, ZEND_SEND_VAR, &value_node, NULL);
5011+
opline->op2.opline_num = 1;
5012+
zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
5013+
5014+
zend_emit_jump(opnum_fetch);
5015+
5016+
opline = &CG(active_op_array)->opcodes[opnum_reset];
5017+
opline->op2.opline_num = get_next_op_number();
5018+
5019+
opline = &CG(active_op_array)->opcodes[opnum_fetch];
5020+
opline->extended_value = get_next_op_number();
5021+
5022+
zend_end_loop(opnum_fetch, &reset_node);
5023+
5024+
opline = zend_emit_op(NULL, ZEND_FE_FREE, &reset_node, NULL);
5025+
5026+
result->op_type = IS_CONST;
5027+
ZVAL_LONG(&result->u.constant, 1);
5028+
5029+
return SUCCESS;
5030+
}
5031+
49595032
static zend_result zend_try_compile_special_func_ex(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc, uint32_t type) /* {{{ */
49605033
{
49615034
if (zend_string_equals_literal(lcname, "strlen")) {
@@ -5024,6 +5097,8 @@ static zend_result zend_try_compile_special_func_ex(znode *result, zend_string *
50245097
return zend_compile_func_array_key_exists(result, args);
50255098
} else if (zend_string_equals_literal(lcname, "sprintf")) {
50265099
return zend_compile_func_sprintf(result, args);
5100+
} else if (zend_string_equals_literal(lcname, "array_map")) {
5101+
return zend_compile_func_array_map(result, args);
50275102
} else {
50285103
return FAILURE;
50295104
}

0 commit comments

Comments
 (0)