src/Types.h
author David Anderson <dvander@alliedmods.net>
Wed Dec 26 17:19:49 2012 -0800 (2012-12-26)
changeset 243 3d94c73a824c
parent 241 18f3010a358c
child 247 7721042bdb67
permissions -rw-r--r--
Fix build bustage.
dvander@238
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@238
     2
 *
dvander@238
     3
 * Copyright (C) 2012 David Anderson
dvander@238
     4
 *
dvander@238
     5
 * This file is part of JITCraft.
dvander@238
     6
 *
dvander@238
     7
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@238
     8
 * the terms of the GNU General Public License as published by the Free
dvander@238
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@238
    10
 * any later version.
dvander@238
    11
 * 
dvander@238
    12
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@238
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@238
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@238
    15
 *
dvander@238
    16
 * You should have received a copy of the GNU General Public License along with
dvander@238
    17
 * JITCraft. If not, see http://www.gnu.org/licenses/.
dvander@238
    18
 */
dvander@238
    19
#ifndef _include_jc_types_h_
dvander@238
    20
#define _include_jc_types_h_
dvander@238
    21
dvander@238
    22
#include "Heap.h"
dvander@238
    23
#include "Barriers.h"
dvander@238
    24
#include "FixedArray.h"
dvander@238
    25
#include "compiler/Token.h"
dvander@238
    26
dvander@238
    27
