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 +}