src/Array.h
author David Anderson <dvander@alliedmods.net>
Sat Sep 15 18:25:54 2012 -0700 (2012-09-15)
changeset 185 10936f3a2ba3
parent 169 0456a16c2a63
child 187 9308d52205a0
permissions -rw-r--r--
Added support for declaring empty-length arrays.
     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, Heap::Tenure = Heap::Tenure_Default);
    38     static Array *New(Zone *zone, Handle<ArrayMap> map, uint32 elements,
    39                       Heap::Tenure = Heap::Tenure_Default);
    40     static Array *NewString(Zone *zone, Handle<ArrayMap> map, Address buffer, size_t length, Heap::Tenure = Heap::Tenure_Default);
    41     static Array *NewExternal(Zone *zone, Handle<ArrayMap> map, uint32 nelements,
    42                               void *elements, Heap::Tenure = Heap::Tenure_Default);
    43 
    44     uint32 length() {
    45         return nelements_;
    46     }
    47     void *vec() {
    48         return elements_;
    49     }
    50 
    51     inline int *int32Vec();
    52     inline float *floatVec();
    53     inline Object **objVec();
    54     inline char *chars();
    55 
    56     inline Type *type();
    57     inline size_t elementSize();
    58 
    59     int readInt32(size_t index) {
    60         assert(index < length());
    61         return int32Vec()[index];
    62     }
    63     void writeInt32(size_t index, int i) {
    64         assert(index < length());
    65         int32Vec()[index] = i;
    66     }
    67     char readChar(size_t index) {
    68         assert(index < length());
    69         return chars()[index];
    70     }
    71     void writeChar(size_t index, char c) {
    72         assert(index < length());
    73         chars()[index] = c;
    74     }
    75     float readFloat(size_t index) {
    76         assert(index < length());
    77         return floatVec()[index];
    78     }
    79     void writeFloat(size_t index, float f) {
    80         assert(index < length());
    81         floatVec()[index] = f;
    82     }
    83     inline void *slotPtr(size_t index);
    84     Object *readObject(size_t index) {
    85         assert(index < length());
    86         return objVec()[index];
    87     }
    88     void writeObject(Zone *zone, size_t index, Object *ptr) {
    89         assert(index < length());
    90         write(zone, &objVec()[index], ptr);
    91     }
    92 
    93     bool isExternal() {
    94         // Inline arrays always have their elements pointing at the next slot.
    95         Address buffer = reinterpret_cast<Address>(elements_);
    96         return buffer != reinterpret_cast<Address>(this + 1);
    97     }
    98 
    99     static inline size_t SizeOf(Array *array) {
   100         if (array->isExternal())
   101             return sizeof(Array);
   102         return sizeof(Array) + array->length() * array->elementSize();
   103     }
   104 
   105     static Array *cast(Object *obj) {
   106         assert(!obj || obj->is(MapKind_Array));
   107         return reinterpret_cast<Array *>(obj);
   108     }
   109 };
   110 
   111 class ArrayMap : public Map
   112 {
   113     Barriered<Type> type_;
   114 
   115   public:
   116     static ArrayMap *New(Zone *zone, Handle<Type> type);
   117     static ArrayMap *Attach(Zone *zone, Handle<Type> type);
   118 
   119     Type *type() {
   120         return type_;
   121     }
   122 
   123     // GC Descriptor.
   124     static inline size_t offsetOfType() {
   125         return OFFSETOF(ArrayMap, type_);
   126     }
   127     // End GC Descriptor.
   128     
   129     static ArrayMap *cast(Object *obj) {
   130         assert(!obj || obj->is(MapKind_MetaArray));
   131         return reinterpret_cast<ArrayMap *>(obj);
   132     }
   133 };
   134 
   135 inline int *
   136 Array::int32Vec()
   137 {
   138     assert(type()->levels() == 1);
   139     assert(type()->contained()->isInt32());
   140     return reinterpret_cast<int *>(vec());
   141 }
   142 
   143 inline float *
   144 Array::floatVec()
   145 {
   146     assert(type()->levels() == 1);
   147     assert(type()->contained()->isFloat());
   148     return reinterpret_cast<float *>(vec());
   149 }
   150 
   151 inline Object **
   152 Array::objVec()
   153 {
   154     assert(type()->contained()->isTraceable());
   155     return reinterpret_cast<Object **>(vec());
   156 }
   157 
   158 inline void *
   159 Array::slotPtr(size_t index)
   160 {
   161     assert(type()->contained()->primitive() == PrimitiveType_Int32 ||
   162            type()->contained()->primitive() == PrimitiveType_Float);
   163     assert(index < length());
   164     return reinterpret_cast<int *>(vec()) + index;
   165 }
   166 
   167 inline char *
   168 Array::chars()
   169 {
   170     assert(type()->levels() == 1);
   171     assert(type()->contained()->primitive() == PrimitiveType_Char);
   172     return reinterpret_cast<char *>(vec());
   173 }
   174 
   175 inline Type *
   176 Array::type()
   177 {
   178     return ArrayMap::cast(map())->type();
   179 }
   180 
   181 inline size_t
   182 Array::elementSize()
   183 {
   184     assert(type()->isArray());
   185     if (type()->contained()->isArray())
   186         return sizeof(Object *);
   187     switch (type()->contained()->primitive()) {
   188       case PrimitiveType_Float:
   189         return sizeof(float);
   190       case PrimitiveType_Int32:
   191         return sizeof(int);
   192       default:
   193         assert(type()->contained()->primitive() == PrimitiveType_Char);
   194         return sizeof(char);
   195     }
   196 }
   197 
   198 }
   199 
   200 #endif // _include_jitcraft_array_h_