namespace ke {
dvander@238
    28
dvander@238
    29
class String;
dvander@238
    30
class Descriptor;
dvander@238
    31
class StructMap;
dvander@238
    32
class ArrayMap;
dvander@238
    33
dvander@238
    34
#define MAX_ARRAY_DEPTH     5
dvander@238
    35
dvander@238
    36
enum PrimitiveType
dvander@238
    37
{
dvander@238
    38
    // A boolean type semantically represents 0 or 1. As an optimization, its
dvander@238
    39
    // internal storage type is the same as int32, and any non-zero value
dvander@238
    40
    // compares positively to "true".
dvander@238
    41
    PrimitiveType_Bool,
dvander@238
    42
dvander@238
    43
    // A character is an arbitrary 8-bit value. Characters are not supported
dvander@238
    44
    // as a normal storage class; they may only be used for arrays. When read
dvander@238
    45
    // from an array, they are immediately sign extended to 32 bits. Integers
dvander@238
    46
    // stored into an char array are truncated to 8 bits.
dvander@238
    47
    PrimitiveType_Char,         // signed, 8-bit character
dvander@238
    48
dvander@238
    49
    // Enumerations and untyped variables are stored as signed, 32-bit integers.
dvander@238
    50
    PrimitiveType_Int32,
dvander@238
    51
dvander@238
    52
    // Floating point values are 32-bit IEEE-754 floats. This is required ro
dvander@238
    53
    // SourcePawn 1 compatibility.
dvander@238
    54
    PrimitiveType_Float,
dvander@238
    55
dvander@238
    56
    // This is a native-sized integer type (32-bit on 32-bit systems, 64-bit
dvander@238
    57
    // on 64-bit systems), and does not exist in language semantics.
dvander@238
    58
    PrimitiveType_Native,
dvander@238
    59
dvander@238
    60
    PrimitiveTypes_Total
dvander@238
    61
};
dvander@238
    62
dvander@238
    63
enum TypeQualifiers
dvander@238
    64
{
dvander@238
    65
    TypeQual_None           = 0,
dvander@238
    66
dvander@241
    67
    // Values of this type cannot be modified.
dvander@241
    68
    TypeQual_Const       = (1 << 2)
dvander@238
    69
};
dvander@238
    70
dvander@238
    71
class Type : public Object
dvander@238
    72
{
dvander@238
    73
  protected:
dvander@238
    74
    enum Kind {
dvander@238
    75
        // A primitive is a plain-old-data type.
dvander@238
    76
        PRIMITIVE,
dvander@238
    77
dvander@238
    78
        // Void is an internal type used to specify that a function returns no
dvander@238
    79
        // value.
dvander@238
    80
        VOID,
dvander@238
    81
dvander@238
    82
        // Enums are plain-old-data with int32 storage. They allow for extra
dvander@238
    83
        // type checking that would not be possible with integers.
dvander@238
    84
        ENUM,
dvander@238
    85
dvander@238
    86
        // Unchecked is a magic type that has implicit, bitwise coercion to
dvander@238
    87
        // int32, float, bool, or an enum.
dvander@238
    88
        UNCHECKED,
dvander@238
    89
dvander@239
    90
        // Contains type qualifiers, and a back pointer to the actual
dvander@239
    91
        // unqualified type.
dvander@239
    92
        QUALTYPE,
dvander@239
    93
dvander@239
    94
        // ------ Add traceable types below (STRING FIRST!) -------
dvander@238
    95
dvander@238
    96
        // An immutable type that is a primitive in terms of language
dvander@238
    97
        // semantics, but gets a special type here to make internal
dvander@238
    98
        // logic easier.
dvander@238
    99
        STRING,
dvander@238
   100
dvander@238
   101
        // An array is a fixed-length vector of any other type.
dvander@238
   102
        ARRAY,
dvander@238
   103
        EXTERNAL_ARRAY,
dvander@238
   104
dvander@238
   105
        // A reference type may only be specified on parameters, and
dvander@238
   106
        // references may only be computed to primitives or enums.
dvander@238
   107
        REFERENCE,
dvander@238
   108
dvander@238
   109
        // A function type encapsulates a function signature.
dvander@238
   110
        FUNCTION,
dvander@238
   111
dvander@238
   112
        // Structs are composite records that may contain primitives, arrays,
dvander@238
   113
        // functions, enums, and other structs.
dvander@239
   114
        STRUCT
dvander@238
   115
    };
dvander@238
   116
dvander@240
   117
    void init(Kind kind, Type *root = NULL);
dvander@238
   118
dvander@238
   119
  private:
dvander@238
   120
    Kind kind() {
dvander@238
   121
        return root_->kind_;
dvander@238
   122
    }
dvander@238
   123
dvander@238
   124
  public:   
dvander@238
   125
    static Type *NewVoid(Zone *zone);
dvander@238
   126
    static Type *NewUnchecked(Zone *zone);
dvander@238
   127
    static Type *NewPrimitive(Zone *zone, PrimitiveType type);
dvander@238
   128
    static Type *NewString(Zone *zone);
dvander@240
   129
    static Type *NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> type);
dvander@238
   130
dvander@238
   131
    static Type *cast(Object *obj) {
dvander@238
   132
        assert(!obj ||
dvander@238
   133
               obj->is(MapKind_Type) ||
dvander@238
   134
               obj->is(MapKind_FunctionType) ||
dvander@238
   135
               obj->is(MapKind_StructType) ||
dvander@238
   136
               obj->is(MapKind_ArrayType) ||
dvander@238
   137
               obj->is(MapKind_ReferenceType) ||
dvander@238
   138
               obj->is(MapKind_EnumType));
dvander@238
   139
        return (Type *)obj;
dvander@238
   140
    }
dvander@238
   141
dvander@238
   142
    bool isPrimitive() {
dvander@238
   143
        return kind() == PRIMITIVE;
dvander@238
   144
    }
dvander@238
   145
    bool isArray() {
dvander@238
   146
        return kind() == ARRAY || kind() == EXTERNAL_ARRAY;
dvander@238
   147
    }
dvander@238
   148
    bool isReference() {
dvander@238
   149
        return kind() == REFERENCE;
dvander@238
   150
    }
dvander@238
   151
    bool isFunction() {
dvander@238
   152
        return kind() == FUNCTION;
dvander@238
   153
    }
dvander@238
   154
    bool isVoid() {
dvander@238
   155
        return kind() == VOID;
dvander@238
   156
    }
dvander@238
   157
    bool isUnchecked() {
dvander@238
   158
        return kind() == UNCHECKED;
dvander@238
   159
    }
dvander@238
   160
    bool isStruct() {
dvander@238
   161
        return kind() == STRUCT;
dvander@238
   162
    }
dvander@238
   163
    PrimitiveType primitive() {
dvander@238
   164
        assert(isPrimitive());
dvander@238
   165
        return root_->primitive_;
dvander@238
   166
    }
dvander@238
   167
    bool isPod() {
dvander@238
   168
        return (isPrimitive() && !isString()) || isEnum() || isUnchecked();
dvander@238
   169
    }
dvander@238
   170
    PrimitiveType pod() {
dvander@238
   171
        assert(isPod());
dvander@238
   172
        return isPrimitive()
dvander@238
   173
               ? (primitive() == PrimitiveType_Bool)
dvander@238
   174
                 ? PrimitiveType_Int32
dvander@238
   175
                 : primitive()
dvander@238
   176
               : PrimitiveType_Int32;
dvander@238
   177
    }
dvander@238
   178
    bool isChar() {
dvander@238
   179
        return isPrimitive() && primitive() == PrimitiveType_Char;
dvander@238
   180
    }
dvander@238
   181
    bool isFloat() {
dvander@238
   182
        return isPrimitive() && primitive() == PrimitiveType_Float;
dvander@238
   183
    }
dvander@238
   184
    bool isInt32() {
dvander@238
   185
        return isPrimitive() && primitive() == PrimitiveType_Int32;
dvander@238
   186
    }
dvander@238
   187
    bool isInt32OrEnum() {
dvander@238
   188
        return isInt32() || isEnum();
dvander@238
   189
    }
dvander@238
   190
    bool isBool() {
dvander@238
   191
        return isPrimitive() && primitive() == PrimitiveType_Bool;
dvander@238
   192
    }
dvander@238
   193
    bool isString() {
dvander@238
   194
        return kind() == STRING;
dvander@238
   195
    }
dvander@238
   196
    bool isExternalArray() {
dvander@238
   197
        return kind() == EXTERNAL_ARRAY;
dvander@238
   198
    }
dvander@238
   199
    bool isTraceable() {
dvander@238
   200
        return kind() >= STRING;
dvander@238
   201
    }
dvander@238
   202
    bool isEnum() {
dvander@238
   203
        return kind() == ENUM;
dvander@238
   204
    }
dvander@238
   205
    bool hasTypeQualifiers() {
dvander@238
   206
        return kind_ == QUALTYPE;
dvander@238
   207
    }
dvander@238
   208
dvander@238
   209
    TypeQualifiers quals() {
dvander@241
   210
        if (!hasTypeQualifiers())
dvander@238
   211
            return TypeQual_None;
dvander@238
   212
        return quals_;
dvander@238
   213
    }
dvander@239
   214
    Type *unqualified() {
dvander@239
   215
        return root_;
dvander@239
   216
    }
dvander@238
   217
dvander@238
   218
    // GC Descriptor.
dvander@238
   219
    static inline size_t offsetOfRoot() {
dvander@238
   220
        return OFFSETOF(Type, root_);
dvander@238
   221
    }
dvander@238
   222
    // End GC Descriptor.
dvander@238
   223
dvander@238
   224
  protected:
dvander@238
   225
    Kind kind_;
dvander@238
   226
    PrimitiveType primitive_;
dvander@238
   227
    TypeQualifiers quals_;
dvander@238
   228
dvander@238
   229
    // For unqualified types, this points to |this|. For qualified types, it
dvander@238
   230
    // points to the unqualified original type.
dvander@238
   231
    Barriered<Type> root_;
dvander@238
   232
};
dvander@238
   233
