src/Array.h
author David Anderson <dvander@alliedmods.net>
Sat Nov 17 19:23:39 2012 -0800 (2012-11-17)
changeset 200 e0a601465746
parent 188 bab29bcec7fe
child 209 5cbec15fadfe
permissions -rw-r--r--
Fix OS X build.
     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 #ifndef _include_jitcraft_array_h_
    20 #define _include_jitcraft_array_h_
    21 
    22 #include "Heap.h"
    23 #include "Handles.h"
    24 #include "Types.h"
    25 #include "FixedArray.h"
    26 
    27 namespace ke {
    28 
    29 class ArrayMap;
    30 
    31 class Array : public Object
    32 {
    33     friend class ArrayMap;
    34 
    35     // Note: we do not write barrier |elements_|, since it can be set to
    36     // arbitrary pointers.
    37     uint32 length_;
    38     union {
    39         void *elements_;
    40         Object *objelements_;
    41     };
    42 
    43   private:
    44     void updateLengthAndElements(Zone *zone, unsigned length, Object *array) {
    45         length_ = length;
    46         write(zone, &objelements_, array);
    47     }
    48 
    49   public:
    50     static Array *NewFixed(Zone *zone, Handle<ArrayMap> map, Heap::Tenure = Heap::Tenure_Default);
    51     static Array *NewString(Zone *zone, Handle<ArrayMap> map, Address buffer, size_t length, Heap::Tenure = Heap::Tenure_Default);
    52     static Array *NewSized(Zone *zone, Handle<ArrayMap> map, int sizes[MAX_ARRAY_DEPTH], Heap::Tenure = Heap::Tenure_Default);
    53 
    54     static Array *New1D(Zone *zone, Handle<ArrayMap> map, uint32 elements, Heap::Tenure tenure = Heap::Tenure_Default);
    55     static Array *NewEmpty(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
    56     static Array *NewRaw(Zone *zone, Handle<ArrayMap> map, unsigned nelements, Heap::Tenure tenure);
    57 
    58     static Array *NewExternal(Zone *zone,
    59                               Handle<ArrayMap> map,
    60                               void *buffer,
    61                               unsigned length,
    62                               Heap::Tenure tenure = Heap::Tenure_Default);
    63 
    64     uint32 length() {
    65         return length_;
    66     }
    67 
    68     inline Type *type();
    69 
    70     inline int *int32Vec();
    71     inline float *floatVec();
    72     inline char *chars();
    73     inline void *bytes();
    74 
    75 
    76     static inline size_t SizeForElement(Type *type) {
    77         if (type->contained()->isTraceable())
    78             return sizeof(ke::Object *);
    79         if (type->contained()->isInt32())
    80             return sizeof(int);
    81         if (type->contained()->primitive() == PrimitiveType_Char)
    82             return sizeof(char);
    83         assert(type->contained()->isFloat());
    84         return sizeof(float);
    85     }
    86 
    87     inline size_t objSize(ArrayMap *map);
    88 
    89     int readInt32(size_t index) {
    90         assert(index < length());
    91         return int32Vec()[index];
    92     }
    93     void writeInt32(size_t index, int i) {
    94         assert(index < length());
    95         int32Vec()[index] = i;
    96     }
    97     char readChar(size_t index) {
    98         assert(index < length());
    99         return chars()[index];
   100     }
   101     void writeChar(size_t index, char c) {
   102         assert(index < length());
   103         chars()[index] = c;
   104     }
   105     float readFloat(size_t index) {
   106         assert(index < length());
   107         return floatVec()[index];
   108     }
   109     void writeFloat(size_t index, float f) {
   110         assert(index < length());
   111         floatVec()[index] = f;
   112     }
   113     Object *readObject(size_t index) {
   114         return FixedArray::cast(objelements_)->at(index);
   115     }
   116     void writeObject(Zone *zone, size_t index, Object *ptr) {
   117         FixedArray::cast(objelements_)->set(zone, index, ptr);
   118     }
   119 
   120     // GC Descriptor.
   121     static inline size_t offsetOfElements() {
   122         return offsetof(Array, objelements_);
   123     }
   124     // End GC Descriptor.
   125 
   126     static Array *cast(Object *obj) {
   127         assert(!obj || obj->is(MapKind_Array));
   128         return reinterpret_cast<Array *>(obj);
   129     }
   130 };
   131 
   132 class ArrayMap : public Map
   133 {
   134     Barriered<Type> type_;
   135 
   136   public:
   137     static ArrayMap *New(Zone *zone, Handle<Type> type);
   138     static ArrayMap *Attach(Zone *zone, Handle<Type> type);
   139 
   140     Type *type() {
   141         return type_;
   142     }
   143 
   144     // GC Descriptor.
   145     static inline size_t offsetOfType() {
   146         return OFFSETOF(ArrayMap, type_);
   147     }
   148     // End GC Descriptor.
   149     
   150     static ArrayMap *cast(Object *obj) {
   151         assert(!obj || obj->is(MapKind_MetaArray));
   152         return reinterpret_cast<ArrayMap *>(obj);
   153     }
   154 };
   155 
   156 inline void *
   157 Array::bytes()
   158 {
   159     assert(!type()->contained()->isTraceable());
   160     assert(type()->hasInlineElements() ||
   161            type()->isExternalArray() ||
   162            !length() ||
   163            ByteArray::cast((Object *)elements_));
   164 
   165     return Address(elements_) + ByteArray::offsetToElements();
   166 }
   167 
   168 inline int *
   169 Array::int32Vec()
   170 {
   171     assert(type()->contained()->isInt32());
   172     return reinterpret_cast<int *>(bytes());
   173 }
   174 
   175 inline float *
   176 Array::floatVec()
   177 {
   178     assert(type()->contained()->isFloat());
   179     return reinterpret_cast<float *>(bytes());
   180 }
   181 
   182 inline char *
   183 Array::chars()
   184 {
   185     assert(type()->isCharArray());
   186     return reinterpret_cast<char *>(bytes());
   187 }
   188 
   189 inline Type *
   190 Array::type()
   191 {
   192     return ArrayMap::cast(map())->type();
   193 }
   194 
   195 inline size_t
   196 Array::objSize(ArrayMap *map)
   197 {
   198     assert(this->map() == map);
   199     if (map->type()->hasInlineElements())
   200         return sizeof(Array) + Array::SizeForElement(map->type()) * length();
   201     return sizeof(Array);
   202 }
   203 
   204 }
   205 
   206 #endif // _include_jitcraft_array_h_