src/Types.cpp
author David Anderson <dvander@alliedmods.net>
Sat Jul 28 16:42:38 2012 -0700 (2012-07-28)
changeset 108 9dcf58a17d32
parent 92 e3974e7360e9
child 124 0d7ac9ba25c2
permissions -rw-r--r--
Stop using ccache on OS X.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #include <string.h>
    19 #include "Types.h"
    20 #include "Zone.h"
    21 #include "Strings.h"
    22 #include "Heap-inl.h"
    23 
    24 using namespace ke;
    25 
    26 Type *
    27 Type::NewVoid(Zone *zone)
    28 {
    29     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    30     if (!type)
    31         return NULL;
    32 
    33     type->kind_ = VOID;
    34     type->tag_ = NULL;
    35     type->contained_ = NULL;
    36     type->returnType_ = NULL;
    37     type->parameters_ = NULL;
    38     return type;
    39 }
    40 
    41 Type *
    42 Type::NewPrimitive(Zone *zone, Handle<String> tag)
    43 {
    44     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    45     if (!type)
    46         return NULL;
    47 
    48     type->kind_ = PRIMITIVE;
    49     type->tag_ = tag;
    50     type->contained_ = NULL;
    51     type->returnType_ = NULL;
    52     type->parameters_ = NULL;
    53 
    54     if (tag && strcmp(tag->chars(), "Float") == 0)
    55         type->primitive_ = PrimitiveType_Float;
    56     else if (tag && strcmp(tag->chars(), "String") == 0)
    57         type->primitive_ = PrimitiveType_Char;
    58     else
    59         type->primitive_ = PrimitiveType_Int32;
    60     return type;
    61 }
    62 
    63 Type *
    64 Type::NewPrimitive(Zone *zone, PrimitiveType prim)
    65 {
    66     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    67     if (!type)
    68         return NULL;
    69 
    70     type->kind_ = PRIMITIVE;
    71     type->tag_ = NULL;
    72     type->contained_ = NULL;
    73     type->returnType_ = NULL;
    74     type->parameters_ = NULL;
    75     type->primitive_ = prim;
    76     return type;
    77 }
    78 
    79 Type *
    80 Type::NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst)
    81 {
    82     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    83     if (!type)
    84         return NULL;
    85 
    86     type->kind_ = ARRAY;
    87     type->tag_ = NULL;
    88     type->contained_ = contained;
    89     type->returnType_ = NULL;
    90     type->parameters_ = NULL;
    91     type->elements_ = elements;
    92     if (contained->isPrimitive())
    93         type->levels_ = 1;
    94     else
    95         type->levels_ = contained->levels() + 1;
    96     type->const_ = isConst;
    97     return type;
    98 }
    99 
   100 Type *
   101 Type::NewReference(Zone *zone, Handle<Type> contained, bool isConst)
   102 {
   103     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   104     if (!type)
   105         return NULL;
   106 
   107     type->kind_ = REFERENCE;
   108     type->tag_ = NULL;
   109     type->contained_ = contained;
   110     type->returnType_ = NULL;
   111     type->parameters_ = NULL;
   112     type->const_ = isConst;
   113     return type;
   114 }
   115 
   116 Type *
   117 Type::NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters)
   118 {
   119     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   120     if (!type)
   121         return NULL;
   122 
   123     type->kind_ = FUNCTION;
   124     type->contained_ = NULL;
   125     type->returnType_ = returnType;
   126     type->parameters_ = parameters;
   127     return type;
   128 }
   129 
   130 Type *
   131 Type::NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool variadic)
   132 {
   133     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   134     if (!type)
   135         return NULL;
   136 
   137     type->kind_ = NATIVE;
   138     type->contained_ = NULL;
   139     type->returnType_ = returnType;
   140     type->parameters_ = parameters;
   141     type->variadicNative_ = variadic;
   142     return type;
   143 }
   144 
   145 bool
   146 Type::Compare(Type *left, Type *right)
   147 {
   148     if (left->kind() != right->kind())
   149         return false;
   150 
   151     switch (left->kind()) {
   152       case Type::PRIMITIVE:
   153         return (left->primitive() == right->primitive() &&
   154                 left->tag() == right->tag());
   155 
   156       case Type::ARRAY:
   157       {
   158         if (left->levels() != right->levels())
   159           return false;
   160         if (left->elements() != right->elements())
   161           return false;
   162         return Compare(left->contained(), right->contained());
   163       }
   164 
   165       case Type::FUNCTION:
   166       {
   167         if (!Compare(left->returnType(), right->returnType()))
   168             return false;
   169         if (left->parameters()->length() != right->parameters()->length())
   170             return false;
   171         if (left->isNative() != right->isNative())
   172             return false;
   173         if (left->isNative() && (left->isNativeVariadic() != right->isNativeVariadic()))
   174             return false;
   175         for (unsigned i = 0; i < left->parameters()->length(); i++) {
   176             Type *leftparam = left->parameterAt(i);
   177             Type *rightparam = right->parameterAt(i);
   178             if (!Compare(leftparam, rightparam))
   179                 return false;
   180         }
   181         return true;
   182       }
   183 
   184       default:
   185         assert(left->kind() == Type::REFERENCE);
   186         return Compare(left->contained(), right->contained());
   187     }
   188 }