Skip to content

Commit dbace93

Browse files
committed
Dummy
1 parent 45d1acf commit dbace93

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
@@ -4954,6 +4954,79 @@ static zend_result zend_compile_func_sprintf(znode *result, zend_ast_list *args)
49544954
return SUCCESS;
49554955
}
49564956

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

0 commit comments

Comments
 (0)