cgbkibrp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 590 行 · 第 1/2 页
C
590 行
/****************************************************************************
*
* 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 <float.h>
#include "cgfront.h"
#include "cgback.h"
#include "codegen.h"
#include "cgbackut.h"
#include "ring.h"
#include "initdefs.h"
#ifndef NDEBUG
#include "errdefns.h"
#endif
typedef struct ibrp IBRP;
struct ibrp // IBRP -- inline bound reference parameters
{ IBRP *next; // - next in ring
cg_name handle; // - handle of called function
SYMBOL func; // - inline function called
SYMBOL refed; // - referenced symbol (caller)
target_size_t offset; // - offset added to reference arg
FN_CTL *source; // - handle of generator of IBRPs
union {
unsigned index; // - argument # (before inlining)
SYMBOL parm; // - symbol (after IC_FUNCTION_ARGS)
} u;
};
static carve_t carveIBRP; // allocations for IBRPs
static IBRP *ibrps; // ring of IBRPs scheduled
static unsigned parm_no; // parm # being defined
#ifdef NDEBUG
#define dump_ibrp( ibrp, text )
#else
#include <stdio.h>
#include "dbg.h"
#include "pragdefn.h"
static void prt_ibrp( // PRINT IBRP ENTRY
IBRP* ibrp, // - entry
const char *text ) // - text string
{
printf ( "[%x]%s\n hdl=%x func=%x refed=%x off=%x parm=%x\n"
, ibrp
, text
, ibrp->handle
, ibrp->func
, ibrp->refed
, ibrp->offset
, ibrp->u.parm );
}
static void dump_ibrp( // DUMP IBRP ENTRY
IBRP* ibrp, // - entry
const char *text ) // - text string
{
if( PragDbgToggle.dump_exec_ic ) {
prt_ibrp( ibrp, text );
}
}
boolean IbpEmpty( // DEBUG -- verify empty
void )
{
return ibrps == NULL;
}
void IbpDump() // DEBUG -- dump all entries
{
if( IbpEmpty() ) {
printf( "IBRP -- no bound references\n" );
} else {
IBRP* curr;
RingIterBeg( ibrps, curr ) {
prt_ibrp( curr, "IBRP" );
} RingIterEnd( curr )
}
}
#endif
static void ibpRemove( // REMOVE AN IBRP ENTRY
IBRP *ibrp ) // - item to be removed
{
dump_ibrp( ibrp, "IBRP(popped)" );
RingPrune( &ibrps, ibrp );
CarveFree( carveIBRP, ibrp );
}
void IbpFlush( // REMOVE ALL IBRP ENTRIES FOR THIS CALL CONTEXT
FN_CTL* fctl ) // - current file control
{
IBRP *ibrp; // - current reference
RingIterBegSafe( ibrps, ibrp ) {
if( ibrp->source == fctl ) {
ibpRemove( ibrp );
}
} RingIterEndSafe( ibrp )
}
void IbpAdd( // ADD AN IBRP ENTRY
SYMBOL binding, // - symbol to bind reference to
target_offset_t offset, // - offset into symbol
FN_CTL* fctl ) // - current file information
{
IBRP *ibrp; // - new entry
SYMBOL trans; // - translated symbol
SYMBOL bound; // - bound reference
target_offset_t bound_off; // - bound offset
if( SymIsArgument( binding ) ) {
IbpReference( binding, &trans, &bound, &bound_off );
trans = bound;
offset += bound_off;
} else {
trans = SymTrans( binding );
}
ibrp = RingCarveAlloc( carveIBRP, &ibrps );
ibrp->handle = CallStackTopHandle();
ibrp->func = CallStackTopFunction();
ibrp->refed = trans;
ibrp->offset = offset;
ibrp->source = fctl;
ibrp->u.index = 0;
dump_ibrp( ibrp, "IBRP(created)" );
}
void IbpDefineSym( // DEFINE SYMBOL FOR BOUND PARAMETER
call_handle handle, // - handle for call
SYMBOL sym ) // - the symbol
{
IBRP *ibrp; // - current inline bound reference parameter
if( handle != NULL ) {
RingIterBeg( ibrps, ibrp ) {
if( ( handle == ibrp->handle )
&&( parm_no == ibrp->u.index ) ) {
ibrp->u.parm = sym;
dump_ibrp( ibrp, "IBRP(defined parm)" );
break;
}
} RingIterEnd( ibrp )
++parm_no;
}
}
void IbpDefineOffset( // DEFINE OFFSET FOR BOUND REFERENCE PARAMETER
target_offset_t offset ) // - the offset
{
IBRP *ibrp; // - current IBRP
ibrp = ibrps;
if( ibrp->refed != NULL ) {
ibrp->offset += offset;
dump_ibrp( ibrp, "IBRP(defined offset)" );
}
}
void IbpDefineParms( // START DEFINING PARAMETERS
void )
{
parm_no = 0;
}
void IbpDefineIndex( // DEFINE CURRENT PARAMETER INDEX
unsigned index ) // - index
{
IBRP *ibrp; // - current IBRP
ibrp = ibrps;
if( ibrp->refed == NULL ) {
ibpRemove( ibrp );
} else {
ibrp->u.index = index;
dump_ibrp( ibrp, "IBRP(defined index)" );
}
}
boolean IbpReference( // LOCATE A BOUND REFERENCE
SYMBOL sym, // - original symbol
SYMBOL *trans, // - addr[ translated symbol ]
SYMBOL *bound, // - addr[ bound reference ]
target_offset_t *offset ) // - addr[ offset from bound reference ]
{
IBRP *ibrp; // - current inline bound reference parm.
boolean retn; // - TRUE ==> bound was located
FN_CTL* fctl; // - current file control
fctl = FnCtlTop();
if( sym == NULL ) {
sym = fctl->this_sym;
} else {
sym = SymTrans( sym );
}
*trans = sym;
*bound = NULL;
*offset = 0;
retn = FALSE;
RingIterBeg( ibrps, ibrp ) {
if( ( sym == ibrp->u.parm )
&&( fctl->handle == ibrp->handle ) ) {
*bound = ibrp->refed;
*offset = ibrp->offset;
dump_ibrp( ibrp, "IBRP(used)" );
#if 0
if( PragDbgToggle.dump_exec_ic ) {
printf( "ibrp->func: " );
DumpSymbol( ibrp->func );
printf( "ibrp->refed: " );
DumpSymbol( ibrp->refed );
printf( "ibrp->u.parm: " );
DumpSymbol( ibrp->u.parm );
}
#endif
retn = TRUE;
break;
}
} RingIterEnd( ibrp )
return retn;
}
static cg_name directRef( // DO DIRECT REFERENCE IF POSSIBLE
SYMBOL orig_sym, // - original symbol
SYMBOL* a_sym, // - addr[ translated symbol ]
target_offset_t ref_off ) // - offset to item
{
SYMBOL bound; // - bound reference
target_offset_t offset; // - offset from bound reference
cg_name op; // - NULL or direct-ref expression
ref_off = ref_off;
if( IbpReference( orig_sym, a_sym, &bound, &offset ) ) {
op = CgSymbolPlusOffset( bound, offset );
} else {
op = NULL;
}
return op;
}
cg_name IbpFetchRef( // FETCH A REFERENCE PARAMETER
SYMBOL orig_sym ) // - NULL or original symbol
{
SYMBOL sym; // - current symbol
cg_name op; // - operand
op = directRef( orig_sym, &sym, 0 );
if( NULL == op ) {
op = CgFetchType( CgSymbol( sym ), CgGetCgType( sym->sym_type ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?