src/Structures.cpp
author David Anderson <dvander@alliedmods.net>
Sat Aug 04 19:33:06 2012 -0700 (2012-08-04)
changeset 147 9c544823d090
parent 146 dc7d3b7a918c
child 153 fc91c4a3dfe2
permissions -rw-r--r--
Structure declaration support.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     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)
    10  * any later version.
    11  * 
    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.
    15  *
    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/.
    18  */
    19 #include <string.h>
    20 #include "Structures.h"
    21 #include "Zone.h"
    22 #include "Types.h"
    23 #include "Spaces-inl.h"
    24 #include "Heap-inl.h"
    25 
    26 using namespace ke;
    27 
    28 StructureBufferBuilder::StructureBufferBuilder()
    29   : size_(0)
    30 {
    31 }
    32 
    33 bool
    34 StructureBufferBuilder::add(Handle<Type> type, unsigned *offset)
    35 {
    36     *offset = size_;
    37 
    38     if (!type->isTraceable()) {
    39         // For now, assume the size of primitives is 4-byte.
    40         assert(type->isInt32() || type->isFloat());
    41         size_ += 4;
    42         return true;
    43     }
    44 
    45     if (!offsets_.append(size_))
    46         return false;
    47 
    48     size_ += sizeof(Object *);
    49     return true;
    50 }
    51 
    52 Descriptor *
    53 Descriptor::New(Zone *zone, Handle<String> name, Handle<Type> type, unsigned offset)
    54 {
    55     Local<Descriptor> desc(zone,
    56         Descriptor::cast(zone->allocate(MapKind_Descriptor, sizeof(Descriptor), Heap::Tenure_Old)));
    57     if (!desc)
    58         return NULL;
    59 
    60     desc->name_ = name;
    61     desc->type_ = type;
    62     desc->offset_ = offset;
    63     return desc;
    64 }
    65 
    66 StructMap *
    67 StructMap::New(Zone *zone, const StructureBufferBuilder &builder)
    68 {
    69     size_t bytesNeeded = sizeof(StructMap) +
    70                          (builder.traceableOffsetCount() * sizeof(unsigned));
    71 
    72     Local<StructMap> map(zone);
    73     map = StructMap::cast(zone->allocateMap(MapKind_Struct, bytesNeeded, MapKind_MetaStruct));
    74     if (!map)
    75         return NULL;
    76 
    77     map->structureSize_ = builder.structureSize();
    78     map->traceOffsetCount_ = builder.traceableOffsetCount();
    79     map->type_ = NULL;
    80     memcpy(const_cast<unsigned *>(map->traceOffsets()), builder.offsets(),
    81            sizeof(unsigned) * builder.traceableOffsetCount());
    82 
    83     return map;
    84 }
    85 
    86 Struct *
    87 Struct::New(Zone *zone, Handle<StructMap> map, Heap::Tenure tenure)
    88 {
    89     size_t bytesNeeded = sizeof(Struct) + map->structureSize();
    90     Local<Struct> obj(zone, Struct::cast(zone->allocate(map, bytesNeeded, tenure)));
    91     if (!obj)
    92         return NULL;
    93 
    94     memset((Struct *)obj + 1, 0, map->structureSize());
    95     return obj;
    96 }
    97