|
|
|
@ -1170,22 +1170,18 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) |
|
|
|
|
|
|
|
SAVE_OPLINE(); |
|
|
|
|
|
|
|
if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && |
|
|
|
OP1_TYPE != IS_CV && |
|
|
|
EX_T(opline->op1.var).var.ptr_ptr) { |
|
|
|
PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr); |
|
|
|
} |
|
|
|
|
|
|
|
if (OP1_TYPE == IS_TMP_VAR || OP1_TYPE == IS_CONST) { |
|
|
|
zval *container = GET_OP1_ZVAL_PTR(BP_VAR_R); |
|
|
|
zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); |
|
|
|
FREE_OP2(); |
|
|
|
FREE_OP1(); |
|
|
|
} else { |
|
|
|
container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R); |
|
|
|
container = GET_OP1_ZVAL_PTR_PTR_FAST(BP_VAR_R); |
|
|
|
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); |
|
|
|
FREE_OP2(); |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
if (OP1_TYPE == IS_VAR && !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) { |
|
|
|
FREE_OP1_VAR_PTR_FAST(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
CHECK_EXCEPTION(); |
|
|
|
@ -1255,10 +1251,10 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV) |
|
|
|
zval **container; |
|
|
|
|
|
|
|
SAVE_OPLINE(); |
|
|
|
container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS); |
|
|
|
container = GET_OP1_ZVAL_PTR_PTR_FAST(BP_VAR_IS); |
|
|
|
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_IS TSRMLS_CC); |
|
|
|
FREE_OP2(); |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
FREE_OP1_VAR_PTR_FAST(); |
|
|
|
CHECK_EXCEPTION(); |
|
|
|
ZEND_VM_NEXT_OPCODE(); |
|
|
|
} |
|
|
|
@ -1280,15 +1276,17 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV) |
|
|
|
if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) { |
|
|
|
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var)); |
|
|
|
} |
|
|
|
FREE_OP2(); |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
} else { |
|
|
|
if (OP2_TYPE == IS_UNUSED) { |
|
|
|
zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); |
|
|
|
} |
|
|
|
container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R); |
|
|
|
container = GET_OP1_ZVAL_PTR_PTR_FAST(BP_VAR_R); |
|
|
|
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC); |
|
|
|
FREE_OP2(); |
|
|
|
FREE_OP1_VAR_PTR_FAST(); |
|
|
|
} |
|
|
|
FREE_OP2(); |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
CHECK_EXCEPTION(); |
|
|
|
ZEND_VM_NEXT_OPCODE(); |
|
|
|
} |
|
|
|
@ -2842,9 +2840,7 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) |
|
|
|
retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R); |
|
|
|
|
|
|
|
if (!EG(return_value_ptr_ptr)) { |
|
|
|
if (OP1_TYPE == IS_TMP_VAR) { |
|
|
|
FREE_OP1(); |
|
|
|
} |
|
|
|
FREE_OP1(); |
|
|
|
} else { |
|
|
|
if (OP1_TYPE == IS_CONST || |
|
|
|
OP1_TYPE == IS_TMP_VAR || |
|
|
|
@ -2857,18 +2853,23 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) |
|
|
|
zval_copy_ctor(ret); |
|
|
|
} |
|
|
|
*EG(return_value_ptr_ptr) = ret; |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
} else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && |
|
|
|
retval_ptr == &EG(uninitialized_zval)) { |
|
|
|
zval *ret; |
|
|
|
|
|
|
|
if (OP1_TYPE == IS_VAR) { |
|
|
|
Z_DELREF_P(retval_ptr); |
|
|
|
} |
|
|
|
ALLOC_INIT_ZVAL(ret); |
|
|
|
*EG(return_value_ptr_ptr) = ret; |
|
|
|
} else { |
|
|
|
*EG(return_value_ptr_ptr) = retval_ptr; |
|
|
|
Z_ADDREF_P(retval_ptr); |
|
|
|
if (OP1_TYPE == IS_CV) { |
|
|
|
Z_ADDREF_P(retval_ptr); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); |
|
|
|
} |
|
|
|
|
|
|
|
@ -2936,7 +2937,7 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY) |
|
|
|
} |
|
|
|
} while (0); |
|
|
|
|
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); |
|
|
|
} |
|
|
|
|
|
|
|
@ -3079,21 +3080,26 @@ ZEND_VM_HELPER(zend_send_by_var_helper, VAR|CV, ANY) |
|
|
|
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); |
|
|
|
|
|
|
|
if (varptr == &EG(uninitialized_zval)) { |
|
|
|
ALLOC_ZVAL(varptr); |
|
|
|
INIT_ZVAL(*varptr); |
|
|
|
Z_SET_REFCOUNT_P(varptr, 0); |
|
|
|
if (OP1_TYPE == IS_VAR) { |
|
|
|
Z_DELREF_P(varptr); |
|
|
|
} |
|
|
|
ALLOC_INIT_ZVAL(varptr); |
|
|
|
} else if (PZVAL_IS_REF(varptr)) { |
|
|
|
zval *original_var = varptr; |
|
|
|
if (OP1_TYPE == IS_CV || |
|
|
|
(OP1_TYPE == IS_VAR && Z_REFCOUNT_P(varptr) > 2)) { |
|
|
|
zval *original_var = varptr; |
|
|
|
|
|
|
|
ALLOC_ZVAL(varptr); |
|
|
|
ZVAL_COPY_VALUE(varptr, original_var); |
|
|
|
Z_UNSET_ISREF_P(varptr); |
|
|
|
Z_SET_REFCOUNT_P(varptr, 0); |
|
|
|
zval_copy_ctor(varptr); |
|
|
|
ALLOC_ZVAL(varptr); |
|
|
|
INIT_PZVAL_COPY(varptr, original_var); |
|
|
|
zval_copy_ctor(varptr); |
|
|
|
FREE_OP1(); |
|
|
|
} else { |
|
|
|
Z_UNSET_ISREF_P(varptr); |
|
|
|
} |
|
|
|
} else if (OP1_TYPE == IS_CV) { |
|
|
|
Z_ADDREF_P(varptr); |
|
|
|
} |
|
|
|
Z_ADDREF_P(varptr); |
|
|
|
zend_vm_stack_push(varptr TSRMLS_CC); |
|
|
|
FREE_OP1(); /* for string offsets */ |
|
|
|
|
|
|
|
CHECK_EXCEPTION(); |
|
|
|
ZEND_VM_NEXT_OPCODE(); |
|
|
|
@ -3114,22 +3120,15 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) |
|
|
|
ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); |
|
|
|
} |
|
|
|
|
|
|
|
if (OP1_TYPE == IS_VAR && |
|
|
|
(opline->extended_value & ZEND_ARG_SEND_FUNCTION) && |
|
|
|
EX_T(opline->op1.var).var.fcall_returned_reference && |
|
|
|
EX_T(opline->op1.var).var.ptr) { |
|
|
|
varptr = EX_T(opline->op1.var).var.ptr; |
|
|
|
PZVAL_UNLOCK_EX(varptr, &free_op1, 0); |
|
|
|
} else { |
|
|
|
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); |
|
|
|
} |
|
|
|
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R); |
|
|
|
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || |
|
|
|
EX_T(opline->op1.var).var.fcall_returned_reference) && |
|
|
|
varptr != &EG(uninitialized_zval) && |
|
|
|
(PZVAL_IS_REF(varptr) || |
|
|
|
(Z_REFCOUNT_P(varptr) == 1 && (OP1_TYPE == IS_CV || free_op1.var)))) { |
|
|
|
(PZVAL_IS_REF(varptr) || Z_REFCOUNT_P(varptr) == 1)) { |
|
|
|
Z_SET_ISREF_P(varptr); |
|
|
|
Z_ADDREF_P(varptr); |
|
|
|
if (OP1_TYPE == IS_CV) { |
|
|
|
Z_ADDREF_P(varptr); |
|
|
|
} |
|
|
|
zend_vm_stack_push(varptr TSRMLS_CC); |
|
|
|
} else { |
|
|
|
zval *valptr; |
|
|
|
@ -3144,9 +3143,9 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) |
|
|
|
if (!IS_OP1_TMP_FREE()) { |
|
|
|
zval_copy_ctor(valptr); |
|
|
|
} |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
zend_vm_stack_push(valptr TSRMLS_CC); |
|
|
|
} |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
CHECK_EXCEPTION(); |
|
|
|
ZEND_VM_NEXT_OPCODE(); |
|
|
|
} |
|
|
|
@ -3347,9 +3346,6 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV) |
|
|
|
zend_free_op free_op1, free_op2; |
|
|
|
|
|
|
|
SAVE_OPLINE(); |
|
|
|
if (OP1_TYPE==IS_VAR) { |
|
|
|
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr); |
|
|
|
} |
|
|
|
is_equal_function(&EX_T(opline->result.var).tmp_var, |
|
|
|
GET_OP1_ZVAL_PTR(BP_VAR_R), |
|
|
|
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC); |
|
|
|
@ -3611,7 +3607,8 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS |
|
|
|
INIT_PZVAL_COPY(new_expr, expr_ptr); |
|
|
|
expr_ptr = new_expr; |
|
|
|
zendi_zval_copy_ctor(*expr_ptr); |
|
|
|
} else { |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
} else if (OP1_TYPE == IS_CV) { |
|
|
|
Z_ADDREF_P(expr_ptr); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -3659,8 +3656,6 @@ ZEND_VM_C_LABEL(num_index): |
|
|
|
} |
|
|
|
if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) && opline->extended_value) { |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
} else { |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
} |
|
|
|
CHECK_EXCEPTION(); |
|
|
|
ZEND_VM_NEXT_OPCODE(); |
|
|
|
@ -4147,19 +4142,27 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) |
|
|
|
} else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { |
|
|
|
ce = Z_OBJCE_P(array_ptr); |
|
|
|
if (!ce || !ce->get_iterator) { |
|
|
|
Z_ADDREF_P(array_ptr); |
|
|
|
if (OP1_TYPE == IS_CV) { |
|
|
|
Z_ADDREF_P(array_ptr); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (OP1_TYPE == IS_CONST || |
|
|
|
((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && |
|
|
|
(OP1_TYPE == IS_CV && |
|
|
|
!Z_ISREF_P(array_ptr) && |
|
|
|
Z_REFCOUNT_P(array_ptr) > 1)) { |
|
|
|
Z_REFCOUNT_P(array_ptr) > 1) || |
|
|
|
(OP1_TYPE == IS_VAR && |
|
|
|
!Z_ISREF_P(array_ptr) && |
|
|
|
Z_REFCOUNT_P(array_ptr) > 2)) { |
|
|
|
zval *tmp; |
|
|
|
|
|
|
|
if (OP1_TYPE == IS_VAR) { |
|
|
|
Z_DELREF_P(array_ptr); |
|
|
|
} |
|
|
|
ALLOC_ZVAL(tmp); |
|
|
|
INIT_PZVAL_COPY(tmp, array_ptr); |
|
|
|
zval_copy_ctor(tmp); |
|
|
|
array_ptr = tmp; |
|
|
|
} else { |
|
|
|
} else if (OP1_TYPE == IS_CV) { |
|
|
|
Z_ADDREF_P(array_ptr); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -4167,10 +4170,15 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) |
|
|
|
if (ce && ce->get_iterator) { |
|
|
|
iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); |
|
|
|
|
|
|
|
if (OP1_TYPE == IS_VAR && !(opline->extended_value & ZEND_FE_RESET_VARIABLE)) { |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
} |
|
|
|
if (iter && EXPECTED(EG(exception) == NULL)) { |
|
|
|
array_ptr = zend_iterator_wrap(iter TSRMLS_CC); |
|
|
|
} else { |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
} |
|
|
|
if (!EG(exception)) { |
|
|
|
zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name); |
|
|
|
} |
|
|
|
@ -4187,14 +4195,18 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) |
|
|
|
iter->funcs->rewind(iter TSRMLS_CC); |
|
|
|
if (UNEXPECTED(EG(exception) != NULL)) { |
|
|
|
zval_ptr_dtor(&array_ptr); |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
} |
|
|
|
HANDLE_EXCEPTION(); |
|
|
|
} |
|
|
|
} |
|
|
|
is_empty = iter->funcs->valid(iter TSRMLS_CC) != SUCCESS; |
|
|
|
if (UNEXPECTED(EG(exception) != NULL)) { |
|
|
|
zval_ptr_dtor(&array_ptr); |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
} |
|
|
|
HANDLE_EXCEPTION(); |
|
|
|
} |
|
|
|
iter->index = -1; /* will be set to 0 before using next handler */ |
|
|
|
@ -4224,7 +4236,9 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) |
|
|
|
is_empty = 1; |
|
|
|
} |
|
|
|
|
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
} |
|
|
|
if (is_empty) { |
|
|
|
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num); |
|
|
|
} else { |
|
|
|
@ -4460,7 +4474,7 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST| |
|
|
|
zval *offset; |
|
|
|
|
|
|
|
SAVE_OPLINE(); |
|
|
|
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_IS); |
|
|
|
container = GET_OP1_OBJ_ZVAL_PTR_PTR_FAST(BP_VAR_IS); |
|
|
|
|
|
|
|
offset = GET_OP2_ZVAL_PTR(BP_VAR_R); |
|
|
|
|
|
|
|
@ -4587,7 +4601,7 @@ ZEND_VM_C_LABEL(num_index_prop): |
|
|
|
Z_LVAL(EX_T(opline->result.var).tmp_var) = !result; |
|
|
|
} |
|
|
|
|
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
FREE_OP1_VAR_PTR_FAST(); |
|
|
|
|
|
|
|
CHECK_EXCEPTION(); |
|
|
|
ZEND_VM_NEXT_OPCODE(); |
|
|
|
@ -5289,14 +5303,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE |
|
|
|
generator->value = *value_ptr; |
|
|
|
} |
|
|
|
|
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
FREE_OP1_VAR_PTR(); |
|
|
|
} |
|
|
|
} else { |
|
|
|
zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R); |
|
|
|
|
|
|
|
/* Consts, temporary variables and references need copying */ |
|
|
|
if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR |
|
|
|
|| (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) |
|
|
|
|| PZVAL_IS_REF(value) |
|
|
|
) { |
|
|
|
zval *copy; |
|
|
|
|
|
|
|
@ -5309,12 +5323,13 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE |
|
|
|
} |
|
|
|
|
|
|
|
generator->value = copy; |
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
} else { |
|
|
|
Z_ADDREF_P(value); |
|
|
|
if (OP1_TYPE == IS_CV) { |
|
|
|
Z_ADDREF_P(value); |
|
|
|
} |
|
|
|
generator->value = value; |
|
|
|
} |
|
|
|
|
|
|
|
FREE_OP1_IF_VAR(); |
|
|
|
} |
|
|
|
} else { |
|
|
|
/* If no value was specified yield null */ |
|
|
|
|