@@ -1081,10 +1081,10 @@ static void* dasm_labels[zend_lb_MAX];
10811081|| }
10821082|.endmacro
10831083
1084- |.macro FREE_OP, op_type, op, op_info, cold, opline
1084+ |.macro FREE_OP, op_type, op, op_info, cold, opline, tmp_reg1, tmp_reg2
10851085|| if (op_type & (IS_VAR|IS_TMP_VAR)) {
1086- | brk #0 // TODO: test
1087- | // ZVAL_PTR_DTOR ZEND_ADDR_MEM_ZVAL(ZREG_FP, op.var), op_info, 0, cold, opline
1086+ || zend_jit_addr addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, op.var);
1087+ | ZVAL_PTR_DTOR addr, op_info, 0, cold, opline, tmp_reg1, tmp_reg2
10881088|| }
10891089|.endmacro
10901090
@@ -1137,7 +1137,32 @@ static void* dasm_labels[zend_lb_MAX];
11371137|.endmacro
11381138
11391139|.macro EMALLOC, size, op_array, opline
1140- | brk #0 // TODO
1140+ ||#if ZEND_DEBUG
1141+ || const char *filename = op_array->filename ? op_array->filename->val : NULL;
1142+ | mov FCARG1x, #size
1143+ | LOAD_ADDR FCARG2x, filename
1144+ | LOAD_32BIT_VAL CARG3w, opline->lineno
1145+ | mov CARG4, xzr
1146+ | mov CARG5, xzr
1147+ | EXT_CALL _emalloc, REG0
1148+ | mov REG0, RETVALx
1149+ ||#else
1150+ ||#ifdef HAVE_BUILTIN_CONSTANT_P
1151+ || if (size > 24 && size <= 32) {
1152+ | EXT_CALL _emalloc_32, REG0
1153+ | mov REG0, RETVALx
1154+ || } else {
1155+ | mov FCARG1x, #size
1156+ | EXT_CALL _emalloc, REG0
1157+ | mov REG0, RETVALx
1158+ || }
1159+ ||#else
1160+ | brk #0 // TODO
1161+ | mov FCARG1x, #size
1162+ | EXT_CALL _emalloc, REG0
1163+ | mov REG0, RETVALx
1164+ ||#endif
1165+ ||#endif
11411166|.endmacro
11421167
11431168|.macro OBJ_RELEASE, reg, exit_label, tmp_reg1, tmp_reg2
@@ -3115,8 +3140,8 @@ static int zend_jit_math_helper(dasm_State **Dst,
31153140 } else {
31163141 ZEND_UNREACHABLE();
31173142 }
3118- | FREE_OP op1_type, op1, op1_info, 0, opline
3119- | FREE_OP op2_type, op2, op2_info, 0, opline
3143+ | FREE_OP op1_type, op1, op1_info, 0, opline, ZREG_TMP1, ZREG_TMP2
3144+ | FREE_OP op2_type, op2, op2_info, 0, opline, ZREG_TMP1, ZREG_TMP2
31203145 if (may_throw) {
31213146 zend_jit_check_exception(Dst);
31223147 }
@@ -3804,7 +3829,36 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
38043829 if (Z_REG(var_use_addr) == ZREG_FCARG1x || Z_REG(var_use_addr) == ZREG_REG0) {
38053830 bool keep_gc = 0;
38063831
3807- | brk #0 // TODO
3832+ | GET_ZVAL_PTR Rx(tmp_reg), var_use_addr, TMP1
3833+ if (tmp_reg == ZREG_FCARG1x) {
3834+ if (Z_MODE(val_addr) == IS_REG) {
3835+ keep_gc = 1;
3836+ } else if ((val_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_GUARD)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE))) == 0) {
3837+ keep_gc = 1;
3838+ } else if (Z_MODE(val_addr) == IS_CONST_ZVAL) {
3839+ zval *zv = Z_ZV(val_addr);
3840+ if (Z_TYPE_P(zv) == IS_DOUBLE) {
3841+ if (Z_DVAL_P(zv) == 0) {
3842+ keep_gc = 1;
3843+ }
3844+ } else if (IS_SIGNED_32BIT(Z_LVAL_P(zv))) {
3845+ keep_gc = 1;
3846+ }
3847+ } else if (Z_MODE(val_addr) == IS_MEM_ZVAL) {
3848+ if ((val_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_GUARD)) == MAY_BE_DOUBLE) {
3849+ keep_gc = 1;
3850+ }
3851+ }
3852+ }
3853+ if (!keep_gc) {
3854+ | str Rx(tmp_reg), T1 // save
3855+ }
3856+ if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 0)) {
3857+ return 0;
3858+ }
3859+ if (!keep_gc) {
3860+ | ldr FCARG1x, T1 // restore
3861+ }
38083862 } else {
38093863 | GET_ZVAL_PTR FCARG1x, var_use_addr, TMP1
38103864 if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 1)) {
@@ -3969,7 +4023,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
39694023#endif
39704024
39714025 |9:
3972- | FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
4026+ | FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline, ZREG_TMP1, ZREG_TMP2
39734027
39744028 if (may_throw) {
39754029 zend_jit_check_exception(Dst);
@@ -5792,7 +5846,75 @@ static int zend_jit_send_ref(dasm_State **Dst, const zend_op *opline, const zend
57925846 op1_addr = OP1_ADDR();
57935847 arg_addr = ZEND_ADDR_MEM_ZVAL(ZREG_RX, opline->result.var);
57945848
5795- | brk #0 // TODO
5849+ if (!zend_jit_reuse_ip(Dst)) {
5850+ return 0;
5851+ }
5852+
5853+ if (opline->op1_type == IS_VAR) {
5854+ if (op1_info & MAY_BE_INDIRECT) {
5855+ | LOAD_ZVAL_ADDR REG0, op1_addr
5856+ | // if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
5857+ | IF_NOT_Z_TYPE REG0, IS_INDIRECT, >1, TMP1w
5858+ | // ret = Z_INDIRECT_P(ret);
5859+ | GET_Z_PTR REG0, REG0
5860+ |1:
5861+ op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG0, 0);
5862+ }
5863+ } else if (opline->op1_type == IS_CV) {
5864+ if (op1_info & MAY_BE_UNDEF) {
5865+ if (op1_info & (MAY_BE_ANY|MAY_BE_REF)) {
5866+ | brk #0 // TODO
5867+ }
5868+ op1_info &= ~MAY_BE_UNDEF;
5869+ op1_info |= MAY_BE_NULL;
5870+ }
5871+ } else {
5872+ ZEND_UNREACHABLE();
5873+ }
5874+
5875+ if (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) {
5876+ if (op1_info & MAY_BE_REF) {
5877+ | IF_NOT_ZVAL_TYPE op1_addr, IS_REFERENCE, >2, TMP1w, TMP2
5878+ | GET_ZVAL_PTR REG1, op1_addr, TMP1
5879+ | GC_ADDREF REG1, TMP1w
5880+ | SET_ZVAL_PTR arg_addr, REG1, TMP1
5881+ | SET_ZVAL_TYPE_INFO arg_addr, IS_REFERENCE_EX, TMP1w, TMP2
5882+ | b >6
5883+ }
5884+ |2:
5885+ | // ZVAL_NEW_REF(arg, varptr);
5886+ if (opline->op1_type == IS_VAR) {
5887+ if (Z_REG(op1_addr) != ZREG_REG0 || Z_OFFSET(op1_addr) != 0) {
5888+ | brk #0 // TODO
5889+ | LOAD_ZVAL_ADDR REG0, op1_addr
5890+ }
5891+ | str REG0, T1 // save
5892+ }
5893+ | EMALLOC sizeof(zend_reference), op_array, opline // Allocate space in REG0
5894+ | mov TMP1w, #2
5895+ | str TMP1w, [REG0]
5896+ || ZEND_ASSERT(GC_REFERENCE <= MAX_IMM12);
5897+ | mov TMP1w, #GC_REFERENCE
5898+ | str TMP1w, [REG0, #offsetof(zend_reference, gc.u.type_info)]
5899+ | str xzr, [REG0, #offsetof(zend_reference, sources.ptr)]
5900+ ref_addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG0, offsetof(zend_reference, val));
5901+ if (opline->op1_type == IS_VAR) {
5902+ zend_jit_addr val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_REG1, 0);
5903+
5904+ | ldr REG1, T1 // restore
5905+ | ZVAL_COPY_VALUE ref_addr, MAY_BE_ANY, val_addr, op1_info, ZREG_REG2, ZREG_REG2, ZREG_TMP1, ZREG_TMP2, ZREG_FPR0
5906+ | SET_ZVAL_PTR val_addr, REG0, TMP1
5907+ | SET_ZVAL_TYPE_INFO val_addr, IS_REFERENCE_EX, TMP1w, TMP2
5908+ } else {
5909+ | brk #0 // TODO
5910+ }
5911+ | SET_ZVAL_PTR arg_addr, REG0, TMP1
5912+ | SET_ZVAL_TYPE_INFO arg_addr, IS_REFERENCE_EX, TMP1w, TMP2
5913+ }
5914+
5915+ |6:
5916+ | FREE_OP opline->op1_type, opline->op1, op1_info, !cold, opline, ZREG_TMP1, ZREG_TMP2
5917+ |7:
57965918
57975919 return 1;
57985920}
@@ -6543,9 +6665,9 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst,
65436665 }
65446666#endif
65456667
6546- | FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
6668+ | FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline, ZREG_TMP1, ZREG_TMP2
65476669 if (opline->opcode != ZEND_FETCH_LIST_R && !op1_avoid_refcounting) {
6548- | FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
6670+ | FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline, ZREG_TMP1, ZREG_TMP2
65496671 }
65506672
65516673 if (may_throw) {
@@ -6670,7 +6792,7 @@ static int zend_jit_fetch_dim(dasm_State **Dst,
66706792#endif
66716793
66726794 |8:
6673- | FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
6795+ | FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline, ZREG_TMP1, ZREG_TMP2
66746796
66756797 if (may_throw) {
66766798 if (!zend_jit_check_exception(Dst)) {
@@ -7127,7 +7249,6 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
71277249 |5:
71287250 | SET_EX_OPLINE opline, REG0
71297251 if (opline->opcode == ZEND_FETCH_OBJ_W) {
7130- | brk #0 // TODO
71317252 | EXT_CALL zend_jit_fetch_obj_w_slow, REG0
71327253 } else if (opline->opcode != ZEND_FETCH_OBJ_IS) {
71337254 | EXT_CALL zend_jit_fetch_obj_r_slow, REG0
@@ -7140,7 +7261,28 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
71407261
71417262 if ((op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)- MAY_BE_OBJECT)) && JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) {
71427263 |7:
7143- | brk #0 // TODO
7264+ if (opline->opcode != ZEND_FETCH_OBJ_IS) {
7265+ | SET_EX_OPLINE opline, REG0
7266+ if (opline->opcode != ZEND_FETCH_OBJ_W
7267+ && (op1_info & MAY_BE_UNDEF)) {
7268+ zend_jit_addr orig_op1_addr = OP1_ADDR();
7269+
7270+ | brk #0 // TODO
7271+ } else if (Z_REG(op1_addr) != ZREG_FCARG1x || Z_OFFSET(op1_addr) != 0) {
7272+ | brk #0 // TODO
7273+ | LOAD_ZVAL_ADDR FCARG1x, op1_addr
7274+ }
7275+ | LOAD_ADDR FCARG2x, Z_STRVAL_P(member)
7276+ if (opline->opcode == ZEND_FETCH_OBJ_W) {
7277+ | EXT_CALL zend_jit_invalid_property_write, REG0
7278+ | SET_ZVAL_TYPE_INFO res_addr, _IS_ERROR, TMP1w, TMP2
7279+ } else {
7280+ | brk #0 // TODO
7281+ }
7282+ | b >9
7283+ } else {
7284+ | brk #0 // TODO
7285+ }
71447286 }
71457287
71467288 if (!prop_info
@@ -7160,7 +7302,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
71607302
71617303 | brk #0 // TODO
71627304 } else if (!op1_avoid_refcounting) {
7163- | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline
7305+ | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline, ZREG_TMP1, ZREG_TMP2
71647306 }
71657307 }
71667308
@@ -7352,14 +7494,14 @@ static int zend_jit_assign_obj_op(dasm_State **Dst,
73527494
73537495 |8:
73547496 | // FREE_OP_DATA();
7355- | FREE_OP (opline+1)->op1_type, (opline+1)->op1, val_info, 0, opline
7497+ | FREE_OP (opline+1)->op1_type, (opline+1)->op1, val_info, 0, opline, ZREG_TMP1, ZREG_TMP2
73567498 | b >9
73577499 |.code
73587500 }
73597501
73607502 |9:
73617503 if (opline->op1_type != IS_UNUSED && !use_this && !op1_indirect) {
7362- | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline
7504+ | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline, ZREG_TMP1, ZREG_TMP2
73637505 }
73647506
73657507 if (may_throw) {
@@ -7550,14 +7692,14 @@ static int zend_jit_assign_obj(dasm_State **Dst,
75507692
75517693 |8:
75527694 | // FREE_OP_DATA();
7553- | FREE_OP (opline+1)->op1_type, (opline+1)->op1, val_info, 0, opline
7695+ | FREE_OP (opline+1)->op1_type, (opline+1)->op1, val_info, 0, opline, ZREG_TMP1, ZREG_TMP2
75547696 | b >9
75557697 |.code
75567698 }
75577699
75587700 |9:
75597701 if (opline->op1_type != IS_UNUSED && !use_this && !op1_indirect) {
7560- | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline
7702+ | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline, ZREG_TMP1, ZREG_TMP2
75617703 }
75627704
75637705 if (may_throw) {
0 commit comments