jitcraft/Types.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jul 10 02:11:13 2012 -0700 (2012-07-10)
changeset 68 b40b0e18a918
parent 67 b765a6383849
child 69 dfce0539a77d
permissions -rw-r--r--
Added support for ISourcePawnEngine natives.
     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::NewPrimitive(Zone *zone, Handle<String> tag)
    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_ = PRIMITIVE;
    33     type->tag_ = tag;
    34     type->contained_ = NULL;
    35     type->returnType_ = NULL;
    36     type->parameters_ = NULL;
    37 
    38     if (tag && strcmp(tag->chars(), "Float") == 0)
    39         type->primitive_ = PrimitiveType_Float;
    40     else if (tag && strcmp(tag->chars(), "String") == 0)
    41         type->primitive_ = PrimitiveType_Char;
    42     else
    43         type->primitive_ = PrimitiveType_Int32;
    44     return type;
    45 }
    46 
    47 Type *
    48 Type::NewPrimitive(Zone *zone, PrimitiveType prim)
    49 {
    50     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    51     if (!type)
    52         return NULL;
    53 
    54     type->kind_ = PRIMITIVE;
    55     type->tag_ = NULL;
    56     type->contained_ = NULL;
    57     type->returnType_ = NULL;
    58     type->parameters_ = NULL;
    59     type->primitive_ = prim;
    60     return type;
    61 }
    62 
    63 Type *
    64 Type::NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst)
    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_ = ARRAY;
    71     type->tag_ = NULL;
    72     type->contained_ = contained;
    73     type->returnType_ = NULL;
    74     type->parameters_ = NULL;
    75     type->elements_ = elements;
    76     if (contained->isPrimitive())
    77         type->levels_ = 1;
    78     else
    79         type->levels_ = contained->levels() + 1;
    80     type->const_ = isConst;
    81     return type;
    82 }
    83 
    84 Type *
    85 Type::NewReference(Zone *zone, Handle<Type> contained, bool isConst)
    86 {
    87     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    88     if (!type)
    89         return NULL;
    90 
    91     type->kind_ = REFERENCE;
    92     type->tag_ = NULL;
    93     type->contained_ = contained;
    94     type->returnType_ = NULL;
    95     type->parameters_ = NULL;
    96     type->const_ = isConst;
    97     return type;
    98 }
    99 
   100 Type *
   101 Type::NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters)
   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_ = FUNCTION;
   108     type->contained_ = NULL;
   109     type->returnType_ = returnType;
   110     type->parameters_ = parameters;
   111     return type;
   112 }
   113 
   114 Type *
   115 Type::NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool variadic)
   116 {
   117     Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   118     if (!type)
   119         return NULL;
   120 
   121     type->kind_ = NATIVE;
   122     type->contained_ = NULL;
   123     type->returnType_ = returnType;
   124     type->parameters_ = parameters;
   125     type->variadicNative_ = variadic;
   126     return type;
   127 }
   128 
   129 bool
   130 Type::Compare(Type *left, Type *right)
   131 {
   132     if (left->kind() != right->kind())
   133         return false;
   134 
   135     switch (left->kind()) {
   136       case Type::PRIMITIVE:
   137         return (left->primitive() == right->primitive() &&
   138                 left->tag() == right->tag());
   139 
   140       case Type::ARRAY:
   141       {
   142         if (left->levels() != right->levels())
   143           return false;
   144         if (left->elements() != right->elements())
   145           return false;
   146         return Compare(left->contained(), right->contained());
   147       }
   148 
   149       case Type::FUNCTION:
   150       {
   151         if (!Compare(left->returnType(), right->returnType()))
   152             return false;
   153         if (left->parameters()->length() != right->parameters()->length())
   154             return false;
   155         for (unsigned i = 0; i < left->parameters()->length(); i++) {
   156             Type *leftparam = left->parameterAt(i);
   157             Type *rightparam = right->parameterAt(i);
   158             if (!Compare(leftparam, rightparam))
   159                 return false;
   160         }
   161         return true;
   162       }
   163 
   164       default:
   165         assert(left->kind() == Type::REFERENCE);
   166         return Compare(left->contained(), right->contained());
   167     }
   168 }