fis-gtm/sr_port/op_setfnretin2alsct.c

79 lines
3.6 KiB
C

/****************************************************************
* *
* Copyright 2010, 2013 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_stdio.h"
#include "op.h"
#include "lv_val.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "alias.h"
#include "min_max.h"
#include "stack_frame.h"
GBLREF symval *curr_symval;
GBLREF uint4 dollar_tlevel;
GBLREF stack_frame *frame_pointer;
GBLREF mval *alias_retarg;
/* Operation - Set alias container returned from a function call into another alias container
*
* Note that this opcode's function is very similar to op_setalsct2alsct() but is necessarily different because the
* source container is a temporary mval passed back through a function return rather than the lv_val op_setalsct2alsct()
* deals with. Consequently, the amount of verification we can do is reduced. But this is acceptable due to the checks
* done by unw_retarg() and op_exfunretals() which pre-processed this value for us. There is also different reference
* count maintenance to do than the op_setalsct2alsct() opcode. With substantially more work to reorganize how SET
* operates, it would likely be possible to combine these functions but the way things are structured now, all the
* set functions plus op_sto() share the same API so adding a parm to one means adding a useless parm to all 6 of
* them which is not acceptable so we end up duplicating portions of code here.
*/
void op_setfnretin2alsct(mval *srcmv, lv_val *dstlv)
{
lv_val *src_lvref, *dst_lvbase;
symval *sym_src_lvref, *sym_dstlv;
assert(srcmv);
assert(dstlv);
assert(srcmv == alias_retarg);
assert(!LV_IS_BASE_VAR(dstlv)); /* Verify subscripted var */
assert(srcmv->mvtype & MV_ALIASCONT);
assert(MVAL_IN_RANGE(srcmv, frame_pointer->temps_ptr, frame_pointer->temp_mvals)); /* Verify is a temp mval */
assert(MV_IS_STRING(srcmv) && (0 == srcmv->str.len));
src_lvref = (lv_val *)srcmv->str.addr;
assert(src_lvref);
assert(LV_IS_BASE_VAR(src_lvref)); /* Verify base var */
assert(srcmv != (mval *)dstlv); /* Equality not possible since src is a temp mval and destination cannot be */
dst_lvbase = LV_GET_BASE_VAR(dstlv);
if (dollar_tlevel && (NULL != dst_lvbase->tp_var) && !dst_lvbase->tp_var->var_cloned)
TP_VAR_CLONE(dst_lvbase); /* clone the tree. */
/* Note reference counts were increased in unw_retarg() to preserve the values the input container pointed to
* when they potentially went out of scope during the return. So we do not increment them further here.
*/
DBGRFCT((stderr, "op_setfnretin2alsct: Copying funcret container referencing lvval 0x"lvaddr" into container 0x"lvaddr
"\n", src_lvref, dstlv));
dstlv->v = *srcmv;
assert(0 < src_lvref->stats.trefcnt);
assert(0 <= src_lvref->stats.crefcnt);
assert(src_lvref->stats.trefcnt >= src_lvref->stats.crefcnt);
/* Mark as alias-active the symval(s) of the destination container's and the source's pointed-to arrays */
sym_dstlv = LV_GET_SYMVAL(dst_lvbase);
sym_src_lvref = LV_GET_SYMVAL(src_lvref);
MARK_ALIAS_ACTIVE(MIN(sym_dstlv->symvlvl, sym_src_lvref->symvlvl));
/* Last operation is to mark the base var for our container array that it now has a container in it. */
MARK_CONTAINER_ONBOARD(dst_lvbase);
alias_retarg = NULL;
}