#ifndef GCICMN_HT
#define GCICMN_HT TRUE
/*=========================================================================
 * Copyright (C) VMware Inc. 1986-2011.  All Rights Reserved.
 *
 * Name - gcicmn.ht
 *
 * Description - Common definitions for the GemStone C interface,
 *               known as the GCI. This file contains definitions
 *               used by both gci.hf and gcirtl.hf
 *
 * $Id: gcicmn.ht,v 1.41 2008-01-09 22:51:03 stever Exp $
 *
 *========================================================================
 */

/*******  GemStone constants/types defined in this and other modules ********/
#include "flag.ht"

#if defined (FLG_MSWIN32)
// must include stdlib.h and malloc.h for call to free()
#include <stdlib.h>
#include <malloc.h>

// define export or import for C++ class definitions
#if defined(GCI_DLL)
// implementation of a gci.dll  should use dllexport .
#define CLS_EXPORT __declspec(dllexport)
#else
// Customer GCI code should  always take this definition
#define CLS_EXPORT __declspec(dllimport)
#endif

#else
// Unix
#define CLS_EXPORT
#endif


#include "gci.ht"      /* Constants and typedefs for GCI interface           */
#include "gcioop.ht"   /* Constants for the OOPs of reserved GS. kernel objs */
#include "gcioc.ht"    /* One based constants describing GS. kernel objs     */
#include "gcierr.ht"   /* Defines mnemonics for all GemStone errors          */
#include "version.ht"  /* version dependent default stone and netldi names */

/* no more includes. KEEP THIS LINE */

#ifdef FLG_MSC32
#ifdef GCI_DLL /* building GCI DLL */
#define EXTERN_GCI_DEC(EGDtype) extern __declspec(dllexport) EGDtype
#define EXTERN_GCI_VAR(EGDtype) extern __declspec(dllexport) EGDtype
#define DECL_GCI_VAR(EGDtype) __declspec(dllexport) EGDtype
#elif !defined(GCI_STATIC) /* using DLL */
#define EXTERN_GCI_DEC(EGDtype) __declspec(dllimport) EGDtype
#define EXTERN_GCI_VAR(EGDtype) __declspec(dllimport) EGDtype
#define DECL_GCI_VAR(EGDtype) __declspec(dllexport) EGDtype
#else
#define EXTERN_GCI_DEC(EGDtype) extern EGDtype
#define EXTERN_GCI_VAR(EGDtype) extern EGDtype
#define DECL_GCI_VAR(EGDtype)  extern EGDtype
#endif /* GCI_DLL */


#else /* everybody else , C++ */
#define EXTERN_GCI_DEC(EGDtype) EGDtype
#define EXTERN_GCI_VAR(EGDtype) EGDtype
#define DECL_GCI_VAR(EGDtype)  EGDtype
#endif

#if !defined(GLOBAL_HT)
#ifdef FLG_MSWIN32
typedef unsigned int     uintptr_t;
#endif
#endif

/*******  Macros defined in this module  ************************************/
/* =============================================================================
 * GCI_BOOL_TO_OOP macro
 *   Convert a C Boolean value to a GemStone Boolean object.
 *
 * Arguments:
 *   (1) The C Boolean value to be translated into a GemStone object.
 *
 * Result value:
 *   The OOP of the GemStone Boolean object that is equivalent to aBoolean.
 *   If argument is non-zero returns OOP_TRUE, otherwise returns OOP_FALSE.
 *==============================================================================
 */
#define GCI_BOOL_TO_OOP(aBoolean) ( ((aBoolean) != 0) ? OOP_TRUE : OOP_FALSE )

/* =============================================================================
 * GCI_CHR_TO_OOP macro
 *   Convert a 16 bit C character value to a GemStone Character object.
 *
 * Arguments:
 *   (1) The C character value to be translated into a GemStone object.
 *
 * Result value:
 *   The OOP of the GemStone Character object that is equivalent to aChar.
 *
 *  Note that character oops are not sequential integers
 *==============================================================================
 */
enum { CHAR16_MAX_VALUE = 0xFFFF };