dvander@238
   234
class EnumType : public Type
dvander@238
   235
{
dvander@238
   236
  public:
dvander@238
   237
    static EnumType *New(Zone *Zone, Handle<String> name);
dvander@238
   238
dvander@238
   239
    String *name() {
dvander@238
   240
        return name_;
dvander@238
   241
    }
dvander@238
   242
dvander@238
   243
    // GC Descriptor.
dvander@238
   244
    static inline size_t offsetOfName() {
dvander@238
   245
        return OFFSETOF(EnumType, name_);
dvander@238
   246
    }
dvander@238
   247
    // End GC Descriptor.
dvander@238
   248
dvander@238
   249
    static EnumType *cast(Object *obj) {
dvander@238
   250
        assert(!obj || obj->is(MapKind_EnumType));
dvander@238
   251
        return (EnumType *)obj;
dvander@238
   252
    }
dvander@238
   253
dvander@238
   254
  private:
dvander@238
   255
    Barriered<String> name_;
dvander@238
   256
};
dvander@238
   257
dvander@238
   258
class ReferenceType : public Type
dvander@238
   259
{
dvander@238
   260
  public:
dvander@238
   261
    static ReferenceType *New(Zone *zone, Handle<Type> contained);
dvander@238
   262
    
dvander@238
   263
    Type *contained() {
dvander@238
   264
        return contained_;
dvander@238
   265
    }
dvander@238
   266
dvander@238
   267
    // GC Descriptor.
dvander@238
   268
    static inline size_t offsetOfContained() {
dvander@238
   269
        return OFFSETOF(ReferenceType, contained_);
dvander@238
   270
    }
dvander@238
   271
    // End GC Descriptor.
dvander@238
   272
dvander@239
   273
    static ReferenceType *cast(Type *obj) {
dvander@239
   274
        if (!obj)
dvander@239
   275
            return NULL;
dvander@239
   276
        obj = obj->unqualified();
dvander@239
   277
        assert(obj->is(MapKind_ReferenceType));
dvander@238
   278
        return (ReferenceType *)obj;
dvander@238
   279
    }
dvander@238
   280
dvander@238
   281
  private:
dvander@238
   282
    Barriered<Type> contained_;
dvander@238
   283
};
dvander@238
   284
