Browse Source

Improved return by reference handling

pull/825/merge
Dmitry Stogov 12 years ago
parent
commit
2ea97c6f5a
  1. 23
      Zend/zend_vm_def.h
  2. 32
      Zend/zend_vm_execute.h

23
Zend/zend_vm_def.h

@ -2698,17 +2698,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
ZEND_VM_C_GOTO(fcall_end);
}
} else if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
zval *return_value = NULL;
EG(scope) = fbc->common.scope;
call->symbol_table = NULL;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
ZVAL_NULL(return_value);
Z_VAR_FLAGS_P(return_value) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
}
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
if (RETURN_VALUE_USED(opline)) {
zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var) TSRMLS_CC);
@ -2718,6 +2708,16 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY)
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
zval *return_value = NULL;
call->symbol_table = NULL;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
ZVAL_NULL(return_value);
Z_VAR_FLAGS_P(return_value) = 0;
}
call->prev_execute_data = execute_data;
i_init_func_execute_data(call, &fbc->op_array, return_value TSRMLS_CC);
@ -2842,6 +2842,7 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
}
} else {
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (OP1_TYPE != IS_TMP_VAR) {
zval_opt_copy_ctor_no_imm(EX(return_value));
}
@ -2862,6 +2863,7 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
@ -2872,6 +2874,7 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
} while (0);

32
Zend/zend_vm_execute.h

@ -580,17 +580,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
goto fcall_end;
}
} else if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
zval *return_value = NULL;
EG(scope) = fbc->common.scope;
call->symbol_table = NULL;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
ZVAL_NULL(return_value);
Z_VAR_FLAGS_P(return_value) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0;
}
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
if (RETURN_VALUE_USED(opline)) {
zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var) TSRMLS_CC);
@ -600,6 +590,16 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_vm_stack_free_call_frame(call TSRMLS_CC);
} else {
zval *return_value = NULL;
call->symbol_table = NULL;
if (RETURN_VALUE_USED(opline)) {
return_value = EX_VAR(opline->result.var);
ZVAL_NULL(return_value);
Z_VAR_FLAGS_P(return_value) = 0;
}
call->prev_execute_data = execute_data;
i_init_func_execute_data(call, &fbc->op_array, return_value TSRMLS_CC);
@ -2648,6 +2648,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
}
} else {
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (IS_CONST != IS_TMP_VAR) {
zval_opt_copy_ctor_no_imm(EX(return_value));
}
@ -2668,6 +2669,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
@ -2678,6 +2680,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
} while (0);
@ -9474,6 +9477,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
}
} else {
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (IS_TMP_VAR != IS_TMP_VAR) {
zval_opt_copy_ctor_no_imm(EX(return_value));
}
@ -9494,6 +9498,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
@ -9504,6 +9509,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
} while (0);
@ -16036,6 +16042,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
}
} else {
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (IS_VAR != IS_TMP_VAR) {
zval_opt_copy_ctor_no_imm(EX(return_value));
}
@ -16056,6 +16063,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
@ -16066,6 +16074,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
} while (0);
@ -33680,6 +33689,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
}
} else {
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (IS_CV != IS_TMP_VAR) {
zval_opt_copy_ctor_no_imm(EX(return_value));
}
@ -33700,6 +33710,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
@ -33710,6 +33721,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
Z_VAR_FLAGS_P(EX(return_value)) = IS_VAR_RET_REF;
}
} while (0);

Loading…
Cancel
Save