enum { GCI_OOP_SPECIAL_VALUE_SHIFT = 8,
        // shift a char left by this before adding tag bits to
        //  convert from C char to Smalltalk Character oop

       GCI_OOP_SPECIAL_VALUE_MASK = 0xFF 
    };

#define GCI_CHR_TO_OOP(aChar) \
  ( ((OopType)((aChar) & CHAR16_MAX_VALUE) << GCI_OOP_SPECIAL_VALUE_SHIFT) | \
                    OOP_ASCII_NUL)

/*========================================================================
 *  GCI_JIS_CHAR_TO_OOP
 *
 * macro for converting a 16 bit JisCharacter value to an oop
 *========================================================================
 */

#define GCI_JIS_CHAR_TO_OOP(aChar) \
  ( ((OopType)((aChar) & CHAR16_MAX_VALUE) << GCI_OOP_SPECIAL_VALUE_SHIFT) | \
                    OOP_FIRST_JIS_CHAR)

/*========================================================================
 * GCI_OOP_IS_JIS_CHAR
 *
 * macro for testing whether an oop is a JisCharacter
 */
#define GCI_OOP_IS_JIS_CHAR(oop) ( ((OopType)(oop) & 0xFF ) == OOP_FIRST_JIS_CHAR )

/*========================================================================
 * GCI_OOP_TO_JIS_CHAR
 *   macro for conerting oop of a JisCharacter to a C integer
 *   returns -1 if argument is invalid
 */
static int GCI_OOP_TO_JIS_CHAR(OopType oop) {
  return GCI_OOP_IS_JIS_CHAR(oop) ? (int)(((oop) >> GCI_OOP_SPECIAL_VALUE_SHIFT) & CHAR16_MAX_VALUE) : -1 ;
}


/*========================================================================
   Gci Macros For testing oops
 *========================================================================
 */
/* =============================================================================
 * GCI_OOP_IS_SMALL_INT macro
 *   Determine whether or not a GemStone object represents a SmallInteger.
 *
 * Arguments:
 *   (1) The OOP of the object to test.
 *
 * Result value:
 *   A C Boolean value.  Returns TRUE if the object represents a SmallInteger,
 *   FALSE otherwise.
 *==============================================================================
 */
#define GCI_OOP_IS_SMALL_INT(oop) (((OopType)(oop) & OOP_TAG_SPECIAL_MASK) == OOP_TAG_SMALLINT)

/* =============================================================================
 * GCI_OOP_IS_BOOL macro
 *   Determine whether or not a GemStone object represents a Boolean value.
 *
 * Arguments:
 *   (1) The OOP of the object to test.
 *
 * Result value:
 *   A C Boolean value.  Returns TRUE if the object represents a Boolean, FALSE
 *   otherwise.
 *==============================================================================
 */
#define GCI_OOP_IS_BOOL(oop) ( ((OopType)(oop) & 0xFF) == OOP_FALSE )


static inline BoolType GCI_I64_IS_SMALL_INT(int64 arg)
{
  // Return TRUE if argument is within SmallInteger range .
  // A SmallInteger has a 61 bit 2-s complement integer and 3 tag bits.
  // For a positive int64 argument,
  //  top 4 bits must be 2r0000 for argument to be within SmallInteger range.
  // For a negative int64 argument,
  //  top 4 bits must be 2r1111 for argument to be within SmallInteger range.

  // This algorithm avoids loading large constants (expensive on Sparc)
  // and does only one compare .
  int shiftCount = 64 - (OOP_NUM_TAG_BITS + 1) ;
  int64 top4 = arg >> shiftCount;
  int64 sign4 = (top4 & 0xF0) >> 4;    // sign4 is either 0 or 0xF 
  return (top4 & 0xF) == sign4;
}

// ==================================================================
//  It was thought the following 3 would be an optimization on Sparc, 
//  where loading a large constant can be expensive, but the compiler
//  ignores these and does it's own 3-instruction sequence after
//  computing constants at compile time... 
//  So  GCI_int64_MAX generates same code as using LONG_MAX directly.

