} zend_jit_trace_op;
#define IS_UNKNOWN 255 /* may be used for zend_jit_trace_rec.op?_type */
+#define IS_TRACE_PACKED (1<<4)
#define IS_TRACE_REFERENCE (1<<5)
#define IS_TRACE_INDIRECT (1<<6)
if (op1_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) {
op1_type = IS_UNKNOWN;
}
+ if (op1_type != IS_UNKNOWN) {
+ op1_type &= ~IS_TRACE_PACKED;
+ }
if (op2_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) {
op2_type = IS_UNKNOWN;
}
if (op1_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) {
op1_type = IS_UNKNOWN;
}
+ if (op1_type != IS_UNKNOWN) {
+ op1_type &= ~IS_TRACE_PACKED;
+ }
if (op2_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) {
op2_type = IS_UNKNOWN;
}
fprintf(stderr, " op1(%sobject of class %s)", ref,
ZSTR_VAL(p->ce->name));
} else {
- const char *type = (op1_type == 0) ? "undef" : zend_get_type_by_const(op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT));
- fprintf(stderr, " op1(%s%s)", ref, type);
+ const char *type = (op1_type == 0) ? "undef" : zend_get_type_by_const(op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED));
+ fprintf(stderr, " op1(%s%s%s)", ref, (op1_type & IS_TRACE_PACKED) ? "packed " : "", type);
}
}
if (op2_type != IS_UNKNOWN) {
op1_type = Z_TYPE_P(zv);
flags |= IS_TRACE_REFERENCE;
}
- op1_type |= flags;
if (Z_TYPE_P(zv) == IS_OBJECT) {
ce1 = Z_OBJCE_P(zv);
+ } else if (Z_TYPE_P(zv) == IS_ARRAY) {
+ if (HT_IS_PACKED(Z_ARRVAL_P(zv))) {
+ flags |= IS_TRACE_PACKED;
+ }
}
+ op1_type |= flags;
}
if (opline->op2_type & (IS_TMP_VAR|IS_VAR|IS_CV)
&& opline->opcode != ZEND_INSTANCEOF
op2_type = Z_TYPE_P(zv);
flags |= IS_TRACE_REFERENCE;
}
- op2_type |= flags;
if (Z_TYPE_P(zv) == IS_OBJECT) {
ce2 = Z_OBJCE_P(zv);
}
+ op2_type |= flags;
}
if (opline->opcode == ZEND_ASSIGN_DIM ||
opline->opcode == ZEND_ASSIGN_OBJ ||
var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, offsetof(zend_reference, val));
*var_addr_ptr = var_addr;
- var_type &= ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT);
+ if (var_type != IS_UNKNOWN) {
+ var_type &= ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED);
+ }
if (add_type_guard
&& var_type != IS_UNKNOWN
&& (var_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << var_type)) {
var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
*var_addr_ptr = var_addr;
- var_type &= ~IS_TRACE_INDIRECT;
+ if (var_type != IS_UNKNOWN) {
+ var_type &= ~(IS_TRACE_INDIRECT|IS_TRACE_PACKED);
+ }
if (!(var_type & IS_TRACE_REFERENCE)
&& var_type != IS_UNKNOWN
&& (var_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << var_type)) {
op2_info = OP2_INFO();
if (trace
&& trace->op1_type != IS_UNKNOWN
- && (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) == IS_ARRAY) {
+ && (trace->op1_type & ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED)) == IS_ARRAY) {
op1_info &= ~((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY);
}
return ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) &&