}
+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));
| 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); }
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);
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);
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);
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);
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;