jitcraft/Types.cpp
author David Anderson <dvander@alliedmods.net>
Sat Jul 14 18:43:34 2012 -0700 (2012-07-14)
changeset 71 f7e573226c2b
parent 69 dfce0539a77d
permissions -rw-r--r--
Added definite return analysis and void-return deduction.
     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 "Types.h"
    19 #include "Zone.h"
    20 #include "Strings.h"
    21 #include "Heap-inl.h"
    22 
    23 using namespace ke;
    24 
    25 Type *
    26 Type::NewVoid(Zone *zone)
    27 {
    28     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    29     if (!type)
    30         return NULL;
    31 
    32     type->kind_ = VOID;
    33     type->tag_ = NULL;
    34     type->contained_ = NULL;
    35     type->returnType_ = NULL;
    36     type->parameters_ = NULL;
    37     return type;
    38 }
    39 
    40 Type *
    41 Type::NewPrimitive(Zone *zone, Handle<String> tag)
    42 {
    43     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    44     if (!type)
    45         return NULL;
    46 
    47     type->kind_ = PRIMITIVE;
    48     type->tag_ = tag;
    49     type->contained_ = NULL;
    50     type->returnType_ = NULL;
    51     type->parameters_ = NULL;
    52 
    53     if (tag && strcmp(tag->chars(), "Float") == 0)
    54         type->primitive_ = PrimitiveType_Float;
    55     else if (tag && strcmp(tag->chars(), "String") == 0)
    56         type->primitive_ = PrimitiveType_Char;
    57     else
    58         type->primitive_ = PrimitiveType_Int32;
    59     return type;
    60 }
    61 
    62 Type *
    63 Type::NewPrimitive(Zone *zone, PrimitiveType prim)
    64 {
    65     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    66     if (!type)
    67         return NULL;
    68 
    69     type->kind_ = PRIMITIVE;
    70     type->tag_ = NULL;
    71     type->contained_ = NULL;
    72     type->returnType_ = NULL;
    73     type->parameters_ = NULL;
    74     type->primitive_ = prim;
    75     return type;
    76 }
    77 
    78 Type *
    79 Type::NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst)
    80 {
    81     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    82     if (!type)
    83         return NULL;
    84 
    85     type->kind_ = ARRAY;
    86     type->tag_ = NULL;
    87     type->contained_ = contained;
    88     type->returnType_ = NULL;
    89     type->parameters_ = NULL;
    90     type->elements_ = elements;
    91     if (contained->isPrimitive())
    92         type->levels_ = 1;
    93     else
    94         type->levels_ = contained->levels() + 1;
    95     type->const_ = isConst;
    96     return type;
    97 }
    98 
    99 Type *
   100 Type::NewReference(Zone *zone, Handle<Type> contained, bool isConst)
   101 {
   102     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   103     if (!type)
   104         return NULL;
   105 
   106     type->kind_ = REFERENCE;
   107     type->tag_ = NULL;
   108     type->contained_ = contained;
   109     type->returnType_ = NULL;
   110     type->parameters_ = NULL;
   111     type->const_ = isConst;
   112     return type;
   113 }
   114 
   115 Type *
   116 Type::NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters)
   117 {
   118     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   119     if (!type)
   120         return NULL;
   121 
   122     type->kind_ = FUNCTION;
   123     type->contained_ = NULL;
   124     type->returnType_ = returnType;
   125     type->parameters_ = parameters;
   126     return type;
   127 }
   128 
   129 Type *
   130 Type::NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool variadic)
   131 {
   132     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   133     if (!type)
   134         return NULL;
   135 
   136     type->kind_ = NATIVE;
   137     type->contained_ = NULL;
   138     type->returnType_ = returnType;
   139     type->parameters_ = parameters;
   140     type->variadicNative_ = variadic;
   141     return type;
   142 }
   143 
   144 bool
   145 Type::Compare(Type *left, Type *right)
   146 {
   147     if (left->kind() != right->kind())
   148         return false;
   149 
   150     switch (left->kind()) {
   151       case Type::PRIMITIVE:
   152         return (left->primitive() == right->primitive() &&
   153                 left->tag() == right->tag());
   154 
   155       case Type::ARRAY:
   156       {
   157         if (left->levels() != right->levels())
   158           return false;
   159         if (left->elements() != right->elements())
   160           return false;
   161         return Compare(left->contained(), right->contained());
   162       }
   163 
   164       case Type::FUNCTION:
   165       {
   166         if (!Compare(left->returnType(), right->returnType()))
   167             return false;
   168         if (left->parameters()->length() != right->parameters()->length())
   169             return false;
   170         if (left->isNative() != right->isNative())
   171             return false;
   172         if (left->isNative() && (left->isNativeVariadic() != right->isNativeVariadic()))
   173             return false;
   174         for (unsigned i = 0; i < left->parameters()->length(); i++) {
   175             Type *leftparam = left->parameterAt(i);
   176             Type *rightparam = right->parameterAt(i);
   177             if (!Compare(leftparam, rightparam))
   178                 return false;
   179         }
   180         return true;
   181       }
   182 
   183       default:
   184         assert(left->kind() == Type::REFERENCE);
   185         return Compare(left->contained(), right->contained());
   186     }
   187 }