120 lines
4.3 KiB
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;
|
|
}
|