src/Array.h
author David Anderson <dvander@alliedmods.net>
Sun Aug 05 00:49:31 2012 -0700 (2012-08-05)
changeset 156 0d28dc5af6c7
parent 155 7926a7921fa3
child 169 0456a16c2a63
permissions -rw-r--r--
Re-allow arrays to nest.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #ifndef _include_jitcraft_array_h_
    19 #define _include_jitcraft_array_h_
    20 
    21 #include "Heap.h"
    22 #include "Handles.h"
    23 #include "Types.h"
    24 
    25 namespace ke {
    26 
    27 class ArrayMap;
    28 
    29 class Array : public Object
    30 {
    31     friend class ArrayMap;
    32 
    33     uint32 nelements_;
    34     void *elements_;
    35 
    36   public:
    37     static Array *New(Zone *zone, Handle<ArrayMap> map, uint32 elements,
    38                       Heap::Tenure = Heap::Tenure_Default);
    39     static Array *NewExternal(Zone *zone, Handle<ArrayMap> map, uint32 nelements,
    40                               void *elements, Heap::Tenure = Heap::Tenure_Default);
    41 
    42     uint32 length() {
    43         return nelements_;
    44     }
    45     void *vec() {
    46         return elements_;
    47     }
    48 
    49     inline int *int32Vec();
    50     inline float *floatVec();
    51     inline Object **objVec();
    52     inline char *chars();
    53 
    54     inline Type *type();
    55     inline size_t elementSize();
    56 
    57     int readInt32(size_t index) {
    58         assert(index < length());
    59         return int32Vec()[index];
    60     }
    61     void writeInt32(size_t index, int i) {
    62         assert(index < length());
    63         int32Vec()[index] = i;
    64     }
    65     char readChar(size_t index) {
    66         assert(index < length());
    67         return chars()[index];
    68     }
    69     void writeChar(size_t index, char c) {
    70         assert(index < length());
    71         chars()[index] = c;
    72     }
    73     float readFloat(size_t index) {
    74         assert(index < length());
    75         return floatVec()[index];
    76     }
    77     void writeFloat(size_t index, float f) {
    78         assert(index < length());
    79         floatVec()[index] = f;
    80     }
    81     inline void *slotPtr(size_t index);
    82     Object *readObject(size_t index) {
    83         assert(index < length());
    84         return objVec()[index];
    85     }
    86     void writeObject(Zone *zone, size_t index, Object *ptr) {
    87         assert(index < length());
    88         write(zone, &objVec()[index], ptr);
    89     }
    90 
    91     bool isExternal() {
    92         // Inline arrays always have their elements pointing at the next slot.
    93         Address buffer = reinterpret_cast<Address>(elements_);
    94         return buffer != reinterpret_cast<Address>(this + 1);
    95     }
    96 
    97     static inline size_t SizeOf(Array *array) {
    98         if (array->isExternal())
    99             return sizeof(Array);
   100         return sizeof(Array) + array->length() * array->elementSize();
   101     }
   102 
   103     static Array *cast(Object *obj) {
   104         assert(!obj || obj->is(MapKind_Array));
   105         return reinterpret_cast<Array *>(obj);
   106     }
   107 };
   108 
   109 class ArrayMap : public Map
   110 {
   111     Barriered<Type> type_;
   112 
   113   public:
   114     static ArrayMap *New(Zone *zone, Handle<Type> type);
   115 
   116     Type *type() {
   117         return type_;
   118     }
   119 
   120     // GC Descriptor.
   121     static inline size_t offsetOfType() {
   122         return OFFSETOF(ArrayMap, type_);
   123     }
   124     // End GC Descriptor.
   125     
   126     static ArrayMap *cast(Object *obj) {
   127         assert(!obj || obj->is(MapKind_MetaArray));
   128         return reinterpret_cast<ArrayMap *>(obj);
   129     }
   130 };
   131 
   132 inline int *
   133 Array::int32Vec()
   134 {
   135     assert(type()->levels() == 1);
   136     assert(type()->contained()->isInt32());
   137     return reinterpret_cast<int *>(vec());
   138 }
   139 
   140 inline float *
   141 Array::floatVec()
   142 {
   143     assert(type()->levels() == 1);
   144     assert(type()->contained()->isFloat());
   145     return reinterpret_cast<float *>(vec());
   146 }
   147 
   148 inline Object **
   149 Array::objVec()
   150 {
   151     assert(type()->contained()->isTraceable());
   152     return reinterpret_cast<Object **>(vec());
   153 }
   154 
   155 inline void *
   156 Array::slotPtr(size_t index)
   157 {
   158     assert(type()->contained()->primitive() == PrimitiveType_Int32 ||
   159            type()->contained()->primitive() == PrimitiveType_Float);
   160     assert(index < length());
   161     return reinterpret_cast<int *>(vec()) + index;
   162 }
   163 
   164 inline char *
   165 Array::chars()
   166 {
   167     assert(type()->levels() == 1);
   168     assert(type()->contained()->primitive() == PrimitiveType_Char);
   169     return reinterpret_cast<char *>(vec());
   170 }
   171 
   172 inline Type *
   173 Array::type()
   174 {
   175     return ArrayMap::cast(map())->type();
   176 }
   177 
   178 inline size_t
   179 Array::elementSize()
   180 {
   181     assert(type()->isArray());
   182     if (type()->contained()->isArray())
   183         return sizeof(Object *);
   184     switch (type()->contained()->primitive()) {
   185       case PrimitiveType_Float:
   186         return sizeof(float);
   187       case PrimitiveType_Int32:
   188         return sizeof(int);
   189       default:
   190         assert(type()->contained()->primitive() == PrimitiveType_Char);
   191         return sizeof(char);
   192     }
   193 }
   194 
   195 }
   196 
   197 #endif // _include_jitcraft_array_h_