#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
-# define VAR_NUM_EX(op) ((op ## _type & (IS_TMP_VAR|IS_VAR))?VAR_NUM((op).var):(op).var)
+# define VAR_NUM_EX(op) VAR_NUM((op).var)
# define VAR_SOURCE(op) Tsource[VAR_NUM(op.var)]
# define SET_VAR_SOURCE(opline) Tsource[VAR_NUM(opline->result.var)] = opline
/* we track data dependencies only insight a single basic block */
if (op_array->T) {
- Tsource = ecalloc(op_array->T, sizeof(zend_op *));
+ Tsource = ecalloc(op_array->last_var + op_array->T, sizeof(zend_op *));
}
opline = block->start_opline;
end = opline + block->len;
zend_op *target, *target_end;
char *same_t=NULL;
zend_code_block *target_block;
- int var_num = 0;
- if (op_array->T >= (zend_uint)op_array->last_var) {
- var_num = op_array->T;
- } else {
- var_num = op_array->last_var;
- }
+ int var_num = op_array->last_var + op_array->T;
+//??? if (op_array->T >= (zend_uint)op_array->last_var) {
+//??? var_num = op_array->T;
+//??? } else {
+//??? var_num = op_array->last_var;
+//??? }
+
if (var_num <= 0) {
return;
}
Z_TYPE(op_array->literals[i].constant) == Z_TYPE(op_array->literals[*pos].constant) &&
info[i].flags == info[*pos].flags) {
- if (info[i].flags & (LITERAL_EX_OBJ|LITERAL_EX_CLASS)) {
- efree(key);
- }
+ STR_RELEASE(key);
map[i] = *pos;
zval_dtor(&op_array->literals[i].constant);
n = LITERAL_NUM_RELATED(info[i].flags);
map[i] = j;
if (info[i].flags & LITERAL_MAY_MERGE) {
zend_hash_add_ptr(&hash, key, (void**)&j);
- if (info[i].flags & (LITERAL_EX_OBJ|LITERAL_EX_CLASS)) {
- STR_RELEASE(key);
- }
+ STR_RELEASE(key);
}
if (i != j) {
op_array->literals[j] = op_array->literals[i];
if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR)) {
start_of_T[VAR_NUM(ZEND_RESULT(opline).var) - offset] = opline;
}
+ /* special puprose variable to keep HashPointer on VM stack */
+ if (opline->opcode == ZEND_OP_DATA &&
+ (opline-1)->opcode == ZEND_FE_FETCH &&
+ opline->op1_type == IS_TMP_VAR) {
+ start_of_T[VAR_NUM(ZEND_OP1(opline).var) - offset] = opline;
+ if (sizeof(HashPointer) > sizeof(zval)) {
+ /* Make shure 1 zval is enough for HashPointer (2 must be enough) */
+ start_of_T[VAR_NUM(ZEND_OP1(opline).var) + 1 - offset] = opline;
+ }
+ }
#endif
opline--;
}
|| ((op_const_means_class[opline->opcode] & OP1_CONST_IS_CLASS) && ZEND_OP1_TYPE(opline) == IS_CONST)
#endif
) {
- currT = VAR_NUM(ZEND_OP1(opline).var) - offset;
- if (!valid_T[currT]) {
- GET_AVAILABLE_T();
- map_T[currT] = i;
- valid_T[currT] = 1;
+
+ /* special puprose variable to keep HashPointer on VM stack */
+ if (opline->opcode == ZEND_OP_DATA &&
+ (opline-1)->opcode == ZEND_FE_FETCH &&
+ opline->op1_type == IS_TMP_VAR) {
+ max++;
+ ZEND_OP1(opline).var = NUM_VAR(max + offset);
+ if (sizeof(HashPointer) > sizeof(zval)) {
+ /* Make shure 1 zval is enough for HashPointer (2 must be enough) */
+ max++;
+ }
+ } else {
+ currT = VAR_NUM(ZEND_OP1(opline).var) - offset;
+ if (!valid_T[currT]) {
+ GET_AVAILABLE_T();
+ map_T[currT] = i;
+ valid_T[currT] = 1;
+ }
+ ZEND_OP1(opline).var = NUM_VAR(map_T[currT] + offset);
}
- ZEND_OP1(opline).var = NUM_VAR(map_T[currT] + offset);
}
/* Skip OP_DATA */
#endif
collect_constants = 0;
break;
-
#if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
case ZEND_FETCH_R:
case ZEND_FETCH_W:
}
break;
#endif
-
}
opline++;
i++;
(op_array->vars[i]->h == hash_value &&
op_array->vars[i]->len == name->len &&
memcmp(op_array->vars[i], name->val, name->len) == 0)) {
- return i;
+ return (int)EX_VAR_NUM_2(NULL, i);
}
i++;
}
op_array->last_var++;
op_array->vars = erealloc(op_array->vars, op_array->last_var * sizeof(zend_string*));
op_array->vars[i] = STR_DUP(name, 0);
- return i;
+
+ /* all IS_TMP_VAR and IS_VAR variable numbers have to be adjusted */
+ {
+ zend_op *opline = op_array->opcodes;
+ zend_op *end = opline + op_array->last;
+ while (opline < end) {
+ if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
+ opline->op1.var += sizeof(zval);
+ }
+ if (opline->op2_type & (IS_TMP_VAR|IS_VAR)) {
+ opline->op2.var += sizeof(zval);
+ }
+ if (opline->result_type & (IS_TMP_VAR|IS_VAR)) {
+ opline->result.var += sizeof(zval);
+ }
+ if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS ||
+ opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) {
+ opline->extended_value += sizeof(zval);
+ }
+ opline++;
+ }
+ }
+
+ return (int)EX_VAR_NUM_2(NULL, i);
}
#endif