dvander@238
   285
class ArrayType : public Type
dvander@238
   286
{
dvander@238
   287
  public:
dvander@238
   288
    static const int DYNAMIC_ARRAY_SIZE = -1;
dvander@238
   289
dvander@238
   290
    static ArrayType *New(Zone *zone, Handle<Type> contained, int elements);
dvander@238
   291
    static ArrayType *NewExternal(Zone *zone, Handle<Type> contained);
dvander@238
   292
dvander@238
   293
    Type *innermost() {
dvander@238
   294
        Type *temp = contained();
dvander@238
   295
        while (temp->isArray())
dvander@238
   296
            temp = ArrayType::cast(temp)->contained();
dvander@238
   297
        return temp;
dvander@238
   298
    }
dvander@238
   299
dvander@238
   300
    Type *contained() {
dvander@238
   301
        return contained_;
dvander@238
   302
    }
dvander@238
   303
    bool isFixedLength() {
dvander@238
   304
        return elements_ > 0;
dvander@238
   305
    }
dvander@238
   306
    bool isCharArray() {
dvander@238
   307
        return contained()->isPrimitive() &&
dvander@238
   308
               contained()->primitive() == PrimitiveType_Char;
dvander@238
   309
    }
dvander@238
   310
    unsigned fixedLength() {
dvander@238
   311
        assert(isFixedLength());
dvander@238
   312
        return elements_;
dvander@238
   313
    }
dvander@238
   314
    unsigned levels() {
dvander@238
   315
        return levels_;
dvander@238
   316
    }
dvander@238
   317
    bool hasInlineElements() {
dvander@238
   318
        // We don't allocate traceable elements inline, since there's no
dvander@238
   319
        // point to the optimization; we're going to be allocating lots of
dvander@238
   320
        // objects anyway (in theory).
dvander@238
   321
        return isFixedLength() && !contained()->isTraceable();
dvander@238
   322
    }
dvander@238
   323
dvander@238
   324
    // Arrays of this type can be created with this cached map.
dvander@238
   325
    ArrayMap *newMap() {
dvander@238
   326
        return newMap_;
dvander@238
   327
    }
dvander@238
   328
    void setNewMap(ArrayMap *map) {
dvander@238
   329
        assert(!newMap());
dvander@238
   330
        newMap_ = map;
dvander@238
   331
    }
dvander@238
   332
dvander@238
   333
    // GC Descriptor.
dvander@238
   334
    static inline size_t offsetOfContained() {
dvander@238
   335
        return OFFSETOF(ArrayType, contained_);
dvander@238
   336
    }
dvander@238
   337
    static inline size_t offsetOfNewMap() {
dvander@238
   338
        return OFFSETOF(ArrayType, newMap_);
dvander@238
   339
    }
dvander@238
   340
    // End GC Descriptor.
dvander@238
   341
dvander@239
   342
    static ArrayType *cast(Type *obj) {
dvander@239
   343
        if (!obj)
dvander@239
   344
            return NULL;
dvander@239
   345
        obj = obj->unqualified();
dvander@239
   346
        assert(obj->is(MapKind_ArrayType));
dvander@238
   347
        return (ArrayType *)obj;
dvander@238
   348
    }
dvander@238
   349
dvander@238
   350
  private:
dvander@238
   351
    int32 elements_;
dvander@238
   352
    unsigned levels_;
dvander@238
   353
    Barriered<Type> contained_;
dvander@238
   354
    Barriered<ArrayMap> newMap_;
dvander@238
   355
};
dvander@238
   356
