diff -r c4b1341297e5 -r ba85a47ee414 src/TypeManager.cpp --- a/src/TypeManager.cpp Mon Jun 10 00:46:29 2013 +0100 +++ b/src/TypeManager.cpp Mon Jun 10 01:04:43 2013 +0100 @@ -1,167 +1,167 @@ -/* vim: set ts=4 sw=4 tw=99 et: - * - * Copyright (C) 2012 David Anderson - * - * This file is part of SourcePawn. - * - * SourcePawn is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * SourcePawn. If not, see http://www.gnu.org/licenses/. - */ -#include -#include "Types.h" -#include "TypeManager.h" -#include "Zone.h" -#include "Strings.h" -#include "Spaces-inl.h" -#include "Heap-inl.h" - -using namespace ke; - - -TypeManager::TypeManager(Zone *zone) - : zone_(zone), - qualTable_(ZoneAllocatorPolicy()) -{ -} - -bool -TypeManager::initialize() -{ - voidType_ = Type::NewVoid(zone_); - if (!voidType_) - return false; - - uncheckedType_ = Type::NewUnchecked(zone_); - if (!uncheckedType_) - return false; - - stringType_ = Type::NewString(zone_); - if (!stringType_) - return false; - - importableType_ = Type::NewImportable(zone_); - if (!importableType_) - return false; - - typeType_ = Type::NewType(zone_); - if (!typeType_) - return false; - - if ((primitiveTypes_[PrimitiveType_Int32] = Type::NewPrimitive(zone_, PrimitiveType_Int32)) == NULL) - return false; - if ((primitiveTypes_[PrimitiveType_Float] = Type::NewPrimitive(zone_, PrimitiveType_Float)) == NULL) - return false; - if ((primitiveTypes_[PrimitiveType_Native] = Type::NewPrimitive(zone_, PrimitiveType_Native)) == NULL) - return false; - if ((primitiveTypes_[PrimitiveType_Char] = Type::NewPrimitive(zone_, PrimitiveType_Char)) == NULL) - return false; - if ((primitiveTypes_[PrimitiveType_Bool] = Type::NewPrimitive(zone_, PrimitiveType_Bool)) == NULL) - return false; - - Local type(zone_); - for (unsigned i = 0; i < PrimitiveTypes_Total; i++) { - type = primitiveTypes_[i]; - if ((referenceTypes_[i] = ReferenceType::New(zone_, type)) == NULL) - return false; - } - - if (!qualTable_.init(32)) - return false; - - return true; -} - -ArrayType * -TypeManager::newArray(Handle contained, int elements) -{ - // :TODO: cache this. - return ArrayType::New(zone_, contained, elements); -} - -ArrayType * -TypeManager::newExternalArray(Handle contained) -{ - return ArrayType::NewExternal(zone_, contained); -} - -ReferenceType * -TypeManager::getReference(Handle type, bool isConst) -{ - if (!isConst && type->isPrimitive()) - return referenceTypes_[type->primitive()]; - - // :TODO: cache this. - return ReferenceType::New(zone_, type); -} - -EnumType * -TypeManager::newEnum(Handle name) -{ - return EnumType::New(zone_, name); -} - -Type * -TypeManager::qualify(Handle argType, TypeQualifiers quals) -{ - Local type(zone_, argType->unqualified()); - - if (!quals) - return type; - - LookupKey key(type, quals); - - // We can't use findForAdd because a GC could rehash the table. - TypeHashTable::Result r = qualTable_.find(key); - if (r.found()) - return *r; - - Type *quald = Type::NewQualified(zone_, quals, type); - if (!quald) - return NULL; - - // :TODO: assert-no-gc - TypeHashTable::Insert i = qualTable_.findForAdd(key); - assert(!i.found()); - - if (!qualTable_.add(i, quald)) - return NULL; - - return quald; -} - -void -TypeManager::accept(VirtualObjectVisitor *visitor) -{ - visitor->visit(voidType_.address()); - visitor->visit(uncheckedType_.address()); - visitor->visit(stringType_.address()); - visitor->visit(importableType_.address()); - visitor->visit(typeType_.address()); - for (unsigned i = 0; i < PrimitiveTypes_Total; i++) { - visitor->visit(primitiveTypes_[i].address()); - visitor->visit(referenceTypes_[i].address()); - } -} - -void -TypeManager::sweep() -{ - for (TypeHashTable::iterator i(&qualTable_); !i.empty(); i.next()) { - Type *obj = *i; - MarkBit bits = HeapChunk::GetMarkBit(obj); - if (HeapChunk::IsWhite(bits)) - i.erase(); - else - assert(HeapChunk::IsBlack(bits)); - } - qualTable_.checkDensity(); -} +/* vim: set ts=4 sw=4 tw=99 et: + * + * Copyright (C) 2012 David Anderson + * + * This file is part of SourcePawn. + * + * SourcePawn is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * SourcePawn. If not, see http://www.gnu.org/licenses/. + */ +#include +#include "Types.h" +#include "TypeManager.h" +#include "Zone.h" +#include "Strings.h" +#include "Spaces-inl.h" +#include "Heap-inl.h" + +using namespace ke; + + +TypeManager::TypeManager(Zone *zone) + : zone_(zone), + qualTable_(ZoneAllocatorPolicy()) +{ +} + +bool +TypeManager::initialize() +{ + voidType_ = Type::NewVoid(zone_); + if (!voidType_) + return false; + + uncheckedType_ = Type::NewUnchecked(zone_); + if (!uncheckedType_) + return false; + + stringType_ = Type::NewString(zone_); + if (!stringType_) + return false; + + importableType_ = Type::NewImportable(zone_); + if (!importableType_) + return false; + + typeType_ = Type::NewType(zone_); + if (!typeType_) + return false; + + if ((primitiveTypes_[PrimitiveType_Int32] = Type::NewPrimitive(zone_, PrimitiveType_Int32)) == NULL) + return false; + if ((primitiveTypes_[PrimitiveType_Float] = Type::NewPrimitive(zone_, PrimitiveType_Float)) == NULL) + return false; + if ((primitiveTypes_[PrimitiveType_Native] = Type::NewPrimitive(zone_, PrimitiveType_Native)) == NULL) + return false; + if ((primitiveTypes_[PrimitiveType_Char] = Type::NewPrimitive(zone_, PrimitiveType_Char)) == NULL) + return false; + if ((primitiveTypes_[PrimitiveType_Bool] = Type::NewPrimitive(zone_, PrimitiveType_Bool)) == NULL) + return false; + + Local type(zone_); + for (unsigned i = 0; i < PrimitiveTypes_Total; i++) { + type = primitiveTypes_[i]; + if ((referenceTypes_[i] = ReferenceType::New(zone_, type)) == NULL) + return false; + } + + if (!qualTable_.init(32)) + return false; + + return true; +} + +ArrayType * +TypeManager::newArray(Handle contained, int elements) +{ + // :TODO: cache this. + return ArrayType::New(zone_, contained, elements); +} + +ArrayType * +TypeManager::newExternalArray(Handle contained) +{ + return ArrayType::NewExternal(zone_, contained); +} + +ReferenceType * +TypeManager::getReference(Handle type, bool isConst) +{ + if (!isConst && type->isPrimitive()) + return referenceTypes_[type->primitive()]; + + // :TODO: cache this. + return ReferenceType::New(zone_, type); +} + +EnumType * +TypeManager::newEnum(Handle name) +{ + return EnumType::New(zone_, name); +} + +Type * +TypeManager::qualify(Handle argType, TypeQualifiers quals) +{ + Local type(zone_, argType->unqualified()); + + if (!quals) + return type; + + LookupKey key(type, quals); + + // We can't use findForAdd because a GC could rehash the table. + TypeHashTable::Result r = qualTable_.find(key); + if (r.found()) + return *r; + + Type *quald = Type::NewQualified(zone_, quals, type); + if (!quald) + return NULL; + + // :TODO: assert-no-gc + TypeHashTable::Insert i = qualTable_.findForAdd(key); + assert(!i.found()); + + if (!qualTable_.add(i, quald)) + return NULL; + + return quald; +} + +void +TypeManager::accept(VirtualObjectVisitor *visitor) +{ + visitor->visit(voidType_.address()); + visitor->visit(uncheckedType_.address()); + visitor->visit(stringType_.address()); + visitor->visit(importableType_.address()); + visitor->visit(typeType_.address()); + for (unsigned i = 0; i < PrimitiveTypes_Total; i++) { + visitor->visit(primitiveTypes_[i].address()); + visitor->visit(referenceTypes_[i].address()); + } +} + +void +TypeManager::sweep() +{ + for (TypeHashTable::iterator i(&qualTable_); !i.empty(); i.next()) { + Type *obj = *i; + MarkBit bits = HeapChunk::GetMarkBit(obj); + if (HeapChunk::IsWhite(bits)) + i.erase(); + else + assert(HeapChunk::IsBlack(bits)); + } + qualTable_.checkDensity(); +}