dvander@85: /* dvander@85: * Copyright (C) 2012 David Anderson dvander@85: * dvander@195: * This file is part of SourcePawn. dvander@85: * dvander@195: * SourcePawn is free software: you can redistribute it and/or modify it under dvander@85: * the terms of the GNU General Public License as published by the Free dvander@85: * Software Foundation, either version 3 of the License, or (at your option) dvander@85: * any later version. dvander@85: * dvander@195: * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY dvander@85: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@85: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@85: * dvander@85: * You should have received a copy of the GNU General Public License along with dvander@195: * SourcePawn. If not, see http://www.gnu.org/licenses/. dvander@85: */ danderson@92: #include dvander@85: #include "Utility.h" dvander@85: #include "Environments.h" dvander@85: #include "Structures.h" dvander@85: #include "FixedArray.h" dvander@85: #include "Zone.h" dvander@195: #include "compiler/NameBinding.h" danderson@92: #include "Spaces-inl.h" danderson@92: #include "Heap-inl.h" dvander@85: dvander@85: using namespace ke; dvander@85: dvander@85: EnvironmentSlotDescriptorArray * dvander@85: EnvironmentSlotDescriptorArray::New(Zone *zone, unsigned nslots) dvander@85: { dvander@85: size_t bytesNeeded = sizeof(EnvironmentSlotDescriptorArray) + dvander@85: sizeof(EnvironmentSlotDescriptor) * nslots; dvander@85: dvander@85: Local array(zone); dvander@85: Local map(zone, zone->getMap(MapKind_EnvironmentSlotDescriptorArray)); dvander@85: dvander@85: array = EnvironmentSlotDescriptorArray::cast(zone->allocate(map, bytesNeeded, Heap::Tenure_Old)); dvander@85: if (!array) dvander@85: return NULL; dvander@85: dvander@85: // We zero the array for safety, since we could GC or fail before initialization. dvander@85: array->length_ = nslots; dvander@85: memset(array->slots(), 0, sizeof(EnvironmentSlotDescriptor) * nslots); dvander@85: return array; dvander@85: } dvander@85: dvander@85: Environment * dvander@85: Environment::New(Zone *zone, Handle map, Heap::Tenure tenure) dvander@85: { dvander@85: size_t bytesNeeded = sizeof(Environment) + map->structureSize(); dvander@85: Local env(zone, Environment::cast(zone->allocate(map, bytesNeeded, tenure))); dvander@85: if (!env) dvander@85: return NULL; dvander@85: dvander@85: // Initialize when called from C++, to make sure object slots are NULL. dvander@85: memset((Object *)env + 1, 0, map->structureSize()); dvander@85: return env; dvander@85: } dvander@85: dvander@195: #if 0 dvander@85: EnvironmentMap * dvander@85: EnvironmentMap::New(Zone *zone, unsigned nvars, Variable **vars) dvander@85: { dvander@85: StructureBufferBuilder structure; dvander@85: dvander@85: Local slots(zone); dvander@85: slots = EnvironmentSlotDescriptorArray::New(zone, nvars); dvander@85: if (!slots) dvander@85: return NULL; dvander@85: dvander@85: // Build the descriptor table, mapping each slot to an offset and type. dvander@85: Local type(zone); dvander@85: for (unsigned i = 0; i < nvars; i++) { dvander@85: assert(vars[i]->slot() == i); dvander@85: type = vars[i]->type(); dvander@85: dvander@85: EnvironmentSlotDescriptor &desc = slots->slots()[i]; dvander@85: if (!structure.add(type, &desc.offset)) dvander@85: return NULL; dvander@85: dvander@85: desc.type = type; dvander@85: } dvander@85: dvander@85: // Allocate the actual map now. dvander@85: size_t bytesNeeded = sizeof(EnvironmentMap) + structure.traceableOffsetCount() * sizeof(unsigned); dvander@147: dvander@85: Local map(zone); dvander@85: map = EnvironmentMap::cast(zone->allocateMap(MapKind_Environment, bytesNeeded, MapKind_MetaEnvironment)); dvander@85: if (!map) dvander@85: return NULL; dvander@85: dvander@85: // Fill in the map fields, and copy the traceable offsets structure. dvander@85: map->structureSize_ = structure.structureSize(); dvander@85: map->traceOffsetCount_ = structure.traceableOffsetCount(); dvander@85: map->slots_ = slots; dvander@85: memcpy(const_cast(map->traceOffsets()), structure.offsets(), sizeof(unsigned) * structure.traceableOffsetCount()); dvander@85: dvander@85: return map; dvander@85: } dvander@195: #endif