cgbkcmds.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 736 行 · 第 1/2 页

C
736
字号
/****************************************************************************
*
*                            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 "cgback.h"
#include "cgbackut.h"
#include "typesig.h"
#include "ctexcept.h"
#include "carve.h"
#include "ring.h"
#include "initdefs.h"

#ifndef NDEBUG
    #include "errdefns.h"
    #include <stdio.h>
    #include "dbg.h"
    #include "toggle.h"
    #include "pragdefn.h"
#endif

enum                                    // INDICES FOR STATE-TABLE COMMANDS
{   DTOR_CMD_INDEX_VBASE                // - virtual base
,   DTOR_CMD_INDEX_DBASE                // - direct base
,   DTOR_CMD_INDEX_SETSV                // - set sv (must be last)
};


static carve_t carveCMD_SET_SV;         // allocations for CMD_SET_SV
static carve_t carveCMD_TEST_FLAG;      // allocations for CMD_TEST_FLAG
static carve_t carveCMD_TRY;            // allocations for CMD_TRY
static carve_t carveCMD_FN_EXC;         // allocations for CMD_FN_EXC
static carve_t carveCMD_COMPONENT;      // allocations for CMD_COMPONENT
static carve_t carveCMD_ARRAY_INIT;     // allocations for CMD_ARRAY_INIT
static carve_t carveCMD_DEL_1;          // allocations for CMD_DEL_1
static carve_t carveCMD_DEL_2;          // allocations for CMD_DEL_2
static carve_t carveCMD_DEL_1_ARRAY;    // allocations for CMD_DEL_1_ARRAY
static carve_t carveCMD_DEL_2_ARRAY;    // allocations for CMD_DEL_2_ARRAY
static carve_t carveCMD_CTOR_TEST;      // allocations for CMD_CTOR_TEST

static CMD_SET_SV* ringCmdsSetSv;       // commands: SET_SV
static CMD_TEST_FLAG* ringCmdsTestFlag; // commands: TEST_FLAG
static CMD_COMPONENT* ringCmdsComponent;// commands: COMPONENT (function)
static CMD_TRY* ringCmdsTry;            // commands: TRY
static CMD_FN_EXC* ringCmdsFnExc;       // commands: FN_EXC
static CMD_DEL_1* ringCmdsDel1;         // commands: DEL_1
static CMD_DEL_2* ringCmdsDel2;         // commands: DEL_2
static CMD_DEL_1* ringCmdsDel1Array;    // commands: DEL_1_ARRAY
static CMD_DEL_2* ringCmdsDel2Array;    // commands: DEL_2_ARRAY
static CMD_ARRAY_INIT* ringCmdsArrayInit;//commands: array initialization
static CMD_CTOR_TEST* ringCmdsCtorTest; // commands: CTOR_TEST


static void* stateTableCmdAlloc(// ALLOCATE STATE-TABLE CMD
    carve_t allocation,         // - allocation
    void** hdr )                // - ring hdr
{
    CMD_BASE* cmd;

    cmd = RingCarveAlloc( allocation, hdr );
    cmd->emitted = FALSE;
    cmd->sym = NULL;
    return cmd;
}


static void* stateTableCmdAllocVar( // ALLOCATE STATE-TABLE CMD, SET VAR
    carve_t allocation,         // - allocation
    void** hdr,                 // - ring hdr
    target_size_t size )        // - size of command
{
    CMD_BASE* cmd;

    cmd = stateTableCmdAlloc( allocation, hdr );
    cmd->sym = CgVarRo( size, SC_STATIC, NULL );
    return cmd;
}


static SYMBOL stateTableCmdName(// CREATE COMDEF VARIABLE FOR DTOR_CMD
    unsigned index )            // - command index
{
    return CgVarRo( 1, SC_PUBLIC, CppNameStateTableCmd( index ) );
}


SYMBOL CgCmdFnExc(              // GET SYMBOL FOR FN-EXCEPTION SPEC. COMMAND
    SE* se )                    // - state entry in state table
{
    TYPE_SIG_ENT* sigs;         // - ring of signatures
    CMD_FN_EXC* cmd;            // - command

    sigs = BeTypeSigEntsCopy( se->fn_exc.sigs );
    cmd = stateTableCmdAllocVar
                    ( carveCMD_FN_EXC
                    , &ringCmdsFnExc
                    , 2 +
                      CgbkInfo.size_offset +
                      RingCount( sigs ) * CgbkInfo.size_data_ptr );
    cmd->sigs = sigs;
    return cmd->base.sym;
}


SYMBOL CgCmdTestFlag(           // GET SYMBOL FOR TEST_FLAG CMD TO BE GEN'ED
    SE* se )                    // - state entry in state table
{
    CMD_TEST_FLAG* cmd;         // - command for entry
    CMD_TEST_FLAG* curr;        // - current command
    STATE_VAR sv_true;          // - true state
    STATE_VAR sv_false;         // - false state

    cmd = NULL;
    sv_true  = SeStateVar( se->test_flag.se_true  );
    sv_false = SeStateVar( se->test_flag.se_false );
    RingIterBeg( ringCmdsTestFlag, curr ) {//{
        if(  se->test_flag.index == curr->index
          && sv_true             == curr->state_var_true
          && sv_false            == curr->state_var_false ) {
            cmd = curr;
            break;
        }
    } RingIterEnd( curr )
    if( cmd == NULL ) {
        cmd = stateTableCmdAllocVar( carveCMD_TEST_FLAG
                                   , &ringCmdsTestFlag
                                   , 2 + 3 * CgbkInfo.size_offset );
        cmd->index           = se->test_flag.index;
        cmd->state_var_true  = sv_true;
        cmd->state_var_false = sv_false;
    }
    return cmd->base.sym;
}


SYMBOL CgCmdSetSv(              // GET SYMBOL FOR SET_SV CMD TO BE GEN'ED
    SE* se )                    // - state entry in state table
{
    CMD_SET_SV* cmd;            // - command for entry
    CMD_SET_SV* curr;           // - current command
    STATE_VAR state;            // - state for set_sv

    cmd = NULL;
    state = SeStateVar( se->set_sv.se );
    RingIterBeg( ringCmdsSetSv, curr ) {
        if( state == curr->state_var ) {
            cmd = curr;
            break;
        }
    } RingIterEnd( curr )
    if( cmd == NULL ) {
        cmd = stateTableCmdAlloc( carveCMD_SET_SV, &ringCmdsSetSv );
        cmd->state_var = state;
        cmd->base.sym = stateTableCmdName( state + DTOR_CMD_INDEX_SETSV );
    }
    return cmd->base.sym;
}


// note: the code disabled does not work because it checks offset; it should
//       check the offset relative to the R/W block, because that it what
//       is generated ultimately.
//
// fix in future by computing the relative offset and using it
//
//
SYMBOL CgCmdComponent(          // GET SYMBOL FOR DTC_COMP... COMMAND
    SE* se )                    // - state entry in state table
{
    CMD_COMPONENT* cmd;         // - command

    DbgVerify( UNDEF_AREL != se->component.obj->offset
             , "CgCmdComponent -- no offset" );
    cmd = stateTableCmdAllocVar( carveCMD_COMPONENT
                               , &ringCmdsComponent
                               , 1 );
    cmd->obj = se->component.obj;
    cmd->dtor = se->component.dtor;
    cmd->offset = se->component.offset;
    cmd->cmd_type = se->base.se_type;
    return cmd->base.sym;
}


SYMBOL CgCmdArrayInit(          // GET SYMBOL FOR DTC_ARRAY_INIT COMMAND
    SE* se )                    // - state entry in state table
{
    CMD_ARRAY_INIT* cmd;        // - command

    DbgVerify( UNDEF_AREL != se->array_init.reg->offset
             , "cgAddCmdArrayInit -- no offset" );
    cmd = stateTableCmdAllocVar( carveCMD_ARRAY_INIT
                               , &ringCmdsArrayInit
                               , 1 );
    cmd->reg = se->array_init.reg;
    return cmd->base.sym;
}


SYMBOL CgCmdDel1(               // GET SYMBOL FOR DTC_DEL_1
    SE* se )                    // - state entry in state table
{
    CMD_DEL_1* cmd;             // - command for operation
    CMD_DEL_1* cur;             // - current command

    DbgVerify( UNDEF_AREL != se->del_1.offset
             , "CgCmdDel1 -- no offset for DLT_1" );
    cmd = NULL;
    RingIterBeg( ringCmdsDel1, cur ) {
        if( cur->op_del == se->del_1.op_del
         && cur->offset == se->del_1.offset ) {
            cmd = cur;
            break;
        }
    } RingIterEnd( cur )
    if( cmd == NULL ) {
        cmd = stateTableCmdAllocVar( carveCMD_DEL_1
                                   , &ringCmdsDel1
                                   , 1 );
        cmd->op_del = se->del_1.op_del;
        cmd->offset = CgOffsetRw( se->del_1.offset );
    }
    return cmd->base.sym;
}


SYMBOL CgCmdDel1Array(          // GET SYMBOL FOR DTC_DEL_1
    SE* se )                    // - state entry in state table
{
    CMD_DEL_1_ARRAY* cmd;       // - command for operation
    CMD_DEL_1_ARRAY* cur;       // - current command

    DbgVerify( UNDEF_AREL != se->del_1_array.offset
             , "CgCmdDel1 -- no offset for DLT_1" );
    cmd = NULL;
    RingIterBeg( ringCmdsDel1Array, cur ) {
        if( cur->op_del == se->del_1_array.op_del
         && cur->offset == se->del_1_array.offset ) {
            cmd = cur;
            break;
        }
    } RingIterEnd( cur )
    if( cmd == NULL ) {
        cmd = stateTableCmdAllocVar( carveCMD_DEL_1_ARRAY
                                   , &ringCmdsDel1Array
                                   , 1 );
        cmd->op_del = se->del_1_array.op_del;
        cmd->offset = CgOffsetRw( se->del_1_array.offset );
    }
    return cmd->base.sym;
}


SYMBOL CgCmdDel2(               // GET SYMBOL FOR DTC_DEL_2
    SE* se )                    // - state entry in state table
{
    CMD_DEL_2* cmd;             // - command for operation
    CMD_DEL_2* cur;             // - current command

    DbgVerify( UNDEF_AREL != se->del_2.offset
             , "CgCmdDel2 -- no offset for DLT_2" );
    cmd = NULL;
    RingIterBeg( ringCmdsDel2, cur ) {
        if( cur->op_del == se->del_2.op_del
         && cur->offset == se->del_2.offset
         && cur->size   == se->del_2.size ) {
            cmd = cur;
            break;
        }
    } RingIterEnd( cur )
    if( cmd == NULL ) {
        cmd = stateTableCmdAllocVar( carveCMD_DEL_2
                                   , &ringCmdsDel2
                                   , 1 );
        cmd->op_del = se->del_2.op_del;
        cmd->offset = CgOffsetRw( se->del_2.offset );
        cmd->size   = se->del_2.size;
    }
    return cmd->base.sym;
}


SYMBOL CgCmdDel2Array(          // GET SYMBOL FOR DTC_DEL_2
    SE* se )                    // - state entry in state table
{
    CMD_DEL_2_ARRAY* cmd;       // - command for operation
    CMD_DEL_2_ARRAY* cur;       // - current command

    DbgVerify( UNDEF_AREL != se->del_2_array.offset
             , "CgCmdDel2 -- no offset for DLT_2" );
    cmd = NULL;
    RingIterBeg( ringCmdsDel2Array, cur ) {
        if( cur->op_del == se->del_2_array.op_del
         && cur->offset == se->del_2_array.offset
         && cur->size   == se->del_2_array.size ) {
            cmd = cur;
            break;
        }
    } RingIterEnd( cur )
    if( cmd == NULL ) {
        cmd = stateTableCmdAllocVar( carveCMD_DEL_2_ARRAY
                                   , &ringCmdsDel2Array
                                   , 1 );
        cmd->op_del = se->del_2_array.op_del;
        cmd->offset = CgOffsetRw( se->del_2_array.offset );
        cmd->size   = se->del_2_array.size;
    }
    return cmd->base.sym;
}


SYMBOL CgCmdTry(                // GET SYMBOL FOR TRY BLOCK
    SE* se )                    // - state entry in state table
{
    TYPE_SIG_ENT* sigs;         // - ring of type signatures
    CMD_TRY* cmd;               // - command

    DbgVerify( UNDEF_AREL != se->try_blk.try_impl->offset_jmpbuf
             , "cgGenerateCmdsTry -- no offset for jmpbuf" );
    DbgVerify( UNDEF_AREL != se->try_blk.try_impl->offset_var
             , "cgGenerateCmdsTry -- no offset for var" );
    sigs = BeTypeSigEntsCopy( se->try_blk.sigs );
    cmd = stateTableCmdAllocVar
                    ( carveCMD_TRY
                    , &ringCmdsTry
                    , 2 + 2 +
                      3 * CgbkInfo.size_offset +
                      RingCount( sigs ) * CgbkInfo.size_data_ptr );
    cmd->state = SeStateVar( FstabPrevious( se ) );
    cmd->offset_var = CgOffsetRw( se->try_blk.try_impl->offset_var );
    cmd->offset_jmpbuf = CgOffsetRw( se->try_blk.try_impl->offset_jmpbuf );
    cmd->sigs = sigs;
    return cmd->base.sym;
}


SYMBOL CgCmdCtorTest(           // GET SYMBOL FOR CTOR-TEST COMMAND

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?