src/Types.h
author David Anderson <dvander@alliedmods.net>
Sun Aug 05 15:38:52 2012 -0700 (2012-08-05)
changeset 167 cf82769eb136
parent 154 a85a0303bcb8
child 168 4d0fff61d65e
permissions -rw-r--r--
Added bogo "unchecked" type that will evolve later.
     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 class Descriptor;
    30 
    31 enum PrimitiveType
    32 {
    33     // A boolean type semantically represents 0 or 1. As an optimization, its
    34     // internal storage type is the same as int32, and any non-zero value
    35     // compares positively to "true".
    36     PrimitiveType_Bool,
    37 
    38     // A character is an arbitrary 8-bit value. Characters are not supported
    39     // as a normal storage class; they may only be used for arrays. When read
    40     // from an array, they are immediately sign extended to 32 bits. Integers
    41     // stored into an char array are truncated to 8 bits.
    42     PrimitiveType_Char,         // signed, 8-bit character
    43 
    44     // Enumerations and untyped variables are stored as signed, 32-bit integers.
    45     PrimitiveType_Int32,
    46 
    47     // Floating point values are 32-bit IEEE-754 floats. This is required ro
    48     // SourcePawn 1 compatibility.
    49     PrimitiveType_Float,
    50 
    51     // This is a native-sized integer type (32-bit on 32-bit systems, 64-bit
    52     // on 64-bit systems), and does not exist in language semantics.
    53     PrimitiveType_Native,
    54 
    55     PrimitiveTypes_Total
    56 };
    57 
    58 class Type : public Object
    59 {
    60     enum Kind {
    61         // A primitive is a plain-old-data type.
    62         PRIMITIVE,
    63 
    64         // An array is a fixed-length vector of any other type.
    65         ARRAY,
    66 
    67         // A reference type may only be specified on parameters, and
    68         // references may only be computed to primitives or enums.
    69         REFERENCE,
    70 
    71         // A function type encapsulates a function signature.
    72         FUNCTION,
    73 
    74         // A native is a limited type of function used for system calls.
    75         NATIVE,
    76 
    77         // Void is an internal type used to specify that a function returns no
    78         // value.
    79         VOID,
    80 
    81         // Enums are plain-old-data with int32 storage. They allow for extra
    82         // type checking that would not be possible with integers.
    83         ENUM,
    84 
    85         // Structs are composite records that may contain primitives, arrays,
    86         // functions, enums, and other structs.
    87         STRUCT,
    88 
    89         // Unchecked is a magic type that has implicit, bitwise coercion to
    90         // int32, float, bool, or an enum.
    91         UNCHECKED
    92     };
    93 
    94   private:
    95     Kind kind() {
    96         return kind_;
    97     }
    98 
    99   public:
   100     static const int UNKNOWN_SIZE = -1;
   101     static const size_t MAX_UNSAFE_ARRAY_DEPTH = 5;
   102     
   103     static Type *NewVoid(Zone *zone);
   104     static Type *NewUnchecked(Zone *zone);
   105     static Type *NewPrimitive(Zone *zone, PrimitiveType type);
   106     static Type *NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst);
   107     static Type *NewReference(Zone *zone, Handle<Type> contained, bool isConst);
   108     static Type *NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters);
   109     static Type *NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool isVariadic);
   110     static Type *NewEnum(Zone *zone, Handle<String> name);
   111     static Type *NewStruct(Zone *zone, Handle<String> name, Handle<FixedArray> fields, Handle<Map> newMap);
   112 
   113     static bool Compare(Type *left, Type *right);
   114 
   115     static Type *cast(Object *obj) {
   116         assert(!obj || obj->is(MapKind_Type));
   117         return (Type *)obj;
   118     }
   119 
   120     bool isPrimitive() {
   121         return kind() == PRIMITIVE;
   122     }
   123     bool isArray() {
   124         return kind() == ARRAY;
   125     }
   126     bool isReference() {
   127         return kind() == REFERENCE;
   128     }
   129     bool isFunction() {
   130         return kind() == FUNCTION || kind() == NATIVE;
   131     }
   132     bool isNative() {
   133         return kind() == NATIVE;
   134     }
   135     bool isVoid() {
   136         return kind() == VOID;
   137     }
   138     bool isUnchecked() {
   139         return kind() == UNCHECKED;
   140     }
   141     bool isStruct() {
   142         return kind() == STRUCT;
   143     }
   144     bool isNativeVariadic() {
   145         assert(isNative());
   146         return variadicNative_;
   147     }
   148     PrimitiveType primitive() {
   149         assert(isPrimitive());
   150         return primitive_;
   151     }
   152     PrimitiveType pod() {
   153         assert(isPrimitive() || isEnum());
   154         return isPrimitive()
   155                ? (primitive() == PrimitiveType_Bool)
   156                  ? PrimitiveType_Int32
   157                  : primitive()
   158                : PrimitiveType_Int32;
   159     }
   160     Type *contained() {
   161         assert(isArray() || isReference());
   162         return Type::cast(contained_);
   163     }
   164     int elements() {
   165         assert(isArray());
   166         return elements_;
   167     }
   168     unsigned levels() {
   169         assert(isArray());
   170         return levels_;
   171     }
   172     Type *innermost() {
   173         assert(isArray());
   174         Type *temp = contained();
   175         while (temp->isArray())
   176             temp = temp->contained();
   177         return temp;
   178     }
   179     bool isFloat() {
   180         return isPrimitive() && primitive() == PrimitiveType_Float;
   181     }
   182     bool isInt32() {
   183         return isPrimitive() && primitive() == PrimitiveType_Int32;
   184     }
   185     bool isInt32OrEnum() {
   186         return isInt32() || isEnum();
   187     }
   188     bool isBool() {
   189         return isPrimitive() && primitive() == PrimitiveType_Bool;
   190     }
   191     bool isCharArray() {
   192         return isArray() &&
   193                contained()->isPrimitive() &&
   194                contained()->primitive() == PrimitiveType_Char;
   195     }
   196     Type *returnType() {
   197         assert(isFunction());
   198         return returnType_;
   199     }
   200     FixedArray *parameters() {
   201         assert(isFunction());
   202         return parameters_;
   203     }
   204     Type *parameterAt(size_t i) {
   205         return Type::cast(parameters()->at(i));
   206     }
   207     bool isTraceable() {
   208         return !isPrimitive();
   209     }
   210     bool isConst() {
   211         assert(kind() == PRIMITIVE || kind() == ARRAY || kind() == REFERENCE);
   212         return const_;
   213     }
   214     bool isEnum() {
   215         return kind() == ENUM;
   216     }
   217 
   218     String *name() {
   219         assert(isEnum() || isStruct());
   220         return name_;
   221     }
   222     FixedArray *fields() {
   223         assert(isStruct());
   224         return fields_;
   225     }
   226     Descriptor *lookupField(Handle<String> name, unsigned *index);
   227 
   228     // Objects of this type can be created with this cached map.
   229     Map *newMap() {
   230         assert(isStruct() || isArray());
   231         return newMap_;
   232     }
   233     void setNewMap(Map *map) {
   234         assert(!newMap());
   235         newMap_ = map;
   236     }
   237 
   238     // GC Descriptor.
   239     static inline size_t offsetOfContained() {
   240         return OFFSETOF(Type, contained_);
   241     }
   242     static inline size_t offsetOfReturnType() {
   243         return OFFSETOF(Type, returnType_);
   244     }
   245     static inline size_t offsetOfParameters() {
   246         return OFFSETOF(Type, parameters_);
   247     }
   248     static inline size_t offsetOfName() {
   249         return OFFSETOF(Type, name_);
   250     }
   251     static inline size_t offsetOfFields() {
   252         return OFFSETOF(Type, fields_);
   253     }
   254     static inline size_t offsetOfNewMap() {
   255         return OFFSETOF(Type, newMap_);
   256     }
   257     // End GC Descriptor.
   258 
   259   private:
   260     Kind kind_;
   261     PrimitiveType primitive_;
   262 
   263     // Primitives, arrays, and references.
   264     bool const_;
   265 
   266     // Arrays only.
   267     int32 elements_;
   268     unsigned levels_;
   269 
   270     // Arrays and references only.
   271     Barriered<Type> contained_;
   272 
   273     // Functions only.
   274     Barriered<Type> returnType_;
   275     Barriered<FixedArray> parameters_;
   276     bool variadicNative_;
   277 
   278     // Enums and structs only.
   279     Barriered<String> name_;
   280 
   281     // Structs only.
   282     Barriered<FixedArray> fields_;
   283     Barriered<Map> newMap_;
   284 };
   285 
   286 class BoxedPrimitive
   287 {
   288     PrimitiveType type_;
   289     union {
   290         int i_;
   291     };
   292 
   293   public:
   294     static BoxedPrimitive Int(int i) {
   295         BoxedPrimitive b;
   296         b.type_ = PrimitiveType_Int32;
   297         b.i_ = i;
   298         return b;
   299     }
   300 
   301     PrimitiveType type() const {
   302         return type_;
   303     }
   304     int toInt() const {
   305         assert(type() == PrimitiveType_Int32);
   306         return i_;
   307     }
   308 };
   309 
   310 }
   311 
   312 #endif // _include_jc_types_h_