Fixed type checking for multidimensional arrays.
2 * Copyright (C) 2012 David Anderson
4 * This file is part of SourcePawn.
6 * SourcePawn is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 3 of the License, or (at your option)
11 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * SourcePawn. If not, see http://www.gnu.org/licenses/.
20 #include "Environments.h"
21 #include "Structures.h"
22 #include "FixedArray.h"
24 #include "compiler/NameBinding.h"
25 #include "Spaces-inl.h"
30 EnvironmentSlotDescriptorArray *
31 EnvironmentSlotDescriptorArray::New(Zone *zone, unsigned nslots)
33 size_t bytesNeeded = sizeof(EnvironmentSlotDescriptorArray) +
34 sizeof(EnvironmentSlotDescriptor) * nslots;
36 Local<EnvironmentSlotDescriptorArray> array(zone);
37 Local<Map> map(zone, zone->getMap(MapKind_EnvironmentSlotDescriptorArray));
39 array = EnvironmentSlotDescriptorArray::cast(zone->allocate(map, bytesNeeded, Heap::Tenure_Old));
43 // We zero the array for safety, since we could GC or fail before initialization.
44 array->length_ = nslots;
45 memset(array->slots(), 0, sizeof(EnvironmentSlotDescriptor) * nslots);
50 Environment::New(Zone *zone, Handle<EnvironmentMap> map, Heap::Tenure tenure)
52 size_t bytesNeeded = sizeof(Environment) + map->structureSize();
53 Local<Environment> env(zone, Environment::cast(zone->allocate(map, bytesNeeded, tenure)));
57 // Initialize when called from C++, to make sure object slots are NULL.
58 memset((Object *)env + 1, 0, map->structureSize());
64 EnvironmentMap::New(Zone *zone, unsigned nvars, Variable **vars)
66 StructureBufferBuilder structure;
68 Local<EnvironmentSlotDescriptorArray> slots(zone);
69 slots = EnvironmentSlotDescriptorArray::New(zone, nvars);
73 // Build the descriptor table, mapping each slot to an offset and type.
74 Local<Type> type(zone);
75 for (unsigned i = 0; i < nvars; i++) {
76 assert(vars[i]->slot() == i);
77 type = vars[i]->type();
79 EnvironmentSlotDescriptor &desc = slots->slots()[i];
80 if (!structure.add(type, &desc.offset))
86 // Allocate the actual map now.
87 size_t bytesNeeded = sizeof(EnvironmentMap) + structure.traceableOffsetCount() * sizeof(unsigned);
89 Local<EnvironmentMap> map(zone);
90 map = EnvironmentMap::cast(zone->allocateMap(MapKind_Environment, bytesNeeded, MapKind_MetaEnvironment));
94 // Fill in the map fields, and copy the traceable offsets structure.
95 map->structureSize_ = structure.structureSize();
96 map->traceOffsetCount_ = structure.traceableOffsetCount();
98 memcpy(const_cast<unsigned *>(map->traceOffsets()), structure.offsets(), sizeof(unsigned) * structure.traceableOffsetCount());