fis-gtm/sr_port/do_indir_do.c

120 lines
4.3 KiB
C

/****************************************************************
* *
* Copyright 2001, 2012 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_string.h"
#include "toktyp.h"
#include "rtnhdr.h"
#include "stack_frame.h"
#include "indir_enum.h"
#include "cmd_qlf.h"
#include "gtm_caseconv.h"
#include "op.h"
#include "do_indir_do.h"
#include "valid_mname.h"
GBLREF stack_frame *frame_pointer;
GBLREF command_qualifier cmd_qlf;
GBLREF boolean_t is_tracing_on;
int do_indir_do(mval *v, unsigned char argcode)
{
mval label;
lnr_tabent USHBIN_ONLY(*)*addr;
mident_fixed ident;
rhdtyp *current_rhead;
if (valid_labname(&v->str))
{
memcpy(ident.c, v->str.addr, v->str.len);
if (!(cmd_qlf.qlf & CQ_LOWER_LABELS))
lower_to_upper((uchar_ptr_t)ident.c, (uchar_ptr_t)ident.c, v->str.len);
label.mvtype = MV_STR;
label.str.len = v->str.len;
label.str.addr = &ident.c[0];
addr = op_labaddr(frame_pointer->rvector, &label, 0);
current_rhead = CURRENT_RHEAD_ADR(frame_pointer->rvector);
if (argcode == indir_do)
{ /* If we aren't in an indirect, exfun_frame() is the best way to copy the stack frame as it does not
* require re-allocation of the various tables (temps, linkage, literals, etc). But if we are in an
* indirect, the various stackframe fields cannot be copied as the indirect has different values so
* re-create the frame from the values in the routine header via new_stack_frame().
*/
if (!(frame_pointer->flags & SFF_INDCE))
{
if (!is_tracing_on)
exfun_frame();
else
exfun_frame_sp();
} else
{
if (!is_tracing_on)
{
new_stack_frame(CURRENT_RHEAD_ADR(frame_pointer->rvector),
# ifdef HAS_LITERAL_SECT
(unsigned char *)LINKAGE_ADR(current_rhead),
# else
PTEXT_ADR(current_rhead),
# endif
USHBIN_ONLY(LINE_NUMBER_ADDR(current_rhead, *addr))
/* On non-shared binary calculate the transfer address to be passed to
* new_stack_frame as follows:
* 1) get the number stored at addr; this is the offset to the line number
* entry
* 2) add the said offset to the address of the routine header; this is the
* address of line number entry
* 3) dereference the said address to get the line number of the actual
* program
* 4) add the said line number to the address of the routine header
*/
NON_USHBIN_ONLY((unsigned char *)((char *)current_rhead
+ *(int4 *)((char *)current_rhead + *addr))));
} else
{
new_stack_frame_sp(CURRENT_RHEAD_ADR(frame_pointer->rvector),
# ifdef HAS_LITERAL_SECT
(unsigned char *)LINKAGE_ADR(current_rhead),
# else
PTEXT_ADR(current_rhead),
# endif
USHBIN_ONLY(LINE_NUMBER_ADDR(current_rhead, *addr))
/* On non-shared binary calculate the transfer address to be passed to
* new_stack_frame as follows:
* 1) get the number stored at addr; this is the offset to the line
* number entry
* 2) add the said offset to the address of the routine header; this is
* the address of line number entry
* 3) dereference the said address to get the line number of the actual
* program
* 4) add the said line number to the address of the routine header
*/
NON_USHBIN_ONLY((unsigned char *)((char *)current_rhead
+ *(int4 *)((char *)current_rhead + *addr))));
}
return TRUE;
}
}
/* On non-shared binary calculate the mpc pointer similarly to the descriptions above. */
frame_pointer->mpc =
USHBIN_ONLY(LINE_NUMBER_ADDR(current_rhead, *addr))
NON_USHBIN_ONLY((unsigned char *)((char *)current_rhead + *(int4 *)((char *)current_rhead + *addr)));
# ifdef HAS_LITERAL_SECT
frame_pointer->ctxt = (unsigned char *)LINKAGE_ADR(current_rhead);
# else
frame_pointer->ctxt = PTEXT_ADR(current_rhead);
# endif
return TRUE;
} else
return FALSE;
}