sslgen.c

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

C
589
字号
/****************************************************************************
*
*                            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:  Output generation routines for ssl.
*
****************************************************************************/


#include <stdio.h>
#include <stdlib.h>

#include "ssl.h"
#include "sslint.h"


instruction     *FirstIns;
instruction     *LastIns;

static instruction *NewIns( op_code op )
{
    instruction *ins;

    ins = malloc( sizeof( instruction ) );
    if( ins == NULL ) Error( "out of memory for instructions" );
    ins->ins = op;
    ins->flink = NULL;
    ins->blink = NULL;
    ins->ptr = NULL;
    ins->operand = 0;
    ins->location = NO_LOCATION;
    return( ins );
}

static void CheckLong( instruction *ins )
{
    if( (unsigned int)ins->operand != (unsigned char)ins->operand) {
        ins->ins |= INS_LONG; /* change to long form of instruction */
    }
}


static void AddStream( instruction *after, instruction *ins )
{
    if( after == LastIns ) {
        if( after != NULL ) after->flink = ins;
        ins->blink = after;
        ins->flink = NULL;
        LastIns = ins;
        if( FirstIns == NULL ) FirstIns = ins;
    } else if( after == NULL ) {
        ins->flink = FirstIns;
        ins->blink = NULL;
        FirstIns->blink = ins;
        FirstIns = ins;
        if( LastIns == NULL ) LastIns = ins;
    } else {
        ins->flink = after->flink;
        ins->blink = after;
        after->flink = ins;
        ins->flink->blink = ins;
    }
}


static void DelStream( instruction *ins )
{
    choice_entry        *tbl;
    choice_entry        *next;

    if( ins == FirstIns ) {
        FirstIns = ins->flink;
        if( FirstIns != NULL ) {
            FirstIns->blink = NULL;
        } else {
            LastIns = NULL;
        }
    } else if( ins == LastIns ) {
        LastIns = ins->blink;
        LastIns->flink = NULL;
    } else {
        ins->blink->flink = ins->flink;
        ins->flink->blink = ins->blink;
    }
    switch( ins->ins & INS_MASK ) {
    case INS_IN_CHOICE:
    case INS_CHOICE:
        for( tbl = ins->ptr; tbl != NULL; tbl = next ) {
            next = tbl->link;
            tbl->lbl->operand--; /* decrement label reference count */
            free( tbl );
        }
        break;
    case INS_JUMP:
    case INS_CALL:
        ((instruction *)ins->ptr)->operand--;
        break;
    }
}

instruction *GenNewLbl(void)
{
    return( NewIns( INS_LABEL ) );
}

void GenLabel( instruction *lbl )
{
    lbl->location = 0;
    AddStream( LastIns, lbl );
}

void GenExportLabel( instruction *lbl )
{
    GenLabel( lbl );
    lbl->operand++;     /* so it never gets deleted */
}

void GenInput( unsigned value )
{
    instruction *ins;

    ins = NewIns( INS_INPUT );
    ins->operand = value;
    CheckLong( ins );
    AddStream( LastIns, ins );
}

void GenInputAny( void )
{
    AddStream( LastIns, NewIns( INS_IN_ANY ) );
}

void GenOutput( unsigned value )
{
    instruction *ins;

    ins = NewIns( INS_OUTPUT );
    ins->operand = value;
    CheckLong( ins );
    AddStream( LastIns, ins );
}

void GenError( unsigned value )
{
    instruction *ins;

    ins = NewIns( INS_ERROR );
    ins->operand = value;
    CheckLong( ins );
    AddStream( LastIns, ins );
}

void GenJump( instruction *lbl )
{
    instruction *ins;

    ins = NewIns( INS_JUMP );
    ins->ptr = lbl;
    lbl->operand++;
    AddStream( LastIns, ins );
}

void GenReturn(void)
{
    AddStream( LastIns, NewIns( INS_RETURN ) );
}

void GenSetParm( unsigned value )
{
    instruction *ins;

    ins = NewIns( INS_SET_PARM );
    ins->operand = value;
    CheckLong( ins );
    AddStream( LastIns, ins );
}

void GenSetResult( unsigned value )
{
    instruction *ins;

    ins = NewIns( INS_SET_RESULT );
    ins->operand = value;
    CheckLong( ins );
    AddStream( LastIns, ins );
}

void GenLblCall( instruction *lbl )
{
    instruction *ins;

    ins = NewIns( INS_CALL );
    ins->ptr = lbl;
    lbl->operand++;
    AddStream( LastIns, ins );
}

void GenSemCall( unsigned num )
{
    instruction *ins;

    ins = NewIns( INS_SEMANTIC );
    ins->operand = num;
    CheckLong( ins );
    AddStream( LastIns, ins );
}

instruction *GenInpChoice(void)
{
    instruction *ins;

    ins = NewIns( INS_IN_CHOICE );
    AddStream( LastIns, ins );
    return( ins );
}

instruction *GenChoice(void)
{
    instruction *ins;

    ins = NewIns( INS_CHOICE );
    AddStream( LastIns, ins );
    return( ins );
}

void GenTblLabel( instruction *choice, instruction *lbl, unsigned value )
{
    choice_entry *new;
    choice_entry **owner;
    choice_entry *curr;

    new = malloc( sizeof( choice_entry ) );
    if( new == NULL ) Error( "no memory for choice entry" );
    lbl->operand++;
    new->value = value;
    if( (unsigned int)value != (unsigned char)value ) {
        choice->ins |= INS_LONG;
    }
    new->lbl = lbl;
    owner = &choice->ptr;
    for( ;; ) {
        curr = *owner;
        if( curr == NULL ) break;
        if( curr->value > value ) break;
        owner = &curr->link;
    }
    new->link = curr;
    *owner = new;
    choice->operand++;
}

void GenKill(void)
{
    instruction *ins;

    ins = NewIns( INS_KILL );
    ins->operand = SrcLine();
    CheckLong( ins );
    AddStream( LastIns, ins );
}


static char Optimize(void)
{
    char        change;
    instruction *ins;
    instruction *next;
    instruction *dest;
    char        dead_code;

    dead_code = 0; /* want to keep code at location 0 */
    change = 0;
    for( ins = FirstIns; ; ins = next ) {

⌨️ 快捷键说明

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