src/TypeManager.cpp
changeset 263 ba85a47ee414
parent 261 219b49bf4a03
     1.1 --- a/src/TypeManager.cpp	Mon Jun 10 00:46:29 2013 +0100
     1.2 +++ b/src/TypeManager.cpp	Mon Jun 10 01:04:43 2013 +0100
     1.3 @@ -1,167 +1,167 @@
     1.4 -/* vim: set ts=4 sw=4 tw=99 et:
     1.5 - *
     1.6 - * Copyright (C) 2012 David Anderson
     1.7 - *
     1.8 - * This file is part of SourcePawn.
     1.9 - *
    1.10 - * SourcePawn is free software: you can redistribute it and/or modify it under
    1.11 - * the terms of the GNU General Public License as published by the Free
    1.12 - * Software Foundation, either version 3 of the License, or (at your option)
    1.13 - * any later version.
    1.14 - * 
    1.15 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    1.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    1.18 - *
    1.19 - * You should have received a copy of the GNU General Public License along with
    1.20 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
    1.21 - */
    1.22 -#include <string.h>
    1.23 -#include "Types.h"
    1.24 -#include "TypeManager.h"
    1.25 -#include "Zone.h"
    1.26 -#include "Strings.h"
    1.27 -#include "Spaces-inl.h"
    1.28 -#include "Heap-inl.h"
    1.29 -
    1.30 -using namespace ke;
    1.31 -
    1.32 -
    1.33 -TypeManager::TypeManager(Zone *zone)
    1.34 -  : zone_(zone),
    1.35 -    qualTable_(ZoneAllocatorPolicy())
    1.36 -{
    1.37 -}
    1.38 -
    1.39 -bool
    1.40 -TypeManager::initialize()
    1.41 -{
    1.42 -    voidType_ = Type::NewVoid(zone_);
    1.43 -    if (!voidType_)
    1.44 -        return false;
    1.45 -
    1.46 -    uncheckedType_ = Type::NewUnchecked(zone_);
    1.47 -    if (!uncheckedType_)
    1.48 -        return false;
    1.49 -
    1.50 -    stringType_ = Type::NewString(zone_);
    1.51 -    if (!stringType_)
    1.52 -        return false;
    1.53 -
    1.54 -    importableType_ = Type::NewImportable(zone_);
    1.55 -    if (!importableType_)
    1.56 -        return false;
    1.57 -
    1.58 -    typeType_ = Type::NewType(zone_);
    1.59 -    if (!typeType_)
    1.60 -        return false;
    1.61 -
    1.62 -    if ((primitiveTypes_[PrimitiveType_Int32] = Type::NewPrimitive(zone_, PrimitiveType_Int32)) == NULL)
    1.63 -        return false;
    1.64 -    if ((primitiveTypes_[PrimitiveType_Float] = Type::NewPrimitive(zone_, PrimitiveType_Float)) == NULL)
    1.65 -        return false;
    1.66 -    if ((primitiveTypes_[PrimitiveType_Native] = Type::NewPrimitive(zone_, PrimitiveType_Native)) == NULL)
    1.67 -        return false;
    1.68 -    if ((primitiveTypes_[PrimitiveType_Char] = Type::NewPrimitive(zone_, PrimitiveType_Char)) == NULL)
    1.69 -        return false;
    1.70 -    if ((primitiveTypes_[PrimitiveType_Bool] = Type::NewPrimitive(zone_, PrimitiveType_Bool)) == NULL)
    1.71 -        return false;
    1.72 -
    1.73 -    Local<Type> type(zone_);
    1.74 -    for (unsigned i = 0; i < PrimitiveTypes_Total; i++) {
    1.75 -        type = primitiveTypes_[i];
    1.76 -        if ((referenceTypes_[i] = ReferenceType::New(zone_, type)) == NULL)
    1.77 -            return false;
    1.78 -    }
    1.79 -
    1.80 -    if (!qualTable_.init(32))
    1.81 -        return false;
    1.82 -
    1.83 -    return true;
    1.84 -}
    1.85 -
    1.86 -ArrayType *
    1.87 -TypeManager::newArray(Handle<Type> contained, int elements)
    1.88 -{
    1.89 -    // :TODO: cache this.
    1.90 -    return ArrayType::New(zone_, contained, elements);
    1.91 -}
    1.92 -
    1.93 -ArrayType *
    1.94 -TypeManager::newExternalArray(Handle<Type> contained)
    1.95 -{
    1.96 -    return ArrayType::NewExternal(zone_, contained);
    1.97 -}
    1.98 -
    1.99 -ReferenceType *
   1.100 -TypeManager::getReference(Handle<Type> type, bool isConst)
   1.101 -{
   1.102 -    if (!isConst && type->isPrimitive())
   1.103 -        return referenceTypes_[type->primitive()];
   1.104 -
   1.105 -    // :TODO: cache this.
   1.106 -    return ReferenceType::New(zone_, type);
   1.107 -}
   1.108 -
   1.109 -EnumType *
   1.110 -TypeManager::newEnum(Handle<String> name)
   1.111 -{
   1.112 -    return EnumType::New(zone_, name);
   1.113 -}
   1.114 -
   1.115 -Type *
   1.116 -TypeManager::qualify(Handle<Type> argType, TypeQualifiers quals)
   1.117 -{
   1.118 -    Local<Type> type(zone_, argType->unqualified());
   1.119 -
   1.120 -    if (!quals)
   1.121 -        return type;
   1.122 -
   1.123 -    LookupKey key(type, quals);
   1.124 -
   1.125 -    // We can't use findForAdd because a GC could rehash the table.
   1.126 -    TypeHashTable::Result r = qualTable_.find(key);
   1.127 -    if (r.found())
   1.128 -        return *r;
   1.129 -
   1.130 -    Type *quald = Type::NewQualified(zone_, quals, type);
   1.131 -    if (!quald)
   1.132 -        return NULL;
   1.133 -
   1.134 -    // :TODO: assert-no-gc
   1.135 -    TypeHashTable::Insert i = qualTable_.findForAdd(key);
   1.136 -    assert(!i.found());
   1.137 -
   1.138 -    if (!qualTable_.add(i, quald))
   1.139 -        return NULL;
   1.140 -
   1.141 -    return quald;
   1.142 -}
   1.143 -
   1.144 -void
   1.145 -TypeManager::accept(VirtualObjectVisitor *visitor)
   1.146 -{
   1.147 -    visitor->visit(voidType_.address());
   1.148 -    visitor->visit(uncheckedType_.address());
   1.149 -    visitor->visit(stringType_.address());
   1.150 -    visitor->visit(importableType_.address());
   1.151 -    visitor->visit(typeType_.address());
   1.152 -    for (unsigned i = 0; i < PrimitiveTypes_Total; i++) {
   1.153 -        visitor->visit(primitiveTypes_[i].address());
   1.154 -        visitor->visit(referenceTypes_[i].address());
   1.155 -    }
   1.156 -}
   1.157 -
   1.158 -void
   1.159 -TypeManager::sweep()
   1.160 -{
   1.161 -    for (TypeHashTable::iterator i(&qualTable_); !i.empty(); i.next()) {
   1.162 -        Type *obj = *i;
   1.163 -        MarkBit bits = HeapChunk::GetMarkBit(obj);
   1.164 -        if (HeapChunk::IsWhite(bits))
   1.165 -            i.erase();
   1.166 -        else
   1.167 -            assert(HeapChunk::IsBlack(bits));
   1.168 -    }
   1.169 -    qualTable_.checkDensity();
   1.170 -}
   1.171 +/* vim: set ts=4 sw=4 tw=99 et:
   1.172 + *
   1.173 + * Copyright (C) 2012 David Anderson
   1.174 + *
   1.175 + * This file is part of SourcePawn.
   1.176 + *
   1.177 + * SourcePawn is free software: you can redistribute it and/or modify it under
   1.178 + * the terms of the GNU General Public License as published by the Free
   1.179 + * Software Foundation, either version 3 of the License, or (at your option)
   1.180 + * any later version.
   1.181 + * 
   1.182 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   1.183 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   1.184 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   1.185 + *
   1.186 + * You should have received a copy of the GNU General Public License along with
   1.187 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
   1.188 + */
   1.189 +#include <string.h>
   1.190 +#include "Types.h"
   1.191 +#include "TypeManager.h"
   1.192 +#include "Zone.h"
   1.193 +#include "Strings.h"
   1.194 +#include "Spaces-inl.h"
   1.195 +#include "Heap-inl.h"
   1.196 +
   1.197 +using namespace ke;
   1.198 +
   1.199 +
   1.200 +TypeManager::TypeManager(Zone *zone)
   1.201 +  : zone_(zone),
   1.202 +    qualTable_(ZoneAllocatorPolicy())
   1.203 +{
   1.204 +}
   1.205 +
   1.206 +bool
   1.207 +TypeManager::initialize()
   1.208 +{
   1.209 +    voidType_ = Type::NewVoid(zone_);
   1.210 +    if (!voidType_)
   1.211 +        return false;
   1.212 +
   1.213 +    uncheckedType_ = Type::NewUnchecked(zone_);
   1.214 +    if (!uncheckedType_)
   1.215 +        return false;
   1.216 +
   1.217 +    stringType_ = Type::NewString(zone_);
   1.218 +    if (!stringType_)
   1.219 +        return false;
   1.220 +
   1.221 +    importableType_ = Type::NewImportable(zone_);
   1.222 +    if (!importableType_)
   1.223 +        return false;
   1.224 +
   1.225 +    typeType_ = Type::NewType(zone_);
   1.226 +    if (!typeType_)
   1.227 +        return false;
   1.228 +
   1.229 +    if ((primitiveTypes_[PrimitiveType_Int32] = Type::NewPrimitive(zone_, PrimitiveType_Int32)) == NULL)
   1.230 +        return false;
   1.231 +    if ((primitiveTypes_[PrimitiveType_Float] = Type::NewPrimitive(zone_, PrimitiveType_Float)) == NULL)
   1.232 +        return false;
   1.233 +    if ((primitiveTypes_[PrimitiveType_Native] = Type::NewPrimitive(zone_, PrimitiveType_Native)) == NULL)
   1.234 +        return false;
   1.235 +    if ((primitiveTypes_[PrimitiveType_Char] = Type::NewPrimitive(zone_, PrimitiveType_Char)) == NULL)
   1.236 +        return false;
   1.237 +    if ((primitiveTypes_[PrimitiveType_Bool] = Type::NewPrimitive(zone_, PrimitiveType_Bool)) == NULL)
   1.238 +        return false;
   1.239 +
   1.240 +    Local<Type> type(zone_);
   1.241 +    for (unsigned i = 0; i < PrimitiveTypes_Total; i++) {
   1.242 +        type = primitiveTypes_[i];
   1.243 +        if ((referenceTypes_[i] = ReferenceType::New(zone_, type)) == NULL)
   1.244 +            return false;
   1.245 +    }
   1.246 +
   1.247 +    if (!qualTable_.init(32))
   1.248 +        return false;
   1.249 +
   1.250 +    return true;
   1.251 +}
   1.252 +
   1.253 +ArrayType *
   1.254 +TypeManager::newArray(Handle<Type> contained, int elements)
   1.255 +{
   1.256 +    // :TODO: cache this.
   1.257 +    return ArrayType::New(zone_, contained, elements);
   1.258 +}
   1.259 +
   1.260 +ArrayType *
   1.261 +TypeManager::newExternalArray(Handle<Type> contained)
   1.262 +{
   1.263 +    return ArrayType::NewExternal(zone_, contained);
   1.264 +}
   1.265 +
   1.266 +ReferenceType *
   1.267 +TypeManager::getReference(Handle<Type> type, bool isConst)
   1.268 +{
   1.269 +    if (!isConst && type->isPrimitive())
   1.270 +        return referenceTypes_[type->primitive()];
   1.271 +
   1.272 +    // :TODO: cache this.
   1.273 +    return ReferenceType::New(zone_, type);
   1.274 +}
   1.275 +
   1.276 +EnumType *
   1.277 +TypeManager::newEnum(Handle<String> name)
   1.278 +{
   1.279 +    return EnumType::New(zone_, name);
   1.280 +}
   1.281 +
   1.282 +Type *
   1.283 +TypeManager::qualify(Handle<Type> argType, TypeQualifiers quals)
   1.284 +{
   1.285 +    Local<Type> type(zone_, argType->unqualified());
   1.286 +
   1.287 +    if (!quals)
   1.288 +        return type;
   1.289 +
   1.290 +    LookupKey key(type, quals);
   1.291 +
   1.292 +    // We can't use findForAdd because a GC could rehash the table.
   1.293 +    TypeHashTable::Result r = qualTable_.find(key);
   1.294 +    if (r.found())
   1.295 +        return *r;
   1.296 +
   1.297 +    Type *quald = Type::NewQualified(zone_, quals, type);
   1.298 +    if (!quald)
   1.299 +        return NULL;
   1.300 +
   1.301 +    // :TODO: assert-no-gc
   1.302 +    TypeHashTable::Insert i = qualTable_.findForAdd(key);
   1.303 +    assert(!i.found());
   1.304 +
   1.305 +    if (!qualTable_.add(i, quald))
   1.306 +        return NULL;
   1.307 +
   1.308 +    return quald;
   1.309 +}
   1.310 +
   1.311 +void
   1.312 +TypeManager::accept(VirtualObjectVisitor *visitor)
   1.313 +{
   1.314 +    visitor->visit(voidType_.address());
   1.315 +    visitor->visit(uncheckedType_.address());
   1.316 +    visitor->visit(stringType_.address());
   1.317 +    visitor->visit(importableType_.address());
   1.318 +    visitor->visit(typeType_.address());
   1.319 +    for (unsigned i = 0; i < PrimitiveTypes_Total; i++) {
   1.320 +        visitor->visit(primitiveTypes_[i].address());
   1.321 +        visitor->visit(referenceTypes_[i].address());
   1.322 +    }
   1.323 +}
   1.324 +
   1.325 +void
   1.326 +TypeManager::sweep()
   1.327 +{
   1.328 +    for (TypeHashTable::iterator i(&qualTable_); !i.empty(); i.next()) {
   1.329 +        Type *obj = *i;
   1.330 +        MarkBit bits = HeapChunk::GetMarkBit(obj);
   1.331 +        if (HeapChunk::IsWhite(bits))
   1.332 +            i.erase();
   1.333 +        else
   1.334 +            assert(HeapChunk::IsBlack(bits));
   1.335 +    }
   1.336 +    qualTable_.checkDensity();
   1.337 +}