static inline int64 GCI_int64_MAX()
{
  // function result is 64bit LONG_MAX
  uint64 val = 0;
  val = ( ~ val) >> 1;
  return (int64)val ;
}

static inline uint64 GCI_uint64_MAX()
{
  // function result is 64bit ULONG_MAX
  uint64 val = 0;
  val =  ~ val ;
  return val ;
}

static inline int64 GCI_int64_MIN()
{
  // function result is 64bit LONG_MIN
  uint64 val = 1;
  val = val << 63;
  return (int64)val ;
}

/* =============================================================================
 * GCI_OOP_IS_SPECIAL
 *   Determine whether or not a GemStone object has a special representation.
 *
 * Arguments:
 *   (1) The OOP of the object to test.
 *
 * Result value:
 *   A C Boolean value.  Returns TRUE if the object has a special
 *   representation, FALSE otherwise.
 *==============================================================================
 */

#define GCI_OOP_IS_SPECIAL(oop) (((OopType)(oop) & OOP_TAG_SPECIAL_MASK) != 0)

/*========================================================================
 *  Gci Macros for converting Oops to C types.  These macros will run
 *  faster than the equivalent functions.  If the argument is out of range for
 *  the result type, the equivalent function is called to generate an error
 *
 *  WARNING - do not use a function call as the expression for the argument,
 *   or you will pay the penalty of executing the function twice.
 *========================================================================
 */

/* =============================================================================
 * GCI_OOP_TO_BOOL
 *   Convert a Boolean object to a C Boolean value.
 *
 * Arguments:
 *   (1) The OOP of the Boolean object to be translated into a C Boolean value.
 *
 * Result value:
 *   A C Boolean value.  Returns the C Boolean value that corresponds to the
 *   GemStone object.  In case of error, this macro returns FALSE.
 *==============================================================================
 */
#define GCI_OOP_TO_BOOL(oop)  GciOopToBool(oop)

/* =============================================================================
 * GCI_OOP_IS_CHAR macro
 *
 * Return TRUE if the argument is an instance of Character , false otherwise .
 * =============================================================================
 */
#define GCI_OOP_IS_CHAR(oop) (((OopType)(oop) & 0xFF ) == OOP_ASCII_NUL )

/* =============================================================================
 * GCI_OOP_TO_CHR macro
 *   Convert a Character object to a 8 bit  C character
 *
 * Arguments:
 *   (1) The OOP of the Character object to be translated into a C character
 *
 * Result value:
 *   A C char.   Generates an error if the argument is not an instance of
 *   Character, or is an instance outside of the range of a C char .
 *==============================================================================
 */
#define GCI_OOP_TO_CHR(oop) (GciOopToChr(oop))

/* =============================================================================
 * GCI_OOP_TO_CHAR16 macro
 *   Convert a Character object to a 16 bit  C character
 *
 * Arguments:
 *   (1) The OOP of the Character object to be translated into a C character
 *
 * Result value:
 *   A C unsigned int .
 *==============================================================================
 */
#define GCI_OOP_TO_CHAR16(oop) GciOopToChar16(oop)

/* =======================================================================
 *  GciStoreBytes
 *
 *  Stores bytes into an object which must have byte format.
 *  Will generate an error if a store is attempted into an instance of
 *  Float or SmallFloat.
 *=======================================================================
 */
#define GciStoreBytes(theObject, startIndex, theBytes, numBytes) \
  GciStoreBytesInstanceOf(OOP_NIL, theObject, startIndex, theBytes, numBytes)


// GciPushErrorHandle macro deleted, use  GciPushErrJump instead

/* ----------------------- gcifloat definitions ------------------------- */

/*=========================================================================
 *  byte-order dependent macros and constants 
 *
 *  GCI_FLOAT_TOP - access the most significant word of a C double
 *  GCI_FLOAT_BOTTOM - access the least significant word of a C double.
 * 
 *  macros to be applied to the result of GCI_FLOAT_TOP
 *    GCI_FLOAT_NEG_BIT - return TRUE if the negative bit is set
 *    GCI_FLOAT_MSB_SET - return TRUE if most significant bit of mantissa is set
 *    GCI_FLOAT_EXPONENT_ZERO - return TRUE if the exponent is zero
 *    GCI_FLOAT_EXCEPTIONAL - return TRUE if double is either NaN or Infinity
 * 
 *  GCI_SMALLFLOAT_EXCEPTIONAL -return TRUE if float is either NaN or Infinity 
 *
 */
