@@ -1023,6 +1023,23 @@ static void* dasm_labels[zend_lb_MAX];
1023
1023
1024
1024
/* the same as above, but "src" may overlap with "tmp_reg1" */
1025
1025
|.macro ZVAL_COPY_VALUE, dst_addr, dst_info, src_addr, src_info, tmp_reg1, tmp_reg2
1026
+ | ZVAL_COPY_VALUE_V dst_addr, dst_info, src_addr, src_info, tmp_reg1, tmp_reg2
1027
+ || if ((src_info & (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)) &&
1028
+ || !(src_info & MAY_BE_GUARD) &&
1029
+ || has_concrete_type(src_info & MAY_BE_ANY)) {
1030
+ || if (Z_MODE(dst_addr) == IS_MEM_ZVAL) {
1031
+ || if ((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) != (src_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD))) {
1032
+ || zend_uchar type = concrete_type(src_info);
1033
+ | SET_ZVAL_TYPE_INFO dst_addr, type
1034
+ || }
1035
+ || }
1036
+ || } else {
1037
+ | GET_ZVAL_TYPE_INFO Rd(tmp_reg1), src_addr
1038
+ | SET_ZVAL_TYPE_INFO dst_addr, Rd(tmp_reg1)
1039
+ || }
1040
+ |.endmacro
1041
+
1042
+ |.macro ZVAL_COPY_VALUE_V, dst_addr, dst_info, src_addr, src_info, tmp_reg1, tmp_reg2
1026
1043
|| if (src_info & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE))) {
1027
1044
|| if ((src_info & (MAY_BE_ANY|MAY_BE_GUARD)) == MAY_BE_LONG) {
1028
1045
|| if (Z_MODE(src_addr) == IS_REG) {
@@ -1066,19 +1083,6 @@ static void* dasm_labels[zend_lb_MAX];
1066
1083
| .endif
1067
1084
|| }
1068
1085
|| }
1069
- || if ((src_info & (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)) &&
1070
- || !(src_info & MAY_BE_GUARD) &&
1071
- || has_concrete_type(src_info & MAY_BE_ANY)) {
1072
- || if (Z_MODE(dst_addr) == IS_MEM_ZVAL) {
1073
- || if ((dst_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) != (src_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD))) {
1074
- || zend_uchar type = concrete_type(src_info);
1075
- | SET_ZVAL_TYPE_INFO dst_addr, type
1076
- || }
1077
- || }
1078
- || } else {
1079
- | GET_ZVAL_TYPE_INFO Rd(tmp_reg1), src_addr
1080
- | SET_ZVAL_TYPE_INFO dst_addr, Rd(tmp_reg1)
1081
- || }
1082
1086
|.endmacro
1083
1087
1084
1088
|.macro ZVAL_COPY_VALUE_2, dst_addr, dst_info, res_addr, src_addr, src_info, tmp_reg1, tmp_reg2
@@ -11235,8 +11239,61 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
11235
11239
| SET_ZVAL_PTR res_addr, FCARG1a
11236
11240
| SET_ZVAL_TYPE_INFO res_addr, IS_INDIRECT
11237
11241
} else {
11238
- if (!zend_jit_zval_copy_deref(Dst, res_addr, prop_addr, ZREG_R2)) {
11239
- return 0;
11242
+ uint32_t res_info = RES_INFO();
11243
+
11244
+ if ((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info) {
11245
+ uint32_t flags = 0;
11246
+ uint32_t old_info;
11247
+ zend_jit_trace_stack *stack = JIT_G(current_frame)->stack;
11248
+ int32_t exit_point;
11249
+ const void *exit_addr;
11250
+ zend_uchar type;
11251
+ zend_jit_addr val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
11252
+
11253
+ if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && !use_this) {
11254
+ flags = ZEND_JIT_EXIT_FREE_OP1;
11255
+ }
11256
+
11257
+ | LOAD_ZVAL_ADDR r0, prop_addr
11258
+
11259
+ old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var));
11260
+ SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_UNKNOWN);
11261
+ SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_ZVAL_COPY_R0);
11262
+ exit_point = zend_jit_trace_get_exit_point(opline, opline+1, NULL, flags);
11263
+ SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var), old_info);
11264
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
11265
+ if (!exit_addr) {
11266
+ return 0;
11267
+ }
11268
+
11269
+ res_info &= ~MAY_BE_GUARD;
11270
+ ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
11271
+ type = concrete_type(res_info);
11272
+
11273
+ | // ZVAL_DEREF()
11274
+ | IF_NOT_TYPE dl, IS_REFERENCE, >1
11275
+ | GET_Z_PTR r0, r0
11276
+ | add r0, offsetof(zend_reference, val)
11277
+ if (type < IS_STRING) {
11278
+ |1:
11279
+ | IF_NOT_ZVAL_TYPE val_addr, type, &exit_addr
11280
+ } else {
11281
+ | GET_ZVAL_TYPE_INFO edx, val_addr
11282
+ |1:
11283
+ | IF_NOT_TYPE dl, type, &exit_addr
11284
+ }
11285
+ | // ZVAL_COPY
11286
+ | ZVAL_COPY_VALUE_V res_addr, -1, val_addr, res_info, ZREG_R2, ZREG_R1
11287
+ if (type < IS_STRING) {
11288
+ | SET_ZVAL_TYPE_INFO res_addr, type
11289
+ } else {
11290
+ | SET_ZVAL_TYPE_INFO res_addr, edx
11291
+ | TRY_ADDREF res_info, dh, r1
11292
+ }
11293
+ } else {
11294
+ if (!zend_jit_zval_copy_deref(Dst, res_addr, prop_addr, ZREG_R2)) {
11295
+ return 0;
11296
+ }
11240
11297
}
11241
11298
}
11242
11299
0 commit comments