Add weak hashtable to manage qual types.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of SourcePawn.
7 * SourcePawn is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * SourcePawn. If not, see http://www.gnu.org/licenses/.
23 #include "Structures.h"
29 Type::init(Kind kind, Type *root)
32 this->root_ = root ? root : this;
36 Type::NewVoid(Zone *zone)
38 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
47 Type::NewString(Zone *zone)
49 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
58 Type::NewUnchecked(Zone *zone)
60 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
64 type->init(UNCHECKED);
69 Type::NewPrimitive(Zone *zone, PrimitiveType prim)
71 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
75 type->init(PRIMITIVE);
76 type->primitive_ = prim;
81 Type::NewQualified(Zone *zone, TypeQualifiers qual, Handle<Type> root)
83 Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
87 type->init(QUALTYPE, root);
93 ArrayType::New(Zone *zone, Handle<Type> contained, int elements)
95 if (contained->isArray() &&
96 ArrayType::cast(contained)->levels() == MAX_ARRAY_DEPTH)
98 zone->reportError(Message_MaximumArrayDepth);
102 Local<ArrayType> type(zone, (ArrayType *)zone->allocate(MapKind_ArrayType, sizeof(ArrayType), Heap::Tenure_Old));
107 type->contained_ = contained;
108 type->elements_ = elements;
109 if (!contained->isArray())
112 type->levels_ = ArrayType::cast(contained)->levels() + 1;
117 ArrayType::NewExternal(Zone *zone, Handle<Type> contained)
119 Local<ArrayType> type(zone, (ArrayType *)zone->allocate(MapKind_ArrayType, sizeof(ArrayType), Heap::Tenure_Old));
123 assert(contained->isPrimitive());
125 type->init(EXTERNAL_ARRAY);
126 type->contained_ = contained;
127 type->elements_ = DYNAMIC_ARRAY_SIZE;
133 ReferenceType::New(Zone *zone, Handle<Type> contained)
135 Local<ReferenceType> type(zone, (ReferenceType *)zone->allocate(MapKind_ReferenceType, sizeof(ReferenceType), Heap::Tenure_Old));
139 type->init(REFERENCE);
140 type->contained_ = contained;
145 EnumType::New(Zone *zone, Handle<String> name)
147 Local<EnumType> type(zone, (EnumType *)zone->allocate(MapKind_EnumType, sizeof(EnumType), Heap::Tenure_Old));
157 StructType::New(Zone *zone, Handle<String> name, Handle<FixedArray> fields)
159 Local<StructType> type(zone, (StructType *)zone->allocate(MapKind_StructType, sizeof(StructType), Heap::Tenure_Old));
164 type->newMap_ = NULL;
165 type->fields_ = fields;
168 // Fill in field offsets.
169 StructureBufferBuilder builder;
170 Local<Type> fieldType(zone);
171 for (size_t i = 0; i < fields->length(); i++) {
172 Descriptor *desc = Descriptor::cast(fields->at(i));
173 fieldType = desc->type();
176 if (!builder.add(fieldType, &offset))
178 desc->setOffset(offset);
181 Local<StructMap> map(zone, StructMap::New(zone, builder, type));
191 StructType::lookupField(Handle<String> name, unsigned *index)
193 for (unsigned i = 0; i < fields_->length(); i++) {
194 Descriptor *desc = Descriptor::cast(fields_->at(i));
195 if (desc->name() == name) {
206 FunctionType::New(Zone *zone, Handle<String> name, TokenKind token)
208 Local<FunctionType> type(zone, (FunctionType *)zone->allocate(MapKind_FunctionType, sizeof(FunctionType), Heap::Tenure_Old));
212 type->init(FUNCTION);
213 type->parameters_ = NULL;
214 type->defaults_ = NULL;
215 type->returnType_ = NULL;
217 type->token_ = token;
221 // :TODO: this leaks an interior pointer.
223 ke::GetTypeName(Type *type)
227 if (type->isFunction())
232 return EnumType::cast(type)->name()->chars();
233 if (type->isStruct())
234 return StructType::cast(type)->name()->chars();
235 if (type->isReference())
236 type = ReferenceType::cast(type)->contained();
237 switch (type->primitive()) {
238 case PrimitiveType_Bool:
240 case PrimitiveType_Char:
242 case PrimitiveType_Int32:
244 case PrimitiveType_Float: