170 lines
5.5 KiB
C
170 lines
5.5 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 <rtnhdr.h>
|
|
#include "mv_stent.h" /* this includes lv_val.h which also includes hashtab_mname.h and hashtab.h */
|
|
#include "stack_frame.h"
|
|
#include "mdq.h"
|
|
|
|
#define MVST_STAB_SIZE (SIZEOF(*mv_chain) - SIZEOF(mv_chain->mv_st_cont) + SIZEOF(mv_chain->mv_st_cont.mvs_stab))
|
|
|
|
GBLREF symval *curr_symval;
|
|
|
|
GBLREF mv_stent *mv_chain;
|
|
GBLREF unsigned char *stackbase, *stacktop, *msp, *stackwarn;
|
|
GBLREF stack_frame *frame_pointer;
|
|
|
|
error_def(ERR_STACKOFLOW);
|
|
error_def(ERR_STACKCRIT);
|
|
|
|
int4 symbinit(void)
|
|
{
|
|
unsigned char *msp_save;
|
|
mv_stent *mv_st_ent, *mvst_tmp, *mvst_prev;
|
|
stack_frame *fp,*fp_prev,*fp_fix;
|
|
symval *ptr;
|
|
int4 shift_size, ls_size, temp_size;
|
|
int size;
|
|
unsigned char *old_sp, *top, *l_syms;
|
|
|
|
if (frame_pointer->type & SFT_COUNT)
|
|
{
|
|
temp_size = frame_pointer->rvector->temp_size;
|
|
size = frame_pointer->vartab_len;
|
|
ls_size = size * SIZEOF(ht_ent_mname *);
|
|
if (frame_pointer->l_symtab != (ht_ent_mname **)((char *)frame_pointer - temp_size - ls_size))
|
|
{
|
|
msp_save = msp;
|
|
msp -= ls_size;
|
|
if (msp <= stackwarn)
|
|
{
|
|
if (msp <= stacktop)
|
|
{
|
|
msp = msp_save;
|
|
rts_error(VARLSTCNT(1) ERR_STACKOFLOW);
|
|
} else
|
|
rts_error(VARLSTCNT(1) ERR_STACKCRIT);
|
|
}
|
|
frame_pointer->l_symtab = (ht_ent_mname **)msp;
|
|
}
|
|
PUSH_MV_STENT(MVST_STAB);
|
|
mv_st_ent = mv_chain;
|
|
l_syms = (unsigned char *)frame_pointer->l_symtab;
|
|
shift_size = 0;
|
|
} else
|
|
{
|
|
fp = frame_pointer;
|
|
fp_prev = fp->old_frame_pointer;
|
|
assert(fp_prev);
|
|
while (!(fp_prev->type & SFT_COUNT))
|
|
{
|
|
fp = fp_prev;
|
|
fp_prev = fp->old_frame_pointer;
|
|
assert(fp_prev);
|
|
}
|
|
top = (unsigned char *)(fp + 1);
|
|
old_sp = msp;
|
|
temp_size = fp_prev->rvector->temp_size;
|
|
size = fp_prev->vartab_len;
|
|
ls_size = size * SIZEOF(ht_ent_mname *);
|
|
shift_size = MVST_STAB_SIZE;
|
|
if (fp_prev->l_symtab != (ht_ent_mname **)((char *)fp_prev - ls_size - temp_size))
|
|
shift_size += ls_size;
|
|
msp -= shift_size;
|
|
if (msp <= stackwarn)
|
|
{
|
|
if (msp <= stacktop)
|
|
{
|
|
msp = old_sp;
|
|
rts_error(VARLSTCNT(1) ERR_STACKOFLOW);
|
|
} else
|
|
rts_error(VARLSTCNT(1) ERR_STACKCRIT);
|
|
}
|
|
memmove(msp, old_sp, top - (unsigned char *)old_sp); /* Shift stack w/possible overlapping range */
|
|
if (shift_size > MVST_STAB_SIZE)
|
|
fp_prev->l_symtab = (ht_ent_mname **)(top - shift_size);
|
|
l_syms = (unsigned char *)fp_prev->l_symtab;
|
|
mv_st_ent = (mv_stent *)(top - MVST_STAB_SIZE);
|
|
mv_st_ent->mv_st_type = MVST_STAB;
|
|
ADJUST_FRAME_POINTER(frame_pointer, shift_size);
|
|
for (fp_fix = frame_pointer; fp_fix != fp_prev ;fp_fix = fp_fix->old_frame_pointer)
|
|
{
|
|
if ((unsigned char *)fp_fix->l_symtab < top && (unsigned char *)fp_fix->l_symtab > stacktop)
|
|
{
|
|
fp_fix->l_symtab = (ht_ent_mname **)((char *)fp_fix->l_symtab - shift_size);
|
|
if ((unsigned char *)fp_fix->l_symtab < (unsigned char *)fp_fix)
|
|
memset((unsigned char *)fp_fix->l_symtab, 0, fp_fix->vartab_len * SIZEOF(ht_ent_mname *));
|
|
}
|
|
if (fp_fix->temps_ptr < top && fp_fix->temps_ptr > stacktop)
|
|
fp_fix->temps_ptr -= shift_size;
|
|
if (fp_fix->vartab_ptr < (char *)top && fp_fix->vartab_ptr > (char *)stacktop)
|
|
fp_fix->vartab_ptr -= shift_size;
|
|
if ((unsigned char *)fp_fix->old_frame_pointer < top && (unsigned char *)fp_fix->old_frame_pointer
|
|
> stacktop)
|
|
{
|
|
ADJUST_FRAME_POINTER(fp_fix->old_frame_pointer, shift_size);
|
|
}
|
|
}
|
|
if ((unsigned char *)mv_chain >= top)
|
|
{
|
|
mv_st_ent->mv_st_next = (uint4)((char *)mv_chain - (char *)mv_st_ent);
|
|
mv_chain = mv_st_ent;
|
|
} else
|
|
{
|
|
fp = (stack_frame *)((char *)fp - shift_size);
|
|
mv_chain = (mv_stent *)((char *)mv_chain - shift_size);
|
|
mvst_tmp = mv_chain;
|
|
mvst_prev = (mv_stent *)((char *)mvst_tmp + mvst_tmp->mv_st_next);
|
|
while (mvst_prev < (mv_stent *)fp)
|
|
{
|
|
mvst_tmp = mvst_prev;
|
|
mvst_prev = (mv_stent *)((char *)mvst_tmp + mvst_tmp->mv_st_next);
|
|
}
|
|
mvst_tmp->mv_st_next = (uint4)((char *)mv_st_ent - (char *)mvst_tmp);
|
|
mv_st_ent->mv_st_next = (uint4)((char *)mvst_prev - (char *)mv_st_ent + shift_size);
|
|
}
|
|
}
|
|
mv_st_ent->mv_st_cont.mvs_stab = (symval *)NULL; /* special case this so failed initialization can be detected */
|
|
|
|
memset(l_syms, 0, ls_size);
|
|
size++;
|
|
ptr = (symval *)malloc(SIZEOF(symval));
|
|
/* the order of initialization of fields mirrors the layout of the fields in the symval structure definition */
|
|
ptr->ident = MV_SYM;
|
|
ptr->sbs_depth = 0;
|
|
ptr->tp_save_all = 0;
|
|
ptr->xnew_var_list = NULL;
|
|
ptr->xnew_ref_list = NULL;
|
|
init_hashtab_mname(&ptr->h_symtab, size, HASHTAB_NO_COMPACT, HASHTAB_NO_SPARE_TABLE);
|
|
ptr->lv_first_block = NULL;
|
|
lv_newblock(ptr, size);
|
|
ptr->lvtree_first_block = NULL;
|
|
ptr->lvtreenode_first_block = NULL;
|
|
ptr->lv_flist = NULL;
|
|
ptr->lvtree_flist = NULL;
|
|
ptr->lvtreenode_flist = NULL;
|
|
ptr->last_tab = curr_symval;
|
|
/* if we get here, our initialization must have been successful */
|
|
if (curr_symval)
|
|
ptr->symvlvl = curr_symval->symvlvl + 1;
|
|
else
|
|
ptr->symvlvl = 1;
|
|
GTMTRIG_ONLY(ptr->trigr_symval = FALSE);
|
|
ptr->alias_activity = FALSE;
|
|
curr_symval = ptr;
|
|
mv_st_ent->mv_st_cont.mvs_stab = ptr;
|
|
return shift_size;
|
|
}
|