dvander@238
   357
class StructType : public Type
dvander@238
   358
{
dvander@238
   359
  public:
dvander@238
   360
    static StructType *New(Zone *zone, Handle<String> name, Handle<FixedArray> fields);
dvander@238
   361
dvander@238
   362
    FixedArray *fields() {
dvander@238
   363
        assert(isStruct());
dvander@238
   364
        return fields_;
dvander@238
   365
    }
dvander@238
   366
    Descriptor *lookupField(Handle<String> name, unsigned *index = NULL);
dvander@238
   367
dvander@238
   368
    // Objects of this type can be created with this cached map.
dvander@238
   369
    StructMap *newMap() {
dvander@238
   370
        return newMap_;
dvander@238
   371
    }
dvander@238
   372
    void setNewMap(StructMap *map) {
dvander@238
   373
        assert(!newMap());
dvander@238
   374
        newMap_ = map;
dvander@238
   375
    }
dvander@238
   376
dvander@238
   377
    String *name() {
dvander@238
   378
        return name_;
dvander@238
   379
    }
dvander@238
   380
dvander@238
   381
    // GC Descriptor.
dvander@238
   382
    static inline size_t offsetOfFields() {
dvander@238
   383
        return OFFSETOF(StructType, fields_);
dvander@238
   384
    }
dvander@238
   385
    static inline size_t offsetOfNewMap() {
dvander@238
   386
        return OFFSETOF(StructType, newMap_);
dvander@238
   387
    }
dvander@238
   388
    static inline size_t offsetOfName() {
dvander@238
   389
        return OFFSETOF(StructType, name_);
dvander@238
   390
    }
dvander@238
   391
    // End GC Descriptor.
dvander@238
   392
dvander@239
   393
    static StructType *cast(Type *obj) {
dvander@239
   394
        if (!obj)
dvander@239
   395
            return NULL;
dvander@239
   396
        obj = obj->unqualified();
dvander@239
   397
        assert(obj->is(MapKind_StructType));
dvander@238
   398
        return (StructType *)obj;
dvander@238
   399
    }
dvander@238
   400
dvander@238
   401
  private:
dvander@238
   402
    // Structs only.
dvander@238
   403
    Barriered<FixedArray> fields_;
dvander@238
   404
    Barriered<StructMap> newMap_;
dvander@238
   405
    Barriered<String> name_;
dvander@238
   406
};
dvander@238
   407
dvander@238
   408
