1.1 --- a/src/Structures.h Mon Jun 10 00:46:29 2013 +0100
1.2 +++ b/src/Structures.h Mon Jun 10 01:04:43 2013 +0100
1.3 @@ -1,215 +1,215 @@
1.4 -/* vim: set ts=4 sw=4 tw=99 et:
1.5 - *
1.6 - * Copyright (C) 2012 David Anderson
1.7 - *
1.8 - * This file is part of SourcePawn.
1.9 - *
1.10 - * SourcePawn is free software: you can redistribute it and/or modify it under
1.11 - * the terms of the GNU General Public License as published by the Free
1.12 - * Software Foundation, either version 3 of the License, or (at your option)
1.13 - * any later version.
1.14 - *
1.15 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
1.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.18 - *
1.19 - * You should have received a copy of the GNU General Public License along with
1.20 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.21 - */
1.22 -#ifndef _include_jc_structure_h_
1.23 -#define _include_jc_structure_h_
1.24 -
1.25 -#include "Objects.h"
1.26 -#include "Handles.h"
1.27 -#include "Vector.h"
1.28 -#include "Heap.h"
1.29 -
1.30 -namespace ke {
1.31 -
1.32 -class Type;
1.33 -class String;
1.34 -class FixedArray;
1.35 -class StructType;
1.36 -
1.37 -// When describing composite structures, the GC must be able to trace interior
1.38 -// references to Objects. To make this possible, maps that describe composite
1.39 -// structures must provide a list of offsets into their objects that are
1.40 -// traceable. StructureBufferBuilder assists with this.
1.41 -class StructureBufferBuilder
1.42 -{
1.43 - public:
1.44 - StructureBufferBuilder();
1.45 -
1.46 - bool add(Handle<Type> type, unsigned *offset);
1.47 -
1.48 - unsigned structureSize() const {
1.49 - return size_;
1.50 - }
1.51 - unsigned traceableOffsetCount() const {
1.52 - return offsets_.length();
1.53 - }
1.54 - const unsigned *offsets() const {
1.55 - return offsets_.buffer();
1.56 - }
1.57 -
1.58 - private:
1.59 - Vector<unsigned> offsets_;
1.60 - unsigned size_;
1.61 -};
1.62 -
1.63 -// Represents a property descriptor for a structure field.
1.64 -class Descriptor : public Object
1.65 -{
1.66 - public:
1.67 - enum Visibility {
1.68 - Private,
1.69 - Protected,
1.70 - Public
1.71 - };
1.72 -
1.73 - private:
1.74 - // The name of the field.
1.75 - Barriered<String> name_;
1.76 -
1.77 - // The type of the field.
1.78 - Barriered<Type> type_;
1.79 -
1.80 - // The offset into an object at which this field can be accessed.
1.81 - unsigned offset_;
1.82 -
1.83 - Visibility visibility_;
1.84 -
1.85 - public:
1.86 - static Descriptor *New(Zone *zone, Handle<String> name, Handle<Type> type, Visibility visibility);
1.87 -
1.88 - String *name() {
1.89 - return name_;
1.90 - }
1.91 - Type *type() {
1.92 - return type_;
1.93 - }
1.94 - unsigned offset() {
1.95 - assert(offset_ != unsigned(-1));
1.96 - return offset_;
1.97 - }
1.98 - void setOffset(unsigned offset) {
1.99 - assert(offset_ == unsigned(-1));
1.100 - offset_ = offset;
1.101 - }
1.102 -
1.103 - // Begin GC descriptor.
1.104 - static inline size_t offsetOfName() {
1.105 - return OFFSETOF(Descriptor, name_);
1.106 - }
1.107 - static inline size_t offsetOfType() {
1.108 - return OFFSETOF(Descriptor, type_);
1.109 - }
1.110 - // End GC descriptor.
1.111 -
1.112 - static inline Descriptor *cast(Object *obj) {
1.113 - assert(!obj || obj->is(MapKind_Descriptor));
1.114 - return reinterpret_cast<Descriptor *>(obj);
1.115 - }
1.116 -};
1.117 -
1.118 -class StructMap : public Map
1.119 -{
1.120 - unsigned structureSize_;
1.121 - unsigned traceOffsetCount_;
1.122 - Barriered<StructType> type_;
1.123 -
1.124 - // List of descriptors which must be allocated upon initialization.
1.125 - Barriered<FixedArray> composed_;
1.126 -
1.127 - public:
1.128 - static StructMap *New(Zone *zone, const StructureBufferBuilder &builder, Handle<StructType> type);
1.129 -
1.130 - unsigned structureSize() {
1.131 - return structureSize_;
1.132 - }
1.133 - unsigned traceOffsetCount() {
1.134 - return traceOffsetCount_;
1.135 - }
1.136 - const unsigned *traceOffsets() {
1.137 - return reinterpret_cast<unsigned *>(this + 1);
1.138 - }
1.139 - size_t objSize() {
1.140 - return sizeof(StructMap) + sizeof(unsigned) * traceOffsetCount();
1.141 - }
1.142 - StructType *type() {
1.143 - return type_;
1.144 - }
1.145 - FixedArray *composed() {
1.146 - return composed_;
1.147 - }
1.148 -
1.149 - void setType(StructType *type) {
1.150 - assert(!type_);
1.151 - type_ = type;
1.152 - }
1.153 -
1.154 - // Begin GC descriptors.
1.155 - static inline size_t offsetOfType() {
1.156 - return OFFSETOF(StructMap, type_);
1.157 - }
1.158 - static inline size_t offsetOfComposed() {
1.159 - return OFFSETOF(StructMap, composed_);
1.160 - }
1.161 - // End GC descriptors.
1.162 -
1.163 - static inline StructMap *cast(Object *obj) {
1.164 - assert(!obj || obj->is(MapKind_MetaStruct));
1.165 - return reinterpret_cast<StructMap *>(obj);
1.166 - }
1.167 -};
1.168 -
1.169 -class Struct : public Object
1.170 -{
1.171 - public:
1.172 - static Struct *New(Zone *zone, Handle<StructMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
1.173 -
1.174 - static bool Copy(Zone *zone, Handle<Struct> dest, Handle<Struct> src);
1.175 -
1.176 - StructMap *map() {
1.177 - return StructMap::cast(Object::map());
1.178 - }
1.179 -
1.180 - void *ref(Descriptor *desc) {
1.181 - return reinterpret_cast<Address>(this) + offsetOfSlotOffset(desc->offset());
1.182 - }
1.183 -
1.184 - static inline size_t SizeFor(StructMap *map) {
1.185 - return Max(sizeof(Struct) + map->structureSize(), kMinObjectSize);
1.186 - }
1.187 -
1.188 - template <typename T> T get(Descriptor *desc) {
1.189 - return *reinterpret_cast<T *>(ref(desc));
1.190 - }
1.191 -
1.192 - // This must NOT be used with any Object * type!
1.193 - // :TODO: prevent with type system
1.194 - template <typename T> void set(Descriptor *desc, const T &t) {
1.195 - *reinterpret_cast<T *>(ref(desc)) = t;
1.196 - }
1.197 -
1.198 - void set(Zone *zone, Descriptor *desc, Object *obj) {
1.199 - // :TODO: write barrier
1.200 - *reinterpret_cast<Object **>(
1.201 - reinterpret_cast<Address>(this) +
1.202 - offsetOfSlotOffset(desc->offset())) = obj;
1.203 - }
1.204 -
1.205 - static inline size_t offsetOfSlotOffset(unsigned offset) {
1.206 - return sizeof(Struct) + offset;
1.207 - }
1.208 -
1.209 - static inline Struct *cast(Object *obj) {
1.210 - assert(!obj || obj->is(MapKind_Struct));
1.211 - return reinterpret_cast<Struct *>(obj);
1.212 - }
1.213 -};
1.214 -
1.215 -}
1.216 -
1.217 -#endif // _include_jc_structure_h_
1.218 -
1.219 +/* vim: set ts=4 sw=4 tw=99 et:
1.220 + *
1.221 + * Copyright (C) 2012 David Anderson
1.222 + *
1.223 + * This file is part of SourcePawn.
1.224 + *
1.225 + * SourcePawn is free software: you can redistribute it and/or modify it under
1.226 + * the terms of the GNU General Public License as published by the Free
1.227 + * Software Foundation, either version 3 of the License, or (at your option)
1.228 + * any later version.
1.229 + *
1.230 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
1.231 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.232 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.233 + *
1.234 + * You should have received a copy of the GNU General Public License along with
1.235 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.236 + */
1.237 +#ifndef _include_jc_structure_h_
1.238 +#define _include_jc_structure_h_
1.239 +
1.240 +#include "Objects.h"
1.241 +#include "Handles.h"
1.242 +#include "Vector.h"
1.243 +#include "Heap.h"
1.244 +
1.245 +namespace ke {
1.246 +
1.247 +class Type;
1.248 +class String;
1.249 +class FixedArray;
1.250 +class StructType;
1.251 +
1.252 +// When describing composite structures, the GC must be able to trace interior
1.253 +// references to Objects. To make this possible, maps that describe composite
1.254 +// structures must provide a list of offsets into their objects that are
1.255 +// traceable. StructureBufferBuilder assists with this.
1.256 +class StructureBufferBuilder
1.257 +{
1.258 + public:
1.259 + StructureBufferBuilder();
1.260 +
1.261 + bool add(Handle<Type> type, unsigned *offset);
1.262 +
1.263 + unsigned structureSize() const {
1.264 + return size_;
1.265 + }
1.266 + unsigned traceableOffsetCount() const {
1.267 + return offsets_.length();
1.268 + }
1.269 + const unsigned *offsets() const {
1.270 + return offsets_.buffer();
1.271 + }
1.272 +
1.273 + private:
1.274 + Vector<unsigned> offsets_;
1.275 + unsigned size_;
1.276 +};
1.277 +
1.278 +// Represents a property descriptor for a structure field.
1.279 +class Descriptor : public Object
1.280 +{
1.281 + public:
1.282 + enum Visibility {
1.283 + Private,
1.284 + Protected,
1.285 + Public
1.286 + };
1.287 +
1.288 + private:
1.289 + // The name of the field.
1.290 + Barriered<String> name_;
1.291 +
1.292 + // The type of the field.
1.293 + Barriered<Type> type_;
1.294 +
1.295 + // The offset into an object at which this field can be accessed.
1.296 + unsigned offset_;
1.297 +
1.298 + Visibility visibility_;
1.299 +
1.300 + public:
1.301 + static Descriptor *New(Zone *zone, Handle<String> name, Handle<Type> type, Visibility visibility);
1.302 +
1.303 + String *name() {
1.304 + return name_;
1.305 + }
1.306 + Type *type() {
1.307 + return type_;
1.308 + }
1.309 + unsigned offset() {
1.310 + assert(offset_ != unsigned(-1));
1.311 + return offset_;
1.312 + }
1.313 + void setOffset(unsigned offset) {
1.314 + assert(offset_ == unsigned(-1));
1.315 + offset_ = offset;
1.316 + }
1.317 +
1.318 + // Begin GC descriptor.
1.319 + static inline size_t offsetOfName() {
1.320 + return OFFSETOF(Descriptor, name_);
1.321 + }
1.322 + static inline size_t offsetOfType() {
1.323 + return OFFSETOF(Descriptor, type_);
1.324 + }
1.325 + // End GC descriptor.
1.326 +
1.327 + static inline Descriptor *cast(Object *obj) {
1.328 + assert(!obj || obj->is(MapKind_Descriptor));
1.329 + return reinterpret_cast<Descriptor *>(obj);
1.330 + }
1.331 +};
1.332 +
1.333 +class StructMap : public Map
1.334 +{
1.335 + unsigned structureSize_;
1.336 + unsigned traceOffsetCount_;
1.337 + Barriered<StructType> type_;
1.338 +
1.339 + // List of descriptors which must be allocated upon initialization.
1.340 + Barriered<FixedArray> composed_;
1.341 +
1.342 + public:
1.343 + static StructMap *New(Zone *zone, const StructureBufferBuilder &builder, Handle<StructType> type);
1.344 +
1.345 + unsigned structureSize() {
1.346 + return structureSize_;
1.347 + }
1.348 + unsigned traceOffsetCount() {
1.349 + return traceOffsetCount_;
1.350 + }
1.351 + const unsigned *traceOffsets() {
1.352 + return reinterpret_cast<unsigned *>(this + 1);
1.353 + }
1.354 + size_t objSize() {
1.355 + return sizeof(StructMap) + sizeof(unsigned) * traceOffsetCount();
1.356 + }
1.357 + StructType *type() {
1.358 + return type_;
1.359 + }
1.360 + FixedArray *composed() {
1.361 + return composed_;
1.362 + }
1.363 +
1.364 + void setType(StructType *type) {
1.365 + assert(!type_);
1.366 + type_ = type;
1.367 + }
1.368 +
1.369 + // Begin GC descriptors.
1.370 + static inline size_t offsetOfType() {
1.371 + return OFFSETOF(StructMap, type_);
1.372 + }
1.373 + static inline size_t offsetOfComposed() {
1.374 + return OFFSETOF(StructMap, composed_);
1.375 + }
1.376 + // End GC descriptors.
1.377 +
1.378 + static inline StructMap *cast(Object *obj) {
1.379 + assert(!obj || obj->is(MapKind_MetaStruct));
1.380 + return reinterpret_cast<StructMap *>(obj);
1.381 + }
1.382 +};
1.383 +
1.384 +class Struct : public Object
1.385 +{
1.386 + public:
1.387 + static Struct *New(Zone *zone, Handle<StructMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
1.388 +
1.389 + static bool Copy(Zone *zone, Handle<Struct> dest, Handle<Struct> src);
1.390 +
1.391 + StructMap *map() {
1.392 + return StructMap::cast(Object::map());
1.393 + }
1.394 +
1.395 + void *ref(Descriptor *desc) {
1.396 + return reinterpret_cast<Address>(this) + offsetOfSlotOffset(desc->offset());
1.397 + }
1.398 +
1.399 + static inline size_t SizeFor(StructMap *map) {
1.400 + return Max(sizeof(Struct) + map->structureSize(), kMinObjectSize);
1.401 + }
1.402 +
1.403 + template <typename T> T get(Descriptor *desc) {
1.404 + return *reinterpret_cast<T *>(ref(desc));
1.405 + }
1.406 +
1.407 + // This must NOT be used with any Object * type!
1.408 + // :TODO: prevent with type system
1.409 + template <typename T> void set(Descriptor *desc, const T &t) {
1.410 + *reinterpret_cast<T *>(ref(desc)) = t;
1.411 + }
1.412 +
1.413 + void set(Zone *zone, Descriptor *desc, Object *obj) {
1.414 + // :TODO: write barrier
1.415 + *reinterpret_cast<Object **>(
1.416 + reinterpret_cast<Address>(this) +
1.417 + offsetOfSlotOffset(desc->offset())) = obj;
1.418 + }
1.419 +
1.420 + static inline size_t offsetOfSlotOffset(unsigned offset) {
1.421 + return sizeof(Struct) + offset;
1.422 + }
1.423 +
1.424 + static inline Struct *cast(Object *obj) {
1.425 + assert(!obj || obj->is(MapKind_Struct));
1.426 + return reinterpret_cast<Struct *>(obj);
1.427 + }
1.428 +};
1.429 +
1.430 +}
1.431 +
1.432 +#endif // _include_jc_structure_h_
1.433 +