#if defined(FLG_IEEE_LITTLE) /* ------------------------------------ */

#define GCI_FLOAT_TOP(x) (((unsigned int *)(&x))[1])
#define GCI_FLOAT_BOTTOM(x) (((unsigned int *)(&x))[0])

/* apply the following four to the top word */
#define GCI_FLOAT_NEG_BIT(x) (((x) & 0x80000000) != 0)
#define GCI_FLOAT_MSB_SET(x) (((x) & 0x00080000) != 0)
#define GCI_FLOAT_EXPONENT_ZERO(x) (((x) & 0x7ff00000) == 0)
#define GCI_FLOAT_EXCEPTIONAL(x) ((((x) & 0x7ff00000) == 0x7ff00000))

#define GCI_SMALLFLOAT_EXCEPTIONAL(x) ((((x) & 0x7f800000) == 0x7f800000))

#elif defined(FLG_IEEE_BIG) /* ------------------------------------ */

#define GCI_FLOAT_TOP(x) (((unsigned int *)(&x))[0])
#define GCI_FLOAT_BOTTOM(x) (((unsigned int *)(&x))[1])

/* apply the following four to the top word */
#define GCI_FLOAT_NEG_BIT(x) (((x) & 0x80000000) != 0)
#define GCI_FLOAT_MSB_SET(x) (((x) & 0x00080000) != 0)
#define GCI_FLOAT_EXPONENT_ZERO(x) (((x) & 0x7ff00000) == 0)
#define GCI_FLOAT_EXCEPTIONAL(x) ((((x) & 0x7ff00000) == 0x7ff00000))

#define GCI_SMALLFLOAT_EXCEPTIONAL(x) ((((x) & 0x7f800000) == 0x7f800000))

/* endif FLG_IEEE_BIG */
#else /* ------------------------------------ */
+++ PORT_ERR, neither FLG_IEEE_LITTLE nor FLG_IEEE_BIG defined.  What is this?
#endif /* FLG_IEEE_BIG or FLG_IEEE_LITTLE */

// Float swizzling macros deleted , see inline functions in gcifloat.hf

/* The following macros are for compatibility with the 4.1 gcifloat.hf */
#define GCI_plusInfinity  GciFloatPlusInfinityVal()
#define GCI_minusInfinity GciFloatMinusInfinityVal()
#define GCI_plusQuietNan  GciFloatPlusQuietNanVal()
#define GCI_minusQuietNan GciFloatMinusQuietNanVal()
#define GCI_plusSignalingNan  GciFloatPlusSignalingNanVal()
#define GCI_minusSignalingNan GciFloatMinusSignalingNanVal()

/* bits in flags argument to GciPerformNoDebug. 
 * comments duplicated in gci.hf 
 */
enum { 
  GCI_PERFORM_FLAG_ENABLE_DEBUG = 1,  
   /* make like GciPerform() with respect to debugging. default is debugger is
    * disabled until GciPerformNoDebug returns */

  GCI_PERFORM_FLAG_DISABLE_ASYNC_EVENTS = 2  ,
   /* disable async events.  Used for GSI to be able to execute an exception
    * block or method to service RT_ERR_SIGNAL_ABORT, 
    *  RT_ERR_SIGNAL_GEMSTONE_SESSION, or ABORT_ERR_LOST_OT_ROOT */

  GCI_PERFORM_FLAG_SINGLE_STEP = 4, 
   /* place a single step break-point at the start of the method to be
    * performed, and then execute to hit that breakpoint.
    */

  GCI_PERFORM_MAP_SYMBOLS = 8 ,
   /* THIS OPTION NOT SUPPORTED
    *
    * If this bit is set map the perform's receiver and arg oops will
    * be mapped to the canonical symbol they represent before the
    * action perform is done.
    */

