Preparatory refactoring for const 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/.
19 #ifndef _include_jc_structure_h_
20 #define _include_jc_structure_h_
34 // When describing composite structures, the GC must be able to trace interior
35 // references to Objects. To make this possible, maps that describe composite
36 // structures must provide a list of offsets into their objects that are
37 // traceable. StructureBufferBuilder assists with this.
38 class StructureBufferBuilder
41 StructureBufferBuilder();
43 bool add(Handle<Type> type, unsigned *offset);
45 unsigned structureSize() const {
48 unsigned traceableOffsetCount() const {
49 return offsets_.length();
51 const unsigned *offsets() const {
52 return offsets_.buffer();
56 Vector<unsigned> offsets_;
60 // Represents a property descriptor for a structure field.
61 class Descriptor : public Object
63 // The name of the field.
64 Barriered<String> name_;
66 // The type of the field.
67 Barriered<Type> type_;
69 // The offset into an object at which this field can be accessed.
73 static Descriptor *New(Zone *zone, Handle<String> name, Handle<Type> type);
82 assert(offset_ != unsigned(-1));
85 void setOffset(unsigned offset) {
86 assert(offset_ == unsigned(-1));
90 // Begin GC descriptor.
91 static inline size_t offsetOfName() {
92 return OFFSETOF(Descriptor, name_);
94 static inline size_t offsetOfType() {
95 return OFFSETOF(Descriptor, type_);
99 static inline Descriptor *cast(Object *obj) {
100 assert(!obj || obj->is(MapKind_Descriptor));
101 return reinterpret_cast<Descriptor *>(obj);
105 class StructMap : public Map
107 unsigned structureSize_;
108 unsigned traceOffsetCount_;
109 Barriered<StructType> type_;
111 // List of descriptors which must be allocated upon initialization.
112 Barriered<FixedArray> composed_;
115 static StructMap *New(Zone *zone, const StructureBufferBuilder &builder, Handle<StructType> type);
117 unsigned structureSize() {
118 return structureSize_;
120 unsigned traceOffsetCount() {
121 return traceOffsetCount_;
123 const unsigned *traceOffsets() {
124 return reinterpret_cast<unsigned *>(this + 1);
127 return sizeof(StructMap) + sizeof(unsigned) * traceOffsetCount();
132 FixedArray *composed() {
136 void setType(StructType *type) {
141 // Begin GC descriptors.
142 static inline size_t offsetOfType() {
143 return OFFSETOF(StructMap, type_);
145 static inline size_t offsetOfComposed() {
146 return OFFSETOF(StructMap, composed_);
148 // End GC descriptors.
150 static inline StructMap *cast(Object *obj) {
151 assert(!obj || obj->is(MapKind_MetaStruct));
152 return reinterpret_cast<StructMap *>(obj);
156 class Struct : public Object
159 static Struct *New(Zone *zone, Handle<StructMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
161 static bool Copy(Zone *zone, Handle<Struct> dest, Handle<Struct> src);
164 return sizeof(Struct) + map()->structureSize();
167 return StructMap::cast(Object::map());
170 void *ref(Descriptor *desc) {
171 return reinterpret_cast<Address>(this) + offsetOfSlotOffset(desc->offset());
174 template <typename T> T get(Descriptor *desc) {
175 return *reinterpret_cast<T *>(ref(desc));
178 // This must NOT be used with any Object * type!
179 // :TODO: prevent with type system
180 template <typename T> void set(Descriptor *desc, const T &t) {
181 *reinterpret_cast<T *>(ref(desc)) = t;
184 void set(Zone *zone, Descriptor *desc, Object *obj) {
185 // :TODO: write barrier
186 *reinterpret_cast<Object **>(
187 reinterpret_cast<Address>(this) +
188 offsetOfSlotOffset(desc->offset())) = obj;
191 static inline size_t offsetOfSlotOffset(unsigned offset) {
192 return sizeof(Struct) + offset;
195 static inline Struct *cast(Object *obj) {
196 assert(!obj || obj->is(MapKind_Struct));
197 return reinterpret_cast<Struct *>(obj);
203 #endif // _include_jc_structure_h_