class FunctionType : public Type
dvander@238
   409
{
dvander@238
   410
  public:
dvander@238
   411
    static FunctionType *New(Zone *zone, Handle<String> name, TokenKind kind);
dvander@238
   412
dvander@238
   413
    Type *parameterAt(size_t i) {
dvander@238
   414
        return Type::cast(parameters()->at(i));
dvander@238
   415
    }
dvander@238
   416
    Type *returnType() {
dvander@238
   417
        assert(isFunction());
dvander@238
   418
        return returnType_;
dvander@238
   419
    }
dvander@238
   420
    FixedArray *parameters() {
dvander@238
   421
        assert(isFunction());
dvander@238
   422
        return parameters_;
dvander@238
   423
    }
dvander@238
   424
    FixedArray *defaults() {
dvander@238
   425
        assert(isFunction());
dvander@238
   426
        return defaults_;
dvander@238
   427
    }
dvander@238
   428
    bool isNative() {
dvander@238
   429
        return token_ == TOK_NATIVE;
dvander@238
   430
    }
dvander@238
   431
    bool isForward() {
dvander@238
   432
        return token_ == TOK_FORWARD;
dvander@238
   433
    }
dvander@238
   434
    bool isNativeVariadic() {
dvander@238
   435
        assert(isNative());
dvander@238
   436
        return variadicNative_;
dvander@238
   437
    }
dvander@238
   438
    void setReturnType(Handle<Type> returnType) {
dvander@238
   439
        assert(!returnType_);
dvander@238
   440
        returnType_ = returnType;
dvander@238
   441
    }
dvander@238
   442
    void setParameterTypes(Handle<FixedArray> types) {
dvander@238
   443
        assert(!parameters_);
dvander@238
   444
        parameters_ = types;
dvander@238
   445
    }
dvander@238
   446
    TokenKind token() {
dvander@238
   447
        return token_;
dvander@238
   448
    }
dvander@238
   449
    String *name() {
dvander@238
   450
        return name_;
dvander@238
   451
    }
dvander@238
   452
dvander@238
   453
    // GC Descriptor.
dvander@238
   454
    static inline size_t offsetOfReturnType() {
dvander@238
   455
        return OFFSETOF(FunctionType, returnType_);
dvander@238
   456
    }
dvander@238
   457
    static inline size_t offsetOfParameters() {
dvander@238
   458
        return OFFSETOF(FunctionType, parameters_);
dvander@238
   459
    }
dvander@238
   460
    static inline size_t offsetOfDefaults() {
dvander@238
   461
        return OFFSETOF(FunctionType, defaults_);
dvander@238
   462
    }
dvander@238
   463
    static inline size_t offsetOfName() {
dvander@238
   464
        return OFFSETOF(FunctionType, name_);
dvander@238
   465
    }
dvander@238
   466
    // End GC Descriptor.
dvander@238
   467
dvander@239
   468
    static FunctionType *cast(Type *obj) {
dvander@239
   469
        if (!obj)
dvander@239
   470
            return NULL;
dvander@239
   471
        obj = obj->unqualified();
dvander@239
   472
        assert(obj->is(MapKind_FunctionType));
dvander@238
   473
        return (FunctionType *)obj;
dvander@238
   474
    }
dvander@238
   475
dvander@238
   476
  private:
dvander@238
   477
    // Functions only.
dvander@238
   478
    Barriered<Type> returnType_;
dvander@238
   479
    Barriered<FixedArray> parameters_;
dvander@238
   480
    Barriered<FixedArray> defaults_;
dvander@238
   481
    Barriered<String> name_;
dvander@238
   482
    TokenKind token_;
dvander@238
   483
    bool variadicNative_;
dvander@238
   484
};
dvander@238
   485
dvander@238
   486
class BoxedPrimitive
dvander@238
   487
{
dvander@238
   488
    PrimitiveType type_;
dvander@238
   489
    union {
dvander@238
   490
        int i_;
dvander@238
   491
        float f_;
dvander@238
   492
    };
dvander@238
   493
dvander@238
   494
  public:
dvander@238
   495
    static BoxedPrimitive Int(int i) {
dvander@238
   496
        BoxedPrimitive b;
dvander@238
   497
        b.type_ = PrimitiveType_Int32;
dvander@238
   498
        b.i_ = i;
dvander@238
   499
        return b;
dvander@238
   500
    }
dvander@238
   501
    static BoxedPrimitive Float(float f) {
dvander@238
   502
        BoxedPrimitive b;
dvander@238
   503
        b.type_ = PrimitiveType_Float;
dvander@238
   504
        b.f_ = f;
dvander@238
   505
        return b;
dvander@238
   506
    }
dvander@238
   507
dvander@238
   508
    PrimitiveType type() const {
dvander@238
   509
        return type_;
dvander@238
   510
    }
dvander@238
   511
    int toInt() const {
dvander@238
   512
        assert(type() == PrimitiveType_Int32);
dvander@238
   513
        return i_;
dvander@238
   514
    }
dvander@238
   515
    float toFloat() const {
dvander@238
   516
        assert(type() == PrimitiveType_Float);
dvander@238
   517
        return f_;
dvander@238
   518
    }
dvander@238
   519
};
dvander@238
   520
dvander@241
   521
const char *GetTypeName(Type *type, char *buffer, size_t maxlen);
dvander@238
   522
dvander@238
   523
}
dvander@238
   524
dvander@238
   525
#endif // _include_jc_types_h_