mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
- MFH Improved version of ternary shortcut (Marcus)
This commit is contained in:
parent
f83871a71d
commit
45f6b4ce2f
@ -16,6 +16,12 @@ var_dump($a ?: $b);
|
||||
var_dump($c ?: $d);
|
||||
|
||||
var_dump(1 ?: print(2));
|
||||
|
||||
$e = array();
|
||||
|
||||
$e['e'] = 'e';
|
||||
$e['e'] = $e['e'] ?: 'e';
|
||||
print_r($e);
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@ -25,3 +31,7 @@ string(3) "bar"
|
||||
int(23)
|
||||
float(23.5)
|
||||
int(1)
|
||||
Array
|
||||
(
|
||||
[e] => e
|
||||
)
|
||||
|
@ -4332,6 +4332,43 @@ void zend_do_end_silence(znode *strudel_token TSRMLS_DC)
|
||||
}
|
||||
|
||||
|
||||
void zend_do_jmp_set(znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC)
|
||||
{
|
||||
int op_number = get_next_op_number(CG(active_op_array));
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
|
||||
opline->opcode = ZEND_JMP_SET;
|
||||
opline->result.op_type = IS_TMP_VAR;
|
||||
opline->result.u.var = get_temporary_variable(CG(active_op_array));
|
||||
opline->op1 = *value;
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
*colon_token = opline->result;
|
||||
|
||||
jmp_token->u.opline_num = op_number;
|
||||
|
||||
INC_BPC(CG(active_op_array));
|
||||
}
|
||||
|
||||
|
||||
void zend_do_jmp_set_else(znode *result, znode *false_value, znode *jmp_token, znode *colon_token TSRMLS_DC)
|
||||
{
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
|
||||
opline->opcode = ZEND_QM_ASSIGN;
|
||||
opline->extended_value = 0;
|
||||
opline->result = *colon_token;
|
||||
opline->op1 = *false_value;
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
*result = opline->result;
|
||||
|
||||
CG(active_op_array)->opcodes[jmp_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
|
||||
|
||||
DEC_BPC(CG(active_op_array));
|
||||
}
|
||||
|
||||
|
||||
void zend_do_begin_qm_op(znode *cond, znode *qm_token TSRMLS_DC)
|
||||
{
|
||||
int jmpz_op_number = get_next_op_number(CG(active_op_array));
|
||||
|
@ -491,6 +491,9 @@ void zend_do_exit(znode *result, znode *message TSRMLS_DC);
|
||||
void zend_do_begin_silence(znode *strudel_token TSRMLS_DC);
|
||||
void zend_do_end_silence(znode *strudel_token TSRMLS_DC);
|
||||
|
||||
void zend_do_jmp_set(znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC);
|
||||
void zend_do_jmp_set_else(znode *result, znode *false_value, znode *jmp_token, znode *colon_token TSRMLS_DC);
|
||||
|
||||
void zend_do_begin_qm_op(znode *cond, znode *qm_token TSRMLS_DC);
|
||||
void zend_do_qm_true(znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC);
|
||||
void zend_do_qm_false(znode *result, znode *false_value, znode *qm_token, znode *colon_token TSRMLS_DC);
|
||||
|
@ -1309,6 +1309,7 @@ void execute_new_code(TSRMLS_D) /* {{{ */
|
||||
case ZEND_JMPNZ:
|
||||
case ZEND_JMPZ_EX:
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_JMP_SET:
|
||||
opline->op2.u.jmp_addr = &CG(active_op_array)->opcodes[opline->op2.u.opline_num];
|
||||
break;
|
||||
}
|
||||
|
@ -611,9 +611,8 @@ expr_without_variable:
|
||||
| expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
|
||||
expr ':' { zend_do_qm_true(&$4, &$2, &$5 TSRMLS_CC); }
|
||||
expr { zend_do_qm_false(&$$, &$7, &$2, &$5 TSRMLS_CC); }
|
||||
| expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
|
||||
':' { zend_do_qm_true(&$1, &$2, &$4 TSRMLS_CC); }
|
||||
expr { zend_do_qm_false(&$$, &$6, &$2, &$4 TSRMLS_CC); }
|
||||
| expr '?' ':' { zend_do_jmp_set(&$1, &$2, &$3 TSRMLS_CC); }
|
||||
expr { zend_do_jmp_set_else(&$$, &$5, &$2, &$3 TSRMLS_CC); }
|
||||
| internal_functions_in_yacc { $$ = $1; }
|
||||
| T_INT_CAST expr { zend_do_cast(&$$, &$2, IS_LONG TSRMLS_CC); }
|
||||
| T_DOUBLE_CAST expr { zend_do_cast(&$$, &$2, IS_DOUBLE TSRMLS_CC); }
|
||||
|
@ -395,6 +395,7 @@ int pass_two(zend_op_array *op_array TSRMLS_DC)
|
||||
case ZEND_JMPNZ:
|
||||
case ZEND_JMPZ_EX:
|
||||
case ZEND_JMPNZ_EX:
|
||||
case ZEND_JMP_SET:
|
||||
opline->op2.u.jmp_addr = &op_array->opcodes[opline->op2.u.opline_num];
|
||||
break;
|
||||
}
|
||||
|
@ -3749,6 +3749,26 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (i_zend_is_true(value)) {
|
||||
EX_T(opline->result.u.var).tmp_var = *value;
|
||||
zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);
|
||||
FREE_OP1();
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
|
||||
#endif
|
||||
ZEND_VM_JMP(opline->op2.u.jmp_addr);
|
||||
}
|
||||
|
||||
FREE_OP1();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
|
@ -2101,6 +2101,25 @@ static int ZEND_EXIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
|
||||
zval *value = &opline->op1.u.constant;
|
||||
|
||||
if (i_zend_is_true(value)) {
|
||||
EX_T(opline->result.u.var).tmp_var = *value;
|
||||
zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);
|
||||
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
|
||||
#endif
|
||||
ZEND_VM_JMP(opline->op2.u.jmp_addr);
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@ -5198,6 +5217,26 @@ static int ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
zval *value = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
|
||||
|
||||
if (i_zend_is_true(value)) {
|
||||
EX_T(opline->result.u.var).tmp_var = *value;
|
||||
zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);
|
||||
zval_dtor(free_op1.var);
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
|
||||
#endif
|
||||
ZEND_VM_JMP(opline->op2.u.jmp_addr);
|
||||
}
|
||||
|
||||
zval_dtor(free_op1.var);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@ -8484,6 +8523,26 @@ static int ZEND_EXIT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
zend_free_op free_op1;
|
||||
zval *value = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
|
||||
|
||||
if (i_zend_is_true(value)) {
|
||||
EX_T(opline->result.u.var).tmp_var = *value;
|
||||
zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
|
||||
#endif
|
||||
ZEND_VM_JMP(opline->op2.u.jmp_addr);
|
||||
}
|
||||
|
||||
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@ -21264,6 +21323,25 @@ static int ZEND_EXIT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
|
||||
zval *value = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
|
||||
|
||||
if (i_zend_is_true(value)) {
|
||||
EX_T(opline->result.u.var).tmp_var = *value;
|
||||
zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var);
|
||||
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Conditional jmp to %d\n", opline->op2.u.opline_num);
|
||||
#endif
|
||||
ZEND_VM_JMP(opline->op2.u.jmp_addr);
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static int ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op *opline = EX(opline);
|
||||
@ -31709,6 +31787,56 @@ void zend_init_opcodes_handlers(void)
|
||||
ZEND_USER_OPCODE_SPEC_HANDLER,
|
||||
ZEND_USER_OPCODE_SPEC_HANDLER,
|
||||
ZEND_USER_OPCODE_SPEC_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CONST_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CONST_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CONST_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CONST_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CONST_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_TMP_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_TMP_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_TMP_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_TMP_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_TMP_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_VAR_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_VAR_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_VAR_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_VAR_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_VAR_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_NULL_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CV_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CV_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CV_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CV_HANDLER,
|
||||
ZEND_JMP_SET_SPEC_CV_HANDLER,
|
||||
ZEND_NULL_HANDLER
|
||||
};
|
||||
zend_opcode_handlers = (opcode_handler_t*)labels;
|
||||
|
@ -148,3 +148,4 @@
|
||||
#define ZEND_ISSET_ISEMPTY_PROP_OBJ 148
|
||||
#define ZEND_HANDLE_EXCEPTION 149
|
||||
#define ZEND_USER_OPCODE 150
|
||||
#define ZEND_JMP_SET 152
|
||||
|
Loading…
Reference in New Issue
Block a user