src/Types.h
author David Anderson <dvander@alliedmods.net>
Wed Aug 01 22:32:59 2012 -0700 (2012-08-01)
changeset 145 e9d804821c48
parent 143 393f1b8ac8c3
child 146 dc7d3b7a918c
permissions -rw-r--r--
Introduced type semantics, completely replacing tag semantics.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #ifndef _include_jc_types_h_
    20 #define _include_jc_types_h_
    21 
    22 #include "Heap.h"
    23 #include "Barriers.h"
    24 #include "FixedArray.h"
    25 
    26 namespace ke {
    27 
    28 class String;
    29 
    30 enum PrimitiveType
    31 {
    32     // A boolean type semantically represents 0 or 1. As an optimization, its
    33     // internal storage type is the same as int32, and any non-zero value
    34     // compares positively to "true".
    35     PrimitiveType_Bool,
    36 
    37     // A character is an arbitrary 8-bit value. Characters are not supported
    38     // as a normal storage class; they may only be used for arrays. When read
    39     // from an array, they are immediately sign extended to 32 bits. Integers
    40     // stored into an char array are truncated to 8 bits.
    41     PrimitiveType_Char,         // signed, 8-bit character
    42 
    43     // Enumerations and untyped variables are stored as signed, 32-bit integers.
    44     PrimitiveType_Int32,
    45 
    46     // Floating point values are 32-bit IEEE-754 floats. This is required ro
    47     // SourcePawn 1 compatibility.
    48     PrimitiveType_Float,
    49 
    50     // This is a native-sized integer type (32-bit on 32-bit systems, 64-bit
    51     // on 64-bit systems), and does not exist in language semantics.
    52     PrimitiveType_Native,
    53 
    54     PrimitiveTypes_Total
    55 };
    56 
    57 class Type : public Object
    58 {
    59     enum Kind {
    60         PRIMITIVE,
    61         ARRAY,
    62         REFERENCE,
    63         FUNCTION,
    64         NATIVE,
    65         VOID,
    66         ENUM
    67     };
    68 
    69   private:
    70     Kind kind() {
    71         return kind_;
    72     }
    73 
    74   public:
    75     static const int UNKNOWN_SIZE = -1;
    76     static const size_t MAX_UNSAFE_ARRAY_DEPTH = 5;
    77     
    78     static Type *NewVoid(Zone *zone);
    79     static Type *NewPrimitive(Zone *zone, PrimitiveType type);
    80     static Type *NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst);
    81     static Type *NewReference(Zone *zone, Handle<Type> contained, bool isConst);
    82     static Type *NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters);
    83     static Type *NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool isVariadic);
    84     static Type *NewEnum(Zone *zone, Handle<String> name);
    85 
    86     static bool Compare(Type *left, Type *right);
    87 
    88     static Type *cast(Object *obj) {
    89         assert(!obj || obj->is(MapKind_Type));
    90         return (Type *)obj;
    91     }
    92 
    93     bool isPrimitive() {
    94         return kind() == PRIMITIVE;
    95     }
    96     bool isArray() {
    97         return kind() == ARRAY;
    98     }
    99     bool isReference() {
   100         return kind() == REFERENCE;
   101     }
   102     bool isFunction() {
   103         return kind() == FUNCTION || kind() == NATIVE;
   104     }
   105     bool isNative() {
   106         return kind() == NATIVE;
   107     }
   108     bool isVoid() {
   109         return kind() == VOID;
   110     }
   111     bool isNativeVariadic() {
   112         assert(isNative());
   113         return variadicNative_;
   114     }
   115     PrimitiveType primitive() {
   116         assert(isPrimitive());
   117         return primitive_;
   118     }
   119     PrimitiveType pod() {
   120         assert(isPrimitive() || isEnum());
   121         return isPrimitive()
   122                ? primitive()
   123                : PrimitiveType_Int32;
   124     }
   125     Type *contained() {
   126         assert(isArray() || isReference());
   127         return Type::cast(contained_);
   128     }
   129     int elements() {
   130         assert(isArray());
   131         return elements_;
   132     }
   133     unsigned levels() {
   134         assert(isArray());
   135         return levels_;
   136     }
   137     Type *innermost() {
   138         assert(isArray());
   139         Type *temp = contained();
   140         while (temp->isArray())
   141             temp = temp->contained();
   142         return temp;
   143     }
   144     bool isFloat() {
   145         return isPrimitive() && primitive() == PrimitiveType_Float;
   146     }
   147     bool isInt32() {
   148         return isPrimitive() && primitive() == PrimitiveType_Int32;
   149     }
   150     bool isInt32OrEnum() {
   151         return isInt32() || isEnum();
   152     }
   153     bool isCharArray() {
   154         return isArray() &&
   155                contained()->isPrimitive() &&
   156                contained()->primitive() == PrimitiveType_Char;
   157     }
   158     Type *returnType() {
   159         assert(isFunction());
   160         return returnType_;
   161     }
   162     FixedArray *parameters() {
   163         assert(isFunction());
   164         return parameters_;
   165     }
   166     Type *parameterAt(size_t i) {
   167         return Type::cast(parameters()->at(i));
   168     }
   169     bool isTraceable() {
   170         return !isPrimitive();
   171     }
   172     bool isConst() {
   173         assert(kind() == PRIMITIVE || kind() == ARRAY || kind() == REFERENCE);
   174         return const_;
   175     }
   176     bool isEnum() {
   177         return kind() == ENUM;
   178     }
   179 
   180     String *name() {
   181         assert(isEnum());
   182         return name_;
   183     }
   184 
   185     // GC Descriptor.
   186     static inline size_t offsetOfContained() {
   187         return OFFSETOF(Type, contained_);
   188     }
   189     static inline size_t offsetOfReturnType() {
   190         return OFFSETOF(Type, returnType_);
   191     }
   192     static inline size_t offsetOfParameters() {
   193         return OFFSETOF(Type, parameters_);
   194     }
   195     static inline size_t offsetOfName() {
   196         return OFFSETOF(Type, name_);
   197     }
   198     // End GC Descriptor.
   199 
   200   private:
   201     Kind kind_;
   202     PrimitiveType primitive_;
   203 
   204     // Primitives, arrays, and references.
   205     bool const_;
   206 
   207     // Arrays only.
   208     int32 elements_;
   209     unsigned levels_;
   210 
   211     // Arrays and references only.
   212     Barriered<Type> contained_;
   213 
   214     // Functions only.
   215     Barriered<Type> returnType_;
   216     Barriered<FixedArray> parameters_;
   217     bool variadicNative_;
   218 
   219     // Enums only.
   220     Barriered<String> name_;
   221 };
   222 
   223 class BoxedPrimitive
   224 {
   225     PrimitiveType type_;
   226     union {
   227         int i_;
   228     };
   229 
   230   public:
   231     static BoxedPrimitive Int(int i) {
   232         BoxedPrimitive b;
   233         b.type_ = PrimitiveType_Int32;
   234         b.i_ = i;
   235         return b;
   236     }
   237 
   238     PrimitiveType type() const {
   239         return type_;
   240     }
   241     int toInt() const {
   242         assert(type() == PrimitiveType_Int32);
   243         return i_;
   244     }
   245 };
   246 
   247 }
   248 
   249 #endif // _include_jc_types_h_