/*++ Copyright (c) 1991 Microsoft Corporation Module Name: mops.h Abstract: The MOPs (Marshalling OPcodes) interpreter is accepting marshalling opcodes and arguments to marshall, and it performs the marshalling (and unmarshalling) of RPC arguments. For a well suited subset of MIDL, stubs can call the interpreter, rather then perform in-line marshalling; which will result in significantly smaller stubs. Author: Dov Harel (DovH) 24-Feb-1991 Modifications: 1) Removed MOP_BOOL from Mopcode enumeration. Objective: Simplify and shrink Mopcode set. Result: Obvious. brucemc 2/5/93. 2) Reindexed first 32 opcodes to have values 0x00 to 0x1f. Objective: Force opcodes representing all basic data types, structures, unions and basic associated constructs to fit into the lower 6 bits of a byte, freeing the top two bits for use in keeping alignment information. This is not a win for basic C types (char, int, ...) when passed, but may be a win for these types when passed as a structure. Result: UNCLEAR (2/5/93). brucemc 2/5/93. --*/ #ifndef __MOPS_H__ #define __MOPS_H__ #include typedef unsigned char MOP_CODE; typedef unsigned char * MOP_STREAM; //.. Array pointer flavors #define MOP_UNIQUE 200 #define MOP_FULL 201 // // Basic OpCode type: (Moved from rpcmopi.h) // typedef unsigned char MOP; // // Currently implemented: Declarative style Marshalling Opcodes // (Mops) also referred to as "Smart" marshalling Op Codes. // For instance: base type opcodes do not embody any alignment // knowledge of the either the data to be [un]marshalled, or // buffer alignment. For example: MOP_SHORT marshalling is short // for: // // o If not sure about alignment then align buffer // pointer to 0 mod 2. // // o Marshall an aligned "short". // // An alternative option (more functional style, or "dumb" marshalling // opcodes, is given at the end of the file. In the alternative style // we have opcodes such as: // // MOP_ALIGN_0MOD2 -- Align buffer pointer to 0 mod 2, // MOP_ALIGNED_SHORT -- Arshall a short given aligned buffer pointer. // // // The decision to go with the more declarative style (which is also more // expressive) is based on the following observations: // // o The hard part of interpretation is dealing with the more // complex types. Using declarative makes interpretation // of complex types easier. Moreover: it reduces the cases // the interpreter has to consider, thus enable a smaller interpreter. // // o We may want to expose the interpreter to users in the future. // We can even allow a variable type argument declaration in the IDL. // Stub will determine the binding, and other low level details // such as initializing the message structure. The user then calls // the interpreter via an entry point vector, supplying his own // marshalling opcodes. // // // The following opcodes are basically essential for describing // more complex (compound) types. // // // Zero is the MOP terminator value. Alows the use of 0-terminated strings // in the as MOP streams by the interpreter. Mop streams serve as descriptors // of procedure argument lists and of compound types. // // OPCODE LAYOUT // Opcodes can be partitioned into two kinds: type opcodes, including aggregate // types and type attributes. // Since the opcodes for the types will function as the determinants in switch statements, // it will help the compiler if these are dense. Therefore, the opcodes will // be laid out to have the type opcodes first, and the attribute opcodes after. // // Reserved opcode // #define MOP_END_ARGLIST (unsigned char)0X00 // // MARSHALLING OPCODES FOR BASE TYPES: // // // Reserved (unsigned char)0X00 // #define MOP_BYTE (unsigned char)0X01 #define MOP_SMALL (unsigned char)0X02 #define MOP_CHAR (unsigned char)0X03 #define MOP_SHORT (unsigned char)0X04 #define MOP_LONG (unsigned char)0X05 #define MOP_FLOAT (unsigned char)0X06 #define MOP_DOUBLE (unsigned char)0X07 #define MOP_HYPER (unsigned char)0X08 // // MARSHALLING OPCODES FOR COMPOUND TYPES: // // STRUCTS: // // Compound types: (required for nesting of compound types inside other // compound types / arrays. // // Struct and union descriptors follows the following rules: // // 1. Structures have two alignment requirements: in memory and on wire. // The on wire requirements are either 4 or 8. // The in memory requirements are determined by structure packing at // compile time. // Recall that a compound type will be represented in the opcode stream // as follows: // ...|compound_type_begin|||... // // The alignment information can be placed in the upper two bits of // an opcode. // // The on wire requirements will be kept in the compound type opcode. // The in memory requirements will be kept in the opcodes of each field. // // Note that the size of the structure is kept in another table. // // // MOP_BEGIN_SIMPLE_STRUCT designates the starting point for a limited // struct descriptor. A simple struct is a sequence of base types. // A simple struct can contain *AT MOST ONE* pointer! // // Some simple structs can be block copied. This can be determined at compile // time, and the following bit it set accordingly. // MOP_BEGIN_STRUCT designates the starting point for a general // struct descriptor. General structs have no hard limit on // the number (or type) of pointers they may contain. // // WARNING: changing these will force changes in alignment macros! // See GET_IN_MEMORY_REQUIREMENTS() in mopmac.h // #define MOP_BEGIN_STRUCT (unsigned char)0X09 #define MOP_BEGIN_STRUCT_ALGN2 (unsigned char)0X0A #define MOP_BEGIN_STRUCT_ALGN4 (unsigned char)0X0B #define MOP_BEGIN_STRUCT_ALGN8 (unsigned char)0X0C // MOP_BEGIN_CONF_STRUCT_* designates the outermost structure // which contains a conformant array. // #define MOP_BEGIN_CONF_STRUCT (unsigned char)0X0D #define MOP_BEGIN_CONF_STRUCT_ALGN2 (unsigned char)0X0E #define MOP_BEGIN_CONF_STRUCT_ALGN4 (unsigned char)0X0F #define MOP_BEGIN_CONF_STRUCT_ALGN8 (unsigned char)0X10 #define MOP_BEGIN_SIMPLE_STRUCT (unsigned char)0X11 #define MOP_END_COMPOUND_TYPE (unsigned char)0X12 // // UNIONS: // // Union descriptors follow the following conventions: // // 1. The byte following the 3 byte union descriptor contains the offset // of the MOP_END_COMPOUND_TYPE in the Mops stream, relative to // the address of the MOP_BEGIN_UNION opcode. // // 2. The next byte contains the discriminator type for the union. // For simplicity, assume discriminators are 7 bit positive byte // values for now. // // 3. The next section of the Mops stream contains a list of // byte pairs, such that: // // o The component is the actual discriminator // value for a branch (or an index into a discriminator table; // table spec - TBD) // // o The component is the offset in the Mops stream // (relative to the beginning of the union descriptor) of the // Mops descriptor for thr corresponding branch. // // The list is terminated by a // MOP_END_SWITCH_LIST. // // 4. A union branch is represented by a MOP_UNION_BRANCH // The next two bytes in the byte stream descriptor of a union // branch contain the alignment, and size values for the branch // respectively. // #define MOP_BEGIN_UNION (unsigned char)0X13 #define MOP_BEGIN_UNION_ALGN2 (unsigned char)0X14 #define MOP_BEGIN_UNION_ALGN4 (unsigned char)0X15 #define MOP_BEGIN_UNION_ALGN8 (unsigned char)0X16 #define MOP_BEGIN_UNION_ND (unsigned char)0X17 #define MOP_BEGIN_UNION_ND_ALGN2 (unsigned char)0X18 #define MOP_BEGIN_UNION_ND_ALGN4 (unsigned char)0X19 #define MOP_BEGIN_UNION_ND_ALGN8 (unsigned char)0X1A #define MOP_BEGIN_ENCAP_UNION (unsigned char)0X1B #define MOP_BEGIN_ENCAP_UNION_ALGN2 (unsigned char)0X1C #define MOP_BEGIN_ENCAP_UNION_ALGN4 (unsigned char)0X1D #define MOP_BEGIN_ENCAP_UNION_ALGN8 (unsigned char)0X1E #define MOP_BEGIN_ENCAP_UNION_ND (unsigned char)0X1F #define MOP_BEGIN_ENCAP_UNION_ND_ALGN2 (unsigned char)0X20 #define MOP_BEGIN_ENCAP_UNION_ND_ALGN4 (unsigned char)0X21 #define MOP_BEGIN_ENCAP_UNION_ND_ALGN8 (unsigned char)0X22 // // MOP_END_SWITCH_LIST designates the end of the // list. // // // MOP_UNION_BRANCH designates a runtime check point for // the offset to branch Mops. A union branch *must* start with a // MOP_UNION_BRANCH opcode. // #define MOP_UNION_BRANCH (unsigned char)0X23 // // MARSHALLING OPCODES FOR POINTERS: // // // Pointer Opcodes determine: // // o the type of pointer to be marshalled // o its directional attributes (for pointer arguments) // o its [de]allocation method // // Note: By default all parameters ar [in] parameters, (including pointers). // Pointers are [unique] by default, are not persistent, and pointees // are allocated on a node-by-node basis. // // // For parameters: MOP_POINTER is an [in, unique] pointer; // otherwise, a [unique] pointer. // // PARAMETER LISTS ONLY: // // MOP_[OUT | IN_OUT]_POINTER designates an [in] or [in, out] // [unique] pointer parameter, respectively. // #define MOP_POINTER (unsigned char)0X24 #define MOP_OUT_POINTER (unsigned char)0X25 #define MOP_IN_OUT_POINTER (unsigned char)0X26 // // For parameters: MOP_REF_POINTER is an [in, ref] pointer; // otherwise, a [ref] pointer. // // PARAMETER LISTS ONLY: // // MOP_[OUT | IN_OUT]_REF_POINTER designates an [in] or [in, out] // [ref] pointer parameter, respectively. // #define MOP_REF_POINTER (unsigned char)0X27 #define MOP_OUT_REF_POINTER (unsigned char)0X28 #define MOP_IN_OUT_REF_POINTER (unsigned char)0X29 // Full pointers follow same convention. // #define MOP_FULL_POINTER (unsigned char)0X2A #define MOP_OUT_FULL_POINTER (unsigned char)0X2B #define MOP_IN_OUT_FULL_POINTER (unsigned char)0X2C // >>>>Pointersto explicit types // // MOP_PSHORT specifies a pointer to short or short size/index/length // specifier // #define MOP_PSHORT (unsigned char)0X2D // MOP_PLONG specifies a pointer to long or long size/index/length specifier // #define MOP_PLONG (unsigned char)0X2E // MOP_PSTRUCT_ALGN? specifies a pointer to a structure aligned at Zp?. // #define MOP_PSTRUCT (unsigned char)0X2F #define MOP_PSTRUCT_ALGN2 (unsigned char)0X30 #define MOP_PSTRUCT_ALGN4 (unsigned char)0X31 #define MOP_PSTRUCT_ALGN8 (unsigned char)0X32 #define MOP_PSTRUCT_SIMPLE (unsigned char)0X33 // // MARSHALLING OPCODES FOR ARRAYS: // // // MOP_ARRAY designates a conformant or varrying array. The size, // first index, length, and element type of the array are determined // by the subsequent opcodes. In the first implementation only // conformant arrays will be supported (ie. the array size must // be specified by another parameter, for an array parameter, or by // another field of the struct for (pointers to) nested arrays. // // In a parameter list MOP_ARRAY represents an [in] array parameter. // In a nested struct, MOP_ARRAY represents a nested array. // // // For parameters: MOP_ARRAY is an [in] array; // otherwise, a nested array. // // PARAMETER LISTS ONLY: // // MOP_[OUT | IN_OUT]_ARRAY designates an [in] or [in, out] // array parameter, respectively. // #define MOP_ARRAY (unsigned char)0X34 #define MOP_OUT_ARRAY (unsigned char)0X35 #define MOP_IN_OUT_ARRAY (unsigned char)0X36 // // MOP_RETURN_VALUE indicates that the following opcode is the // Mop type for the return value of a function. Currently the only // supported types for a return type are base types. // #define MOP_RETURN_VALUE (unsigned char)0X37 // TYPE ATTRIBUTES // // >>>>Compound type attributes. // // Block copy attribute. // #define STRUCT_BLOCK_COPY (unsigned char)0x38 // // >>>>Array attributes. // // ARRAY SIZE SPECIFIERS: // // MOP_SIZE_IS: Following opcodes give an offset from the beginning // of the containing objet, to the object containing the size of the // array. The opcode(s) immedialely following give the type of the // size specifier for the array. The type specification for the // size is immediately followed by the offset from the beginning of the // containing object to the size specifier. Offsets is given in number // of bytes. // // The size specification conventions are as follows: // // o For array parameters the containing object is the stack frame // of the called procedure. The offset is from the beginning of // the stack frame, to the parameter giving the size of the array. // // o For (pointers to) nested arrays, the offset is from the beginning // of the containing struct. // // Note: mop_size_is and mop_length_is may also follow a pointer, // designating a pointer to a contiguous storage, which is allocated // at runtime and treated as an array. Also, note that we don't need // a MOP_LAST_IS, since it's enough to specify MOP_LENGTH_IS and // MOP_FIRST_IS. Moreover, it's important that the _CONST attributes // are of even index. // #define MOP_SIZE_IS (unsigned char)0X39 #define MOP_SIZE_CONST (unsigned char)0X3A #define MOP_MAX_IS (unsigned char)0X3B #define MOP_MAX_CONST (unsigned char)0X3C #define MOP_MIN_IS (unsigned char)0X3D #define MOP_MIN_CONST (unsigned char)0X3E // // MOP_FIRST_IS: Similar to MOP_SIZE_IS. The next opcode (or two opcodes // for "pointed to" first index specifier) give the index type. // The following byte is the offset to the object specifying the first // index of a member to be transmitted. The offset is from the beginning // of the containing object. // #define MOP_FIRST_IS (unsigned char)0X3F #define MOP_FIRST_CONST (unsigned char)0X40 #define MOP_LAST_IS (unsigned char)0X41 #define MOP_LAST_CONST (unsigned char)0X42 // // MOP_LENGTH_IS: Similar to MOP_FIRST_IS and MOP_SIZE_IS. The next opcode // (or two for "pointed to" length specifier) specifies the type of the // length specifier (parameter or struct member) for the array. // The following byte in the Mops stream is the offset to the object // specifying the array length (number of members to transmit) from the // beginning of the containing object. // #define MOP_LENGTH_IS (unsigned char)0X43 #define MOP_LENGTH_CONST (unsigned char)0X44 // MOP_STRING: A string is actually an array of characters (possibly // wide characters - wchar_t). The only difference is that the length // of strings is determined by a call to strlen (or the respective // API for wide character strings), rather then by the value of another // parameter / field. A MOP_STRING opcode replaces the MOP_LENGTH_IS // opcode, at exactly the same relative location in the Mops stream, for // zero terminated strings. // #define MOP_STRING (unsigned char)0X45 // // MOP_END_ARGLIST was defined to be zero, so MOP streams // can be treated as C strings. // // OTHER OPCODES: // #define MOP_TRANSMIT_AS (unsigned char)0X46 // // SHARED OPCODES: // // // Offline opcode(MOP_TABLE_INDEX): The next byte contains an index // an index into a MopsTable[] array; the value is the index of the cell // containing the first opcode of the type MOPS descriptor. This is useful // for both recursively defined types, and sharing type descriptors. // #define MOP_TABLE_INDEX (unsigned char)0X47 #define MOP_ALLOC_ALLNODES (unsigned char)0X48 #define MOP_ALLOC_DONTFREE (unsigned char)0X49 #define MOP_ALLOC_ALLNODES_DONTFREE (unsigned char)0X4A #define MOP_BYTE_COUNT (unsigned char)0X4B #define MOP_IGNORE (unsigned char)0X4C #define MOP_ERROR_STATUS_T (unsigned char)0X4D #define MOP_ENUM (unsigned char)0X4E #define MOP_ATTR_PCHAR (unsigned char)0X4F #define MOP_ATTR_PLONG MOP_PLONG #define MOP_ATTR_PSHORT MOP_PSHORT #define MOP_DO_NOTHING (unsigned char)0X51 #define MOP_CONF_ARRAY (unsigned char)0X52 #define MOP_OUT_CONF_ARRAY (unsigned char)0X53 #define MOP_IN_OUT_CONF_ARRAY (unsigned char)0X54 #define MOP_BIND_PRIMITIVE (unsigned char)0X55 #define MOP_BIND_PRIMITIVE_PTR (unsigned char)0X56 #define MOP_BIND_CONTEXT (unsigned char)0X57 #define MOP_BIND_CONTEXT_PTR (unsigned char)0X58 #define MOP_BIND_GENERIC (unsigned char)0X59 #define MOP_BIND_GENERIC_PTR (unsigned char)0X5A #define MOP_HANDLE_T (unsigned char)0X5B #define MOP_HANDLE_CONTEXT (unsigned char)0X5C #define MOP_HANDLE_CONTEXT_PTR (unsigned char)0X5D #define MOP_HANDLE_CONTEXT_OUT_PTR (unsigned char)0X5E #define MOP_HANDLE_CONTEXT_IN_OUT_PTR (unsigned char)0X5F #define MOP_HANDLE_CONTEXT_RD (unsigned char)0X60 #define MOP_HANDLE_CONTEXT_PTR_RD (unsigned char)0X61 #define MOP_HANDLE_CONTEXT_OUT_PTR_RD (unsigned char)0X62 #define MOP_HANDLE_CONTEXT_IN_OUT_PTR_RD (unsigned char)0X63 #define MOP_EXPR (unsigned char)0X64 // aliases #define MOP_UNION MOP_BEGIN_UNION #define MOP_UNION_ALGN2 MOP_BEGIN_UNION_ALGN2 #define MOP_UNION_ALGN4 MOP_BEGIN_UNION_ALGN4 #define MOP_UNION_ALGN8 MOP_BEGIN_UNION_ALGN8 #define MOP_UNION_ND MOP_BEGIN_UNION_ND #define MOP_UNION_ND_ALGN2 MOP_BEGIN_UNION_ND_ALGN2 #define MOP_UNION_ND_ALGN4 MOP_BEGIN_UNION_ND_ALGN4 #define MOP_UNION_ND_ALGN8 MOP_BEGIN_UNION_ND_ALGN8 #define MOP_ENC_UNION MOP_BEGIN_ENCAP_UNION #define MOP_ENC_UNION_ALGN2 MOP_BEGIN_ENCAP_UNION_ALGN2 #define MOP_ENC_UNION_ALGN4 MOP_BEGIN_ENCAP_UNION_ALGN4 #define MOP_ENC_UNION_ALGN8 MOP_BEGIN_ENCAP_UNION_ALGN8 #define MOP_ENC_UNION_ND MOP_BEGIN_ENCAP_UNION_ND #define MOP_ENC_UNION_ND_ALGN2 MOP_BEGIN_ENCAP_UNION_ND_ALGN2 #define MOP_ENC_UNION_ND_ALGN4 MOP_BEGIN_ENCAP_UNION_ND_ALGN4 #define MOP_ENC_UNION_ND_ALGN8 MOP_BEGIN_ENCAP_UNION_ND_ALGN8 #define MOP_CONF_STRUCT MOP_BEGIN_CONF_STRUCT #define MOP_CONF_STRUCT_ALGN2 MOP_BEGIN_CONF_STRUCT_ALGN2 #define MOP_CONF_STRUCT_ALGN4 MOP_BEGIN_CONF_STRUCT_ALGN4 #define MOP_CONF_STRUCT_ALGN8 MOP_BEGIN_CONF_STRUCT_ALGN8 #define MOP_WCHAR MOP_SHORT #define MOP_BOOL MOP_BYTE #define MOP_ULONG MOP_LONG #define MOP_USHORT MOP_SHORT #define MOP_UBYTE MOP_BYTE #define MOP_UCHAR MOP_CHAR // It's better to have MOP_ERROR undefined, to catch bad stubs at compile. // However, this code needs to be reserved for this purpose anyway. // //#define MOP_ERROR (unsigned char)255 //#define MOP_UNKNOWN_CODE (unsigned char)MOP_ERROR // // ORDER RELATED MACROS // #define MOP_IS_BASE_TYPE(mop) \ ( ((unsigned char)(mop) >= MOP_BYTE) && \ ((unsigned char)(mop) <= MOP_HYPER) ) #define MOP_IS_POINTER(mop) \ ( (MOP_POINTER <= (unsigned char)(mop)) && \ ((unsigned char)(mop) <= MOP_PLONG) ) #define MOP_IS_REF_POINTER(mop) \ ( (MOP_REF_POINTER <= (unsigned char)(mop)) && \ ((unsigned char)(mop) <= MOP_IN_OUT_REF_POINTER) ) #define MOP_IS_UNIQUE_POINTER(mop) \ ( (MOP_POINTER <= (unsigned char)(mop)) && \ ((unsigned char)(mop) <= MOP_IN_OUT_POINTER) ) #define MOP_IS_ARRAY(mop) \ (( (MOP_ARRAY <= (mop)) && \ ((mop) <= MOP_IN_OUT_ARRAY) ) || \ ( (MOP_CONF_ARRAY <= (mop)) && \ ((mop) <= MOP_IN_OUT_CONF_ARRAY) )) #define MOP_IS_ARRAY_ATTRIBUTE(mop) \ ( (MOP_SIZE_IS <= (mop)) && \ ((mop) <= MOP_STRING) ) // Note that the following macro MUST be used in conjunction with // MOP_IS_ARRAY_ATTRIBUTE // #define MOP_IS_CONST_ARRAY_ATTRIBUTE(mop) \ (!(mop%2)) #define MOP_IS_PINTEGER(mop) \ ( (MOP_PSHORT <= (mop)) && \ ((mop) <= PLONG) ) #define MOP_IS_STRUCT(mop) \ ( (MOP_BEGIN_STRUCT <= (mop)) && \ ((mop) <= MOP_BEGIN_SIMPLE_STRUCT) ) #define MOP_IS_CONFORMANT_STRUCT(mop) \ ( (MOP_BEGIN_CONF_STRUCT <= (mop)) && \ ((mop) < MOP_BEGIN_SIMPLE_STRUCT) ) #define MOP_IS_UNION(mop) \ ( (MOP_BEGIN_UNION <= (mop)) && \ ((mop) <= MOP_BEGIN_ENCAP_UNION_ND_ALGN8) ) #define MOP_IS_ENCAP_UNION(mop) \ ( (MOP_BEGIN_ENCAP_UNION <= (mop)) && \ ((mop) <= MOP_BEGIN_ENCAP_UNION_ALGN8) ) #define MOP_IS_NODEFAULT_UNION(mop) \ ( ((MOP_BEGIN_UNION_ND <= (mop)) && ((mop) <= MOP_BEGIN_UNION_ND_ALGN8)) || \ ((MOP_BEGIN_ENCAP_UNION_ND <= (mop)) && ((mop) <= MOP_BEGIN_ENCAP_UNION_ND_ALGN8)) ) #define MOP_IS_BIND_INFO(mop) \ (MOP_BIND_PRIMITIVE <= (mop) && (mop) <= MOP_BIND_GENERIC_PTR) #define MOP_IS_BIND_HANDLE(mop) \ (MOP_HANDLE_T <= (mop) && (mop) <= MOP_HANDLE_CONTEXT_IN_OUT_PTR_RD) #define MOP_IS_ALLOC_INFO(mop) \ (MOP_ALLOC_ALLNODES <= (mop) && (mop) <= MOP_ALLOC_DONTFREE) // // BASE TYPE ALIGNMENT RELATED TABLES // // // The following table gives the natural alignment values for // base types. It assumes the above opcodes and natural alignment (/Zp8). // extern const int NaturalAlignment[]; // // The MopAlignIncrement array gives the values of the incment constant // for a base type. // extern const size_t MopAlignIncrement[]; // // The MopAlignMask array gives the truncation mask values for // // base types as a function of their size: // size = 0-1 mask = 0XFFFFFFFF // 2-3 0XFFFFFFFE // 4-7 0XFFFFFFFC // 8 0XFFFFFFF8 // extern const unsigned long MopAlignMask[]; // // Size of the base type given by an opcode. // Note: MopAlignIncrement[ OPCODE ] = MopSizeOf[ OPCODE ] - 1; // extern const size_t MopSizeOf[]; // // To align a buffer pointer "Buffer" to the right boundary for a // given base type given by OPCODE execute the sequence: // // Buffer += MopAlignIncrement[ OPCODE ]; // Buffer &= MopAlignMask[ OPCODE ]; // /////////////////////////////////////////////////////////////////// // // CURRENTLY UNIMPLEMENTED: FUNCTIONAL STYLE OPCODES // /////////////////////////////////////////////////////////////////// // // "Dumb" marshalling: low level opcodes for // // o advancing the buffer pointer // o aligning the buffer pointer, or // o copy aligned data (plus conversion) // // These opcodes have functional (or operational) semantics. // // Dumb marshalling to be implemented later - for speed mainly. // Since alignment cannot always be determined at compile time // runtime alignment is necessary, and hence "smart" marshalling, // (short-hand for align and then marshall) would be more space // efficient. // For now most of the section is just an option for future reference. // It is left for the few opcodes that are actually required, and // as a simple background for the often more complex declarative // semantics opcodes. // Skip to "Smart marshalling" for the more relevant stuff currently // // Direct copy (+ conversion?) marshalling of naturally aligned // base types (no alignment necessary) // // #define MOP_ALIGNED_BYTE (unsigned char)0XA0 // #define MOP_ALIGNED_SMALL (unsigned char)0XA1 // #define MOP_ALIGNED_CHAR (unsigned char)0XA2 #define MOP_ALIGNED_SHORT (unsigned char)0XA3 #define MOP_ALIGNED_LONG (unsigned char)0XA4 #define MOP_ALIGNED_FLOAT (unsigned char)0XA5 #define MOP_ALIGNED_DOUBLE (unsigned char)0XA6 #define MOP_ALIGNED_HYPER (unsigned char)0XA7 // // MOP_COPY_BYTES_? copies x bytes into the buffer (marshalling only) // where x is given by the next ? bytes in the MOPS stream. (should // the first byte of the byte_count specifier be aligned?) // #define MOP_COPY_BYTES_1 (unsigned char)0XA8 #define MOP_COPY_BYTES_2 (unsigned char)0XA9 #define MOP_COPY_BYTES_4 (unsigned char)0XAA // // Align puffer pointer to next 0 mod x point (x=2,4,8) // #define MOP_ALIGN_0MOD2 (unsigned char)0XAB #define MOP_ALIGN_0MOD4 (unsigned char)0XAC #define MOP_ALIGN_0MOD8 (unsigned char)0XAD // // Advance buffer pointer by a (a=1,2,3,4) // Reserved (unsigned char)0XB0 // #define MOP_DAVANCE_1 (unsigned char)0XB1 #define MOP_DAVANCE_2 (unsigned char)0XB2 #define MOP_DAVANCE_3 (unsigned char)0XB3 #define MOP_DAVANCE_4 (unsigned char)0XB4 // // For future marshalling, of hyper - to advance // buffer pointer by a, 4