Add support for mutually recursive imports.
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/.
19 #ifndef _include_jitcraft_array_h_
20 #define _include_jitcraft_array_h_
25 #include "FixedArray.h"
31 class Array : public Object
33 friend class ArrayMap;
36 // Note: we do not write barrier |elements_|, since it can be set to
37 // arbitrary pointers.
45 void updateLengthAndElements(Zone *zone, unsigned length, Object *array) {
47 write(zone, &objelements_, array);
51 static Array *NewFixed(Zone *zone, Handle<ArrayMap> map, Heap::Tenure = Heap::Tenure_Default);
52 static Array *NewString(Zone *zone, Handle<ArrayMap> map, char *buffer, size_t length, Heap::Tenure = Heap::Tenure_Default);
53 static Array *NewSized(Zone *zone, Handle<ArrayMap> map, int sizes[MAX_ARRAY_DEPTH], Heap::Tenure = Heap::Tenure_Default);
55 static Array *New1D(Zone *zone, Handle<ArrayMap> map, uint32 elements, Heap::Tenure tenure = Heap::Tenure_Default);
56 static Array *NewEmpty(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
57 static Array *NewRaw(Zone *zone, Handle<ArrayMap> map, unsigned nelements, Heap::Tenure tenure);
59 static Array *NewExternal(Zone *zone,
63 Heap::Tenure tenure = Heap::Tenure_Default);
65 // Copies an array from one reference to another, obeying language semantics.
66 static bool ShallowCopy(Zone *zone, Handle<Array> dest, Handle<Array> source);
68 // Creates a full duplicate of an array, following all array references as if
69 // they were fixed. Array references inside structs or objects use ShallowCopy
70 // semantics, as this is only intended for duplicating array literals, which
71 // cannot contain structs.
72 static Array *DeepCopy(Zone *zone, Handle<Array> source, Heap::Tenure tenure);
78 inline ArrayType *type();
80 inline int *int32Vec();
81 inline float *floatVec();
85 bool resize(Zone *zone, size_t newLength);
87 static inline size_t SizeForElement(ArrayType *type) {
88 if (type->contained()->isTraceable())
89 return sizeof(ke::Object *);
90 if (type->contained()->isInt32())
92 if (type->contained()->primitive() == PrimitiveType_Char)
94 assert(type->contained()->isFloat());
98 inline size_t objSize(ArrayMap *map);
100 int readInt32(size_t index) {
101 assert(index < length());
102 return int32Vec()[index];
104 void writeInt32(size_t index, int i) {
105 assert(index < length());
106 int32Vec()[index] = i;
108 char readChar(size_t index) {
109 assert(index < length());
110 return chars()[index];
112 void writeChar(size_t index, char c) {
113 assert(index < length());
116 float readFloat(size_t index) {
117 assert(index < length());
118 return floatVec()[index];
120 void writeFloat(size_t index, float f) {
121 assert(index < length());
122 floatVec()[index] = f;
124 Object *readObject(size_t index) {
125 return FixedArray::cast(objelements_)->at(index);
127 void writeObject(Zone *zone, size_t index, Object *ptr) {
128 FixedArray::cast(objelements_)->set(zone, index, ptr);
132 static inline size_t offsetOfElements() {
133 return offsetof(Array, objelements_);
135 // End GC Descriptor.
137 static Array *cast(Object *obj) {
139 obj->is(MapKind_Array) ||
140 obj->is(MapKind_DependentArray));
141 return reinterpret_cast<Array *>(obj);
145 class DependentArray : public Array
147 Barriered<Array> root_;
150 static Array *New(Zone *zone, Handle<Array> source, Handle<ArrayMap> map, unsigned index);
153 static inline size_t offsetOfRoot() {
154 return offsetof(DependentArray, root_);
156 // End GC Descriptor.
158 static DependentArray *cast(Object *obj) {
159 assert(!obj || obj->is(MapKind_DependentArray));
160 return reinterpret_cast<DependentArray *>(obj);
164 class ArrayMap : public Map
166 Barriered<ArrayType> type_;
169 static ArrayMap *New(Zone *zone, Handle<ArrayType> type);
171 // DependentArray maps are never attached, and are just free-floating,
172 // rooted ultimately by the bytecode. A :TODO: that we might need to
173 // cache these, or attach them somewhere saner like ArrayType, which
174 // itself will eventually be cached.
175 static ArrayMap *NewDependent(Zone *zone, Handle<ArrayType> type);
182 static inline size_t offsetOfType() {
183 return OFFSETOF(ArrayMap, type_);
185 // End GC Descriptor.
187 static ArrayMap *cast(Object *obj) {
188 assert(!obj || obj->is(MapKind_MetaArray));
189 return reinterpret_cast<ArrayMap *>(obj);
196 assert(!type()->contained()->isTraceable());
197 assert(type()->hasInlineElements() ||
198 type()->isExternalArray() ||
199 is(MapKind_DependentArray) ||
201 ByteArray::cast((Object *)elements_));
203 return Address(elements_) + ByteArray::offsetToElements();
209 assert(type()->contained()->isInt32());
210 return reinterpret_cast<int *>(bytes());
216 assert(type()->contained()->isFloat());
217 return reinterpret_cast<float *>(bytes());
223 assert(type()->isCharArray());
224 return reinterpret_cast<char *>(bytes());
230 return ArrayMap::cast(map())->type();
234 Array::objSize(ArrayMap *map)
236 assert(this->map() == map);
237 if (map->type()->hasInlineElements())
238 return sizeof(Array) + Array::SizeForElement(map->type()) * length();
239 return sizeof(Array);
244 #endif // _include_jitcraft_array_h_