  GCI_PERFORM_RESULT_INTO_REFSET = 0x10  /* for internal use only,
    * add result oop to the ReferencedSet, not the PureExportSet  .
    * Used in implementation of GciStoreTravDoTravRefs.
    */
 };

// =============================================================================
// Traversal buffer type

enum { GCI_MIN_TRAV_BUFF_SIZE = 2048 };

class CLS_EXPORT GciTravBufType 
{
 public:
   int64 allocatedBytes; // allocated size of the body
   int64 usedBytes;  // used bytes of the body
   ByteType body[8];
	// actual body size is variable, minimum of GCI_MIN_TRAV_BUFF_SIZE

   inline GciObjRepSType* firstReport() { 
     return (GciObjRepSType*)body;
   }

   inline GciObjRepSType* readLimit() {
      // for use when reading object reports out of a buffer
      // returns pointer past end of last object report in the buffer
      return (GciObjRepSType*)(body + usedBytes);
   }

   inline GciObjRepSType* writeLimit() {
      // for use when composing a buffer
      // returns pointer one byte past end of the allocated buffer
      return (GciObjRepSType*)(body + allocatedBytes);
   }

   inline GciObjRepHdrSType* firstReportHdr() {
      return &firstReport()->hdr;
   }
   inline GciObjRepHdrSType* readLimitHdr() {
      return &readLimit()->hdr;
   }
   inline GciObjRepHdrSType* writeLimitHdr() {
      return &writeLimit()->hdr ;
   }

   GciTravBufType(size_t allocationSize);
     // do not use this constructor, use malloc() instead
 
   static GciTravBufType* malloc(size_t allocationSize, int lineNum = -1,
				 const char* fileName = NULL);
     // returns an instance obtained from ::malloc
     // initialized with allocatedBytes equal to allocationSize,
     //  and usedBytes == 0;  returns NULL if malloc fails.
     // if allocationSize is not a multiple of 8 bytes, allocatedBytes will be
     //  equal to allocationSize rounded up to the next multiple of 8 bytes.
     // lineNum and fileName are optional args for use by the implementation
     //  of GciCHeapCheck .

   void free();
     // releases an instance 
};

class CLS_EXPORT GciTravBufHolder {
  // for use in allocated traversal buffers whose lifetime is
  // confined to the life of a C function call. 
 public:
   GciTravBufType *buf;

  GciTravBufHolder(size_t allocationSize);
    // allocates GciTravBufType on the C heap with:
    //   buf = GciTravBufType::malloc(allocationSize);

  GciTravBufHolder(GciTravBufType *aBuffer);
    // constructor that accepts a previously allocated buffer
  
  ~ GciTravBufHolder();
    // releases the GciTravBufType with:
    //   buf->free();  buf = NULL;
};

/* =============================================================================
 * GCI_TRAVBUFF_SIZE 
 *   Returns a int64 that is the number of bytes in a traversal buffer.
 *
 *   (1) A pointer to a traversal buffer
 *
 * Result value:
 *   A  that is the number of bytes in travFuffPtr.
 *==============================================================================
 */
static inline int64 GCI_TRAVBUFF_SIZE(GciTravBufType* buf)
{
  return buf->usedBytes;
}


/* =============================================================================
 * GCI_FIRST_OBJREP 
 *   Returns a pointer to the first object report in a traversal buffer:
 *
 *   (1) A pointer to a traversal buffer
 *
 * Precondition:
 *   The traversal buffer must contain at least one report.
 *
 * Result value:
 *   A GciObjRepSType* to the first object report.
 *==============================================================================
 */
static inline GciObjRepSType* GCI_FIRST_OBJREP(GciTravBufType* buf)
{
  return buf->firstReport();
}
 
/* =============================================================================
 * GCI_AFTER_LAST_OBJREP 
 *   Returns a pointer just past the last object report in a traversal buffer:
 *
 *   (1) A pointer to a traversal buffer
 *
 * Precondition:
 *   The traversal buffer must contain at least one report.
 *   This is for use when reading reports out of a buffer, not when composing
 *   a buffer.
 *
 * Result value:
 *   A GciObjRepSType* to just past the last object report.
 *==============================================================================
 */
