src/Structures.h
changeset 263 ba85a47ee414
parent 256 3c184218462d
     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 +