cgbkcbak.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 530 行 · 第 1/2 页
C
530 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "plusplus.h"
#include "cgfront.h"
#include "cgback.h"
#include "codegen.h"
#include "cgbackut.h"
#include "carve.h"
#include "pstk.h"
#include "initdefs.h"
#include "errdefns.h"
#include "dbg.h"
typedef struct // patch_entry -- patch SE state variable
{ SE* se; // - state entry
patch_handle patch; // - CG patching handle
target_offset_t flag_no; // - flag # for patching
} patch_entry;
typedef struct // temp_entry -- entry for a temporary
{ SE* se; // - state entry for temporary
SE* start; // - state entry at start of ctor
patch_handle patch; // - CG patching handle
} temp_entry;
static carve_t carve_patch_se; // carver: SE patch entries
static carve_t carve_ctor_flag; // carver: ctor flag patch entries
static carve_t carve_temp_entry; // carver: temp_entry's
static PSTK_CTL stack_new_ctors; // stack: newed ctoring
#ifndef NDEBUG
#include <stdio.h>
#include "toggle.h"
#include "pragdefn.h"
static void _peDump( patch_entry* pe, const char* msg ) {
if( PragDbgToggle.dump_stab ) {
printf( "%s[%x] se[%x] handle[%d]\n"
, msg
, pe
, pe->se
, pe->patch );
}
}
#else
#define _peDump( a, b )
#endif
static void init( // module initialization
INITFINI* defn )
{
defn = defn;
carve_patch_se = CarveCreate( sizeof( patch_entry ), 16 );
carve_ctor_flag = CarveCreate( sizeof( CTOR_FLAG_SET ), 16 );
carve_temp_entry = CarveCreate( sizeof( temp_entry ), 16 );
PstkOpen( &stack_new_ctors );
}
static void fini( // module completion
INITFINI* defn )
{
defn = defn;
CarveDestroy( carve_patch_se );
CarveDestroy( carve_ctor_flag );
CarveDestroy( carve_temp_entry );
PstkClose( &stack_new_ctors );
}
INITDEFN( cg_call_back, init, fini );
static boolean ctorTestReqd( // TEST IF CTOR-TEST REQUIRED
SE* top, // - top entry
SE* object ) // - object being ctored
{
return top->base.se_type != DTC_CTOR_TEST
|| object != top->base.prev;
}
static cg_name emitPatch( // EMIT A PATCH EXPRESSION
patch_handle* a_handle ) // - addr[ patch handle ]
{
return FstabEmitStateVarPatch( a_handle, FnCtlTop() );
}
cg_name CgCallBackLeft( // MAKE A LEFT CALL-BACK
cg_name expr, // - expression
void (*fun)( void* ), // - call-back function
void* data, // - data for call back
cg_type type ) // - type of expression
{
return CgComma( CGCallback( fun, data ), expr, type );
}
cg_name CgCallBackRight( // MAKE A RIGHT CALL-BACK
cg_name expr, // - expression
void (*fun)( void* ), // - call-back function
void* data, // - data for call back
cg_type type ) // - type of expression
{
return CgSideEffect( expr, CGCallback( fun, data ), type );
}
static cg_name ctorFlagSet( // SET/RESET CTOR FLAG
FN_CTL* fctl, // - function info
unsigned opcode, // - set/reset opcode
patch_handle* a_ph ) // - addr[ patch_handle ]
{
unsigned offset; // - offset of flag byte
unsigned mask; // - mask for byte
cg_name op_flg; // - expression for code-gen
mask = FnCtlCondFlagCtor( fctl );
offset = mask / 8;
mask &= 7;
op_flg = CgSymbolPlusOffset( FstabRw(), offset + CgbkInfo.size_rw_base );
*a_ph = BEPatch();
op_flg = CGLVPreGets( opcode
, op_flg
, CGPatchNode( *a_ph, T_UINT_1 )
, T_UINT_1 );
return op_flg;
}
static void callBackCtorFlag( // CALL-BACK FOR CTOR-FLAG AFTER CTORING
void* data ) // - patch entry
{
CTOR_FLAG_SET* cfs = data; // - patch entry
if( ctorTestReqd( FstabActualPosn(), cfs->se ) ) {
FN_CTL* fctl = FnCtlTop();
unsigned mask = 1 << ( FnCtlCondFlagCtor( fctl ) & 7 );
BEPatchInteger( cfs->ph_clr, 255 - mask );
} else {
BEPatchInteger( cfs->ph_clr, -1 );
}
BEFiniPatch( cfs->ph_clr );
CarveFree( carve_ctor_flag, cfs );
}
static cg_name genCtorFlagClr( // CLEAR CTOR FLAGGING
cg_name expr, // - current expression
cg_type type, // - expression type
SE* se ) // - state entry for ctor'ed object
{
FN_CTL* fctl = FnCtlTop(); // - function information
CTOR_FLAG_SET* cfs; // - call-back data
if( DtmTabular( fctl ) ) {
cfs = CarveAlloc( carve_ctor_flag );
cfs->se = se;
expr = CgComma( ctorFlagSet( fctl, O_AND, &cfs->ph_clr )
, expr
, type );
expr = CgCallBackRight( expr, &callBackCtorFlag, cfs, type );
}
return expr;
}
static void setSeCtorTest( // CALL BACK: SET SE AND CTOR-TEST
void* data ) // - state entry
{
SE* se = (SE*)data;
se = BlkPosnUpdate( se );
se = BlkPosnTempEndSet( se );
FstabAdd( se );
FstabCtorTest( FnCtlTop() );
}
cg_name CgCallBackCtorStart( // SET A CALL BACK FOR A CTOR-TEST : START
cg_name expr, // - expression
cg_type type, // - type of expression
SE* se ) // - state entry to be inserted on call back
{
expr = genCtorFlagClr( expr, type, se );
expr = CgCallBackLeft( expr, &setSeCtorTest, se, type );
return expr;
}
cg_name CgCallBackInitRefBeg( // START CALL-BACK FOR INIT-REF
SE* se ) // - state entry for init-ref variable
{
FstabCtorTest( FnCtlTop() );
return genCtorFlagClr( NULL, T_POINTER, se );
}
static void checkCtorTest( // ELIMINATE CTOR-TEST IF POSSIBLE
void* data ) // - state entry
{
SE* se = data;
SE* test = FstabActualPosn();
#ifndef NDEBUG
if( PragDbgToggle.dump_stab ) {
printf( "CallBack: checkCtorTest: se[%x] test[%x]\n"
, se
, test );
}
#endif
if( ctorTestReqd( test, se ) ) {
// intervening state entries
FstabSetSvSe( se );
} else {
// no intervening state entries
FstabRemove();
}
}
static void patchSE( // PATCH STATE ENTRY'S VALUE
patch_entry* pe ) // - patch entry
{
STATE_VAR state_var = SeStateOptimal( pe->se );
FstabMarkedPosnSet( pe->se );
BEPatchInteger( pe->patch, state_var );
BEFiniPatch( pe->patch );
CarveFree( carve_patch_se, pe );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?