static inline GciObjRepSType* GCI_AFTER_LAST_OBJREP(GciTravBufType* buf)
{
  return buf->readLimit();
}

/* =============================================================================
 * GCI_NEXT_OBJREP 
 *   Returns a pointer to the next object report.
 *
 *   (1) A pointer to a object report (GciObjRepSType*).
 *
 * Precondition:
 *   The argument should not point past the last report in a traversal buffer.
 *   Use GCI_AFTER_LAST_OBJREP to get a limit pointer
 *   use it as a sentinal to make sure you do not go to far.
 *
 * Result value:
 *   A GciObjRepSType* to the next object report.
 *==============================================================================
 */
static inline GciObjRepSType* GCI_NEXT_OBJREP(const GciObjRepSType *rpt)
{
  return rpt->nextReport();
}

/* ==========================================================================*/
/* arguments to various traversal functions */

/* bits in retrievalFlags in GciClampedTravArgsSType */
enum { GCI_RETRIEVE_DEFAULT = 0,
       GCI_RETRIEVE_EXPORT = 1, /* causes results to automatically be added 
                                * to an export set using GciSaveObjs semantics*/
       GCI_CLEAR_EXPORT = 2, /* Causes traverse to clear the export set
                                * using GciReleaseAllOops before filling the
                                * traversal buffer . */
       GCI_COMPRESS_TRAV = 4, /* compress traversal buffer before transmission
                                * from gem to an rpc gci client, and decompress
                                * in the client. The flag controls subsequent
                                * GciMoreTraversal calls also. */
       GCI_NOKILL_TRAV = 8, /* start a traversal that will allow GCI message 
                            * sends, executes and store operations to preceed
                            * GciMoreTraversal calls that are part of this
                            * traversal.  Only the start of some other traversal
                            * will kill this traversal. */

  // following flags are intended for use by the implementation of
  //   GciStoreTravDoTravRefs and should not be used in application code
       GCI_TRAV_WITH_REF_SET = 0x10, /* if true, use GciStoreTravDoTravRefs 
            semantics */

       /* the GciStoreTravDoTravRefs function will automatically set
        * the GCI_TRAV_WITH_REF_SET bit as needed during execution.
        * The state of those bits at the end of a GciStoreTravDoTravRefs call 
        * is undefined. 
        * The GciStoreTravDoTravRefs will ignore bits GCI_RETRIEVE_EXPORT, 
	*  GCI_CLEAR_EXPORT
        */

       GCI_TRAV_HAVE_ALTERED_OBJS = 0x20,    /* for internal use only*/

       GCI_TRAV_REFS_EXCLUDE_RESULT_OBJ = 0x80  /* exclude execution result
        * from the traversal result */
  };

#define GCI_CLEAR_AND_EXPORT (GCI_RETRIEVE_EXPORT|GCI_CLEAR_EXPORT)

class CLS_EXPORT GciClampedTravArgsSType {
 public:
  OopType clampSpec;
  OopType resultOop; /* Result of GciPerformTrav/GciExecuteStrTrav */
  GciTravBufType *travBuff;
  int level;
  int retrievalFlags;
  BoolType isRpc; /* private, for use by implementation of GCI */
};

typedef struct {
  int64 startIndex;
  int64 bufSize;
  int64 numReturned; /* output */
  GciObjInfoSType *info; 
  ByteType *buffer;      
  int retrievalFlags;
  BoolType isRpc; /* private, for use by implementation of GCI */
  }  GciFetchObjInfoArgsSType;

/* ==========================================================================*/

enum { GCI_SECONDS_PER_DAY = 86400  };  /* conversion constant */

/* Note: In GemStone versions earlier than 5.1, the DateTime struct had only
 * three fields; in 5.1, timeZone has been added. timeZone represents
 * the time zone of the region in which the DateTime was created/is being 
 * created. If the timeZone field is OOP_NIL, GemStone replaces it with
 * the session's current time zone. (Each session can have a different time 
 * zone).
 * 
 * In 5.1, time is represented in millisecond granularity; in the earlier 
 * versions, it was second granularity. 
 */
