mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Evaluate arguments of new for classes without ctor
ML: http://markmail.org/message/4b3mk7jid64zvz34
This commit is contained in:
parent
24551ed6c8
commit
8e5b139732
@ -8,7 +8,7 @@ class MyClass {
|
||||
$this->myRef = $value;
|
||||
}
|
||||
}
|
||||
$myGlobal=new MyClass($myGlobal);
|
||||
$myGlobal=new MyClass();
|
||||
$myGlobal->myRef=&$myGlobal;
|
||||
$myGlobal->myNonExistentProperty="ok\n";
|
||||
echo $myGlobal;
|
||||
|
10
Zend/tests/new_args_without_ctor.phpt
Normal file
10
Zend/tests/new_args_without_ctor.phpt
Normal file
@ -0,0 +1,10 @@
|
||||
--TEST--
|
||||
Argument of new on class without constructor are evaluated
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
new stdClass(print 'a', print 'b');
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
ab
|
@ -3792,7 +3792,8 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */
|
||||
zend_compile_call_common(&ctor_result, args_ast, NULL);
|
||||
zend_do_free(&ctor_result);
|
||||
|
||||
/* New jumps over ctor call if ctor does not exist */
|
||||
/* We save the position of DO_FCALL for convenience in find_live_range().
|
||||
* This info is not preserved for runtime. */
|
||||
opline = &CG(active_op_array)->opcodes[opnum];
|
||||
opline->op2.opline_num = get_next_op_number(CG(active_op_array));
|
||||
}
|
||||
|
@ -673,7 +673,6 @@ ZEND_API int pass_two(zend_op_array *op_array)
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_NEW:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
|
||||
|
@ -5073,12 +5073,13 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, JMP_ADDR, NUM)
|
||||
ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, ANY, NUM)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *result;
|
||||
zend_function *constructor;
|
||||
zend_class_entry *ce;
|
||||
zend_execute_data *call;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (OP1_TYPE == IS_CONST) {
|
||||
@ -5107,21 +5108,30 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, JMP_ADDR, NUM)
|
||||
|
||||
constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
|
||||
if (constructor == NULL) {
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
/* If there are no arguments, skip over the DO_FCALL opcode. We check if the next
|
||||
* opcode is DO_FCALL in case EXT instructions are used. */
|
||||
if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) {
|
||||
ZEND_VM_NEXT_OPCODE_EX(1, 2);
|
||||
}
|
||||
|
||||
/* Perform a dummy function call */
|
||||
call = zend_vm_stack_push_call_frame(
|
||||
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
|
||||
opline->extended_value, NULL, NULL);
|
||||
} else {
|
||||
/* We are not handling overloaded classes right now */
|
||||
zend_execute_data *call = zend_vm_stack_push_call_frame(
|
||||
call = zend_vm_stack_push_call_frame(
|
||||
ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR,
|
||||
constructor,
|
||||
opline->extended_value,
|
||||
ce,
|
||||
Z_OBJ_P(result));
|
||||
call->prev_execute_data = EX(call);
|
||||
EX(call) = call;
|
||||
Z_ADDREF_P(result);
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
call->prev_execute_data = EX(call);
|
||||
EX(call) = call;
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
|
||||
|
@ -3756,6 +3756,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OP
|
||||
zval *result;
|
||||
zend_function *constructor;
|
||||
zend_class_entry *ce;
|
||||
zend_execute_data *call;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (IS_CONST == IS_CONST) {
|
||||
@ -3784,21 +3785,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OP
|
||||
|
||||
constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
|
||||
if (constructor == NULL) {
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
/* If there are no arguments, skip over the DO_FCALL opcode. We check if the next
|
||||
* opcode is DO_FCALL in case EXT instructions are used. */
|
||||
if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) {
|
||||
ZEND_VM_NEXT_OPCODE_EX(1, 2);
|
||||
}
|
||||
|
||||
/* Perform a dummy function call */
|
||||
call = zend_vm_stack_push_call_frame(
|
||||
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
|
||||
opline->extended_value, NULL, NULL);
|
||||
} else {
|
||||
/* We are not handling overloaded classes right now */
|
||||
zend_execute_data *call = zend_vm_stack_push_call_frame(
|
||||
call = zend_vm_stack_push_call_frame(
|
||||
ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR,
|
||||
constructor,
|
||||
opline->extended_value,
|
||||
ce,
|
||||
Z_OBJ_P(result));
|
||||
call->prev_execute_data = EX(call);
|
||||
EX(call) = call;
|
||||
Z_ADDREF_P(result);
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
call->prev_execute_data = EX(call);
|
||||
EX(call) = call;
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -16484,6 +16494,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCO
|
||||
zval *result;
|
||||
zend_function *constructor;
|
||||
zend_class_entry *ce;
|
||||
zend_execute_data *call;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (IS_VAR == IS_CONST) {
|
||||
@ -16512,21 +16523,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCO
|
||||
|
||||
constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
|
||||
if (constructor == NULL) {
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
/* If there are no arguments, skip over the DO_FCALL opcode. We check if the next
|
||||
* opcode is DO_FCALL in case EXT instructions are used. */
|
||||
if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) {
|
||||
ZEND_VM_NEXT_OPCODE_EX(1, 2);
|
||||
}
|
||||
|
||||
/* Perform a dummy function call */
|
||||
call = zend_vm_stack_push_call_frame(
|
||||
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
|
||||
opline->extended_value, NULL, NULL);
|
||||
} else {
|
||||
/* We are not handling overloaded classes right now */
|
||||
zend_execute_data *call = zend_vm_stack_push_call_frame(
|
||||
call = zend_vm_stack_push_call_frame(
|
||||
ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR,
|
||||
constructor,
|
||||
opline->extended_value,
|
||||
ce,
|
||||
Z_OBJ_P(result));
|
||||
call->prev_execute_data = EX(call);
|
||||
EX(call) = call;
|
||||
Z_ADDREF_P(result);
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
call->prev_execute_data = EX(call);
|
||||
EX(call) = call;
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
@ -26780,6 +26800,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_O
|
||||
zval *result;
|
||||
zend_function *constructor;
|
||||
zend_class_entry *ce;
|
||||
zend_execute_data *call;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (IS_UNUSED == IS_CONST) {
|
||||
@ -26808,21 +26829,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_HANDLER(ZEND_O
|
||||
|
||||
constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
|
||||
if (constructor == NULL) {
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
/* If there are no arguments, skip over the DO_FCALL opcode. We check if the next
|
||||
* opcode is DO_FCALL in case EXT instructions are used. */
|
||||
if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) {
|
||||
ZEND_VM_NEXT_OPCODE_EX(1, 2);
|
||||
}
|
||||
|
||||
/* Perform a dummy function call */
|
||||
call = zend_vm_stack_push_call_frame(
|
||||
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
|
||||
opline->extended_value, NULL, NULL);
|
||||
} else {
|
||||
/* We are not handling overloaded classes right now */
|
||||
zend_execute_data *call = zend_vm_stack_push_call_frame(
|
||||
call = zend_vm_stack_push_call_frame(
|
||||
ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR,
|
||||
constructor,
|
||||
opline->extended_value,
|
||||
ce,
|
||||
Z_OBJ_P(result));
|
||||
call->prev_execute_data = EX(call);
|
||||
EX(call) = call;
|
||||
Z_ADDREF_P(result);
|
||||
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
call->prev_execute_data = EX(call);
|
||||
EX(call) = call;
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
|
@ -277,7 +277,7 @@ static uint32_t zend_vm_opcodes_flags[184] = {
|
||||
0x00001003,
|
||||
0x00001001,
|
||||
0x00001001,
|
||||
0x01002073,
|
||||
0x01000073,
|
||||
0x01000300,
|
||||
0x00004005,
|
||||
0x00186703,
|
||||
|
@ -846,7 +846,6 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_NEW:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_ASSERT_CHECK:
|
||||
|
@ -182,7 +182,6 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_NEW:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_ASSERT_CHECK:
|
||||
@ -250,7 +249,6 @@ static void zend_ssa_remove_nops(zend_op_array *op_array, zend_ssa *ssa)
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_NEW:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_ASSERT_CHECK:
|
||||
|
@ -80,7 +80,6 @@ void zend_optimizer_nop_removal(zend_op_array *op_array)
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_NEW:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_ASSERT_CHECK:
|
||||
@ -123,7 +122,6 @@ void zend_optimizer_nop_removal(zend_op_array *op_array)
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_NEW:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_ASSERT_CHECK:
|
||||
|
@ -643,7 +643,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_FE_FETCH_R:
|
||||
case ZEND_FE_FETCH_RW:
|
||||
case ZEND_NEW:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_ASSERT_CHECK:
|
||||
|
@ -363,7 +363,6 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
|
||||
break;
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_NEW:
|
||||
BB_START(OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes);
|
||||
BB_START(i + 1);
|
||||
break;
|
||||
@ -496,7 +495,6 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b
|
||||
break;
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_NEW:
|
||||
record_successor(blocks, j, 0, block_map[OP_JMP_ADDR(opline, opline->op2) - op_array->opcodes]);
|
||||
record_successor(blocks, j, 1, j + 1);
|
||||
break;
|
||||
|
@ -404,7 +404,6 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_NEW:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_ASSERT_CHECK:
|
||||
@ -982,7 +981,6 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_NEW:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_ASSERT_CHECK:
|
||||
|
@ -541,7 +541,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_JMP_SET:
|
||||
case ZEND_COALESCE:
|
||||
case ZEND_NEW:
|
||||
case ZEND_FE_RESET_R:
|
||||
case ZEND_FE_RESET_RW:
|
||||
case ZEND_ASSERT_CHECK:
|
||||
|
@ -34,7 +34,7 @@ prompt> [Context %s (11 ops)]
|
||||
L1-19 {main}() %s - %s + 11 ops
|
||||
L4 #0 NOP
|
||||
L14 #1 NOP
|
||||
L18 #2 NEW "Foo\\Bar" J4 @1
|
||||
L18 #2 NEW "Foo\\Bar" @1
|
||||
L18 #3 DO_FCALL
|
||||
L18 #4 INIT_METHOD_CALL @1 "Foo"
|
||||
L18 #5 SEND_VAL_EX "test" 1
|
||||
|
Loading…
Reference in New Issue
Block a user