cgbksvar.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 762 行 · 第 1/2 页
C
762 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Back-end support for state-variable version.
*
****************************************************************************/
#include "plusplus.h"
#include <float.h>
#include "cgfront.h"
#include "cgback.h"
#include "memmgr.h"
#include "errdefns.h"
#include "codegen.h"
#include "cgbackut.h"
#include "ring.h"
#include "initdefs.h"
#ifndef NDEBUG
#include <stdio.h>
#include "dbg.h"
#include "toggle.h"
#include "pragdefn.h"
#endif
//**********************************************************************
// Static Data
//**********************************************************************
static carve_t carveSE_SYM_AUTO; // allocations for SE_SYM_AUTO
static carve_t carveSE_SYM_STATIC; // allocations for SE_SYM_STATIC
static carve_t carveSE_SUBOBJ; // allocations for SE_SUBOBJ
static carve_t carveSE_TRY; // allocations for SE_TRY
static carve_t carveSE_CATCH; // allocations for SE_CATCH
static carve_t carveSE_FN_EXC; // allocations for SE_FN_EXC
static carve_t carveSE_SET_SV; // allocations for SE_SET_SV
static carve_t carveSE_TEST_FLAG; // allocations for SE_TEST_FLAG
static carve_t carveSE_COMPONENT; // allocations for SE_COMPONENT
static carve_t carveSE_ARRAY_INIT; // allocations for SE_ARRAY_INIT
static carve_t carveSE_DLT_1; // allocations for SE_DLT_1
static carve_t carveSE_DLT_2; // allocations for SE_DLT_2
static carve_t carveSE_DLT_1_ARRAY; // allocations for SE_DLT_1_ARRAY
static carve_t carveSE_DLT_2_ARRAY; // allocations for SE_DLT_2_ARRAY
static carve_t carveSE_CTOR_TEST; // allocations for SE_CTOR_TEST
static carve_t carveSTAB_DEFN; // allocations for STAB_DEFN
static carve_t carveSTAB_CTL; // allocations for STAB_CTL
//**********************************************************************
// internal support
//**********************************************************************
#define carver_DTC_ARRAY NULL
#define carver_DTC_SYM_AUTO &carveSE_SYM_AUTO
#define carver_DTC_SYM_STATIC &carveSE_SYM_STATIC
#define carver_DTC_SUBOBJ &carveSE_SUBOBJ
#define carver_DTC_TEST_FLAG &carveSE_TEST_FLAG
#define carver_DTC_COMP_VBASE &carveSE_COMPONENT
#define carver_DTC_COMP_DBASE &carveSE_COMPONENT
#define carver_DTC_COMP_MEMB &carveSE_COMPONENT
#define carver_DTC_ACTUAL_VBASE &carveSE_COMPONENT
#define carver_DTC_ACTUAL_DBASE &carveSE_COMPONENT
#define carver_DTC_TRY &carveSE_TRY
#define carver_DTC_CATCH &carveSE_CATCH
#define carver_DTC_FN_EXC &carveSE_FN_EXC
#define carver_DTC_SET_SV &carveSE_SET_SV
#define carver_DTC_ARRAY_INIT &carveSE_ARRAY_INIT
#define carver_DTC_DLT_1 &carveSE_DLT_1
#define carver_DTC_DLT_2 &carveSE_DLT_2
#define carver_DTC_DLT_1_ARRAY &carveSE_DLT_1_ARRAY
#define carver_DTC_DLT_2_ARRAY &carveSE_DLT_2_ARRAY
#define carver_DTC_CTOR_TEST &carveSE_CTOR_TEST
static carve_t* seCarvers[] = {
#define DTC_DEF( a ) carver_ ## a
#define DTC_MRK( a )
#define DTC_VAL( a, b ) DTC_DEF( a )
DTC_DEFS
#undef DTC_DEF
#undef DTC_MRK
#undef DTC_VAL
};
#ifndef NDEBUG
static carve_t seCarver( // GET CARVER FOR AN SE TYPE
uint_8 se_type ) // - code for entry
{
DbgVerify( se_type < MAX_DTC_DEF, "seCarver -- BAD DTC_..." );
DbgVerify( se_type != DTC_ARRAY, "seCarver -- BAD DTC_..." );
return *seCarvers[ se_type ];
}
#else
#define seCarver(a) *seCarvers[a]
#endif
static void seFree( // FREE AN SE ENTRY
SE* se ) // - entry
{
CarveFree( seCarver( se->base.se_type ), se );
}
static void pruneSE( // PRUNE STATE ENTRY
SE** a_stab, // - addr[ state table pointer ]
SE* se ) // - entry to be removed
{
SE* prev // - previous entry
= se->base.prev;
SE* next // - next entry
= se->base.next;
RingPrune( a_stab, se );
#ifndef NDEBUG
if( PragDbgToggle.dump_stab ) {
printf( "State Table[%x] removed: %x\n", a_stab, se );
DbgDumpStateEntry( se );
}
#endif
next->base.prev = prev;
prev->base.next = next;
seFree( se );
}
static boolean sameSE( // DETERMINE IF SAME STATE ENTRY
SE* se, // - state entry to be added
SE* state_table ) // - state table
{
SE* last; // - last state entry in table
boolean retn; // - TRUE ==> same entry
last = state_table;
if( last == NULL ) {
retn = FALSE;
} else {
if( last->base.se_type == DTC_CTOR_TEST ) {
last = last->base.prev;
}
if( last->base.se_type == se->base.se_type ) {
switch( se->base.se_type ) {
case DTC_SET_SV :
last->set_sv.se = se->set_sv.se;
// check for SET_SV to previous
#ifndef NDEBUG
if( PragDbgToggle.dump_stab ) {
printf( "State Table replacement %x\n", se );
DbgDumpStateEntry( last );
}
#endif
retn = TRUE;
break;
case DTC_TEST_FLAG :
if( last->test_flag.index == se->test_flag.index
&& last->test_flag.se_true == se->test_flag.se_true
&& last->test_flag.se_false == se->test_flag.se_false ) {
retn = TRUE;
} else {
retn = FALSE;
}
break;
default :
retn = FALSE;
break;
}
} else {
retn = FALSE;
}
}
return retn;
}
static SE* stateTableAddSe( // ADD TO STATE TABLE
SE* se, // - state entry
SE** a_stab ) // - addr[ state table pointer ]
{
SE* next; // - next in doubly linked ring
SE* state_table; // - end of state table
unsigned state_var; // - value of state variable
state_table = *a_stab;
if( sameSE( se, state_table ) ) {
seFree( se );
se = state_table;
} else {
if( se->base.se_type == DTC_TEST_FLAG
&& NULL != state_table
&& state_table->base.se_type == DTC_SET_SV ) {
pruneSE( a_stab, *a_stab );
state_table = *a_stab;
}
if( NULL == state_table ) {
state_var = 0;
} else {
state_var = state_table->base.state_var;
}
if( se->base.gen ) {
++ state_var;
}
se->base.state_var = state_var;
RingAppend( a_stab, se );
next = se->base.next;
se->base.prev = next->base.prev;
next->base.prev = se;
#ifndef NDEBUG
if( PragDbgToggle.dump_stab ) {
printf( "State Table[%x] added: %x\n", a_stab, se );
DbgDumpStateEntry( se );
}
#endif
}
return se;
}
//**********************************************************************
// STAB_DEFN Support
//**********************************************************************
STAB_DEFN* StabDefnInit( // INITIALIZE STAB_DEFN
STAB_DEFN* defn, // - definition
unsigned kind ) // - kind of table
{
defn->kind = kind;
defn->state_table = NULL;
defn->ro = NULL;
return defn;
}
STAB_DEFN* StabDefnAllocate( // ALLOCATE STAB_DEFN
unsigned kind ) // - kind of table
{
return StabDefnInit( CarveAlloc( carveSTAB_DEFN ), kind );
}
void StabDefnFree( // FREE AN STAB_DEFN
STAB_DEFN* defn ) // - entry to be freed
{
CarveFree( carveSTAB_DEFN, defn );
}
SE* StabDefnAddSe( // ADD STATE ENTRY TO STATE TABLE
SE* se, // - entry to be added
STAB_DEFN* defn ) // - state table definition
{
return stateTableAddSe( se, &defn->state_table );
}
void StabDefnFreeStateTable( // FREE A STATE TABLE
STAB_DEFN* defn ) // - definition for state table
{
SE* se; // - current state entry
if( NULL != defn ) {
RingIterBegSafe( defn->state_table, se ) {
seFree( se );
} RingIterEndSafe( se )
}
}
static void stabDefnRemove( // REMOVE TOP ENTRY
STAB_DEFN* defn ) // - definition for state table
{
pruneSE( &defn->state_table, defn->state_table );
}
//**********************************************************************
// STAB_CTL Support
//**********************************************************************
STAB_CTL* StabCtlInit( // INITIALIZE STAB_CTL
STAB_CTL* stab, // - control info: instance
STAB_DEFN* defn ) // - control information: definition
{
stab->rw = NULL;
stab->defn = defn;
return stab;
}
SE* StateTableCurrPosn( // GET STATE ENTRY FOR CURRENT POSITION
STAB_CTL* sctl ) // - control info
{
SE* curr_posn; // - current position
if( sctl->defn == NULL ) {
curr_posn = NULL;
} else {
curr_posn = SeSetSvPosition( sctl->defn->state_table );
}
return curr_posn;
}
SE* StateTableActualPosn( // GET (UN-OPTIMIZED) CURRENT STATE ENTRY
STAB_CTL* sctl ) // - control info
{
return sctl->defn->state_table;
}
SE* StabCtlPrecedes( // GET PRECEDING ENTRY OR NULL
STAB_CTL* sctl, // - control info
SE* se ) // - state entry
{
se = se->base.prev;
if( se == sctl->defn->state_table ) {
se = NULL;
}
return se;
}
SE* StabCtlPrevious( // GET PREVIOUS ENTRY OR NULL
STAB_CTL* sctl, // - control info
SE* se ) // - state entry
{
return SeSetSvPosition( StabCtlPrecedes( sctl, se ) );
}
static void pruneFixUp( // FIX-UP PTR. TO ENTRY, FOR PRUNING
SE** a_se ) // - addr[ SE ptr ]
{
SE* se; // - entry
STATE_VAR state_var; // - state value
se = *a_se;
if( se != NULL && ! se->base.gen ) {
state_var = se->base.state_var;
if( 0 == state_var ) {
se = NULL;
} else {
for( ; ; ) {
se = se->base.prev;
if( se->base.state_var == state_var ) {
if( se->base.gen ) break;
}
}
}
*a_se = se;
}
}
void StabCtlPrune( // PRUNE UN-GENNED ENTRIES UP TO AN ENTRY
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?