typedef struct {      /* C representation in GMT of instance of class 
                       * DateTime */
   int year;         /* 1901 <= year <= 1000000. Value is the actual year */
   int dayOfYear;    /* 1..366 (366 used for a leap year) */
   int milliseconds; /* since midnight */
   OopType timeZone;  /* oop of the time zone */
   } GciDateTimeSType;

/* ===============================================================
 *  GciStoreTravDoArgsSType used by GCI StoreTravDo  functions
 */
class CLS_EXPORT GciStoreTravDoArgsSType {
 public:
  GciTravBufType *storeTravBuff;
  int          storeTravFlags;   /* GCI_STORE_TRAV* bits from gci.ht */

  int      doPerform; // if 1 then do Perform else do ExecuteStr 
     // for StoreTravDoTravRefs 0 == ExecuteStr, 1 == Perform 2 == ExecuteBlock
     //     3 == no execution , 4 == GciContinueWith  .
     //      if ((retrievalFlags & GCI_TRAV_REFS_EXCLUDE_RESULT_OBJ) == 0) 
     //        use u.perform.receiver as the 
     //        object to traverse after traversing altered objects,
     //      else ignore u.perform.receiver 
                       
  int          doFlags;  /* per GciPerformNoDebug */
  union {
    struct { /* args for a GciPerformNoDebug call */
      OopType        receiver;
      const char*    selector;
      const OopType* args;
      int  numArgs;
    } perform;
    struct { // args for ExecuteStr or ExecuteBlock 
      const char*    source;  // size not defined by null termination
      int64  sourceSize;
      OopType        sourceClass;
      OopType        contextObject;
      OopType        symbolList;
    } executestr;
    struct {  // args for GciContinueWith 
      OopType process;
      OopType replaceTopOfStack;
      // also uses doFlags above
      // GciErrSType *error input of GciContinueWith() always NULL
    } continueArgs ;
  } u;
  OopType*      alteredTheOops;   /* output */
  int alteredNumOops;   /* input/output */
  BoolType      alteredCompleted; /* output */

  // following are logically part of executestr , but
  //   at end of struct for upwards compatibility with older GBS releases
  const OopType* execBlock_args;  // ignored unless ExecuteBlock
  int  execBlock_numArgs;	    // ignored unless ExecuteBlock

  //  For ExecuteBlock variant of GciStoreTravDoArgsSType as used with
  //     GciStoreTravDoTravRefs ,
  //  Given the argument  
  //     GciStoreTravDoArgsSType *args;
  //  Then for ExecuteBlock variant we expect :
  //    args->doPerform == 2
  //    args->executestr.source, args->executestr.sourceSize 
  //     define the source for an anonomous method, which returns a Block
  //     "[:arg1 :arg2 | | t1 t2 |  .... ]"
  //
  //    args->executestr.sourceClass, args->executestr.contextObject, 
  //    args->executestr.symbolList 
  //       have the same semantics as for ExecuteStr
  //
  //    args->args , args->numArgs 
  //      must match the number of arguments to the Block.
  //
  //  The virtual machine will compile the anonomous method, execute it to
  //  get the Block, and then send  valueWithArguments: to the Block.

};




/**************************** Private GCI stuff ****************************/
typedef BoolType GciServerInfoFType(const char *name,
				    const char *machine,
				    BoolType exists,
				    const char* kind,
				    int port,
				    int pid,
				    const char* startDate,
				    const char* starter,
				    const char* version,
				    const char* logName,
				    const char* productDir,
				    const char* cmdLine,
				    const char* configFile1,
				    const char* configFile2);


typedef void GciHelpWriteLineFType(const char *str);

typedef void GciHelpReadLineFType(char * str, int maxSize);

typedef void GciKbIntFType(void);

typedef void GciFaultFuncType(void);

typedef void GciErrMsgPrintFType(const char* msg);

typedef void GciErrMsgObjPrintFType(GciErrMsgPrintFType *printer, OopType o);


#endif /* GCICMN_HT */
