src/Array.h
author David Anderson <dvander@alliedmods.net>
Sat Jul 28 17:12:42 2012 -0700 (2012-07-28)
changeset 111 0a0c37ddad13
parent 91 5f4402180204
child 154 a85a0303bcb8
permissions -rw-r--r--
Trigger build.
     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 nelements() {
    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 < nelements());
    59         return int32Vec()[index];
    60     }
    61     void writeInt32(size_t index, int i) {
    62         assert(index < nelements());
    63         int32Vec()[index] = i;
    64     }
    65     char readChar(size_t index) {
    66         assert(index < nelements());
    67         return chars()[index];
    68     }
    69     void writeChar(size_t index, char c) {
    70         assert(index < nelements());
    71         chars()[index] = c;
    72     }
    73     float readFloat(size_t index) {
    74         assert(index < nelements());
    75         return floatVec()[index];
    76     }
    77     void writeFloat(size_t index, float f) {
    78         assert(index < nelements());
    79         floatVec()[index] = f;
    80     }
    81     inline void *slotPtr(size_t index);
    82     Object *readObject(size_t index) {
    83         assert(index < nelements());
    84         return objVec()[index];
    85     }
    86     void writeObject(Zone *zone, size_t index, Object *ptr) {
    87         assert(index < nelements());
    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->nelements() * 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     Barriered<ArrayMap> contained_;
   113 
   114   public:
   115     static ArrayMap *New(Zone *zone, Handle<Type> type, Handle<ArrayMap> contained);
   116 
   117     Type *type() {
   118         return type_;
   119     }
   120     ArrayMap *contained() {
   121         return contained_;
   122     }
   123 
   124     // GC Descriptor.
   125     static inline size_t offsetOfType() {
   126         return OFFSETOF(ArrayMap, type_);
   127     }
   128     static inline size_t offsetOfContained() {
   129         return OFFSETOF(ArrayMap, contained_);
   130     }
   131     // End GC Descriptor.
   132     
   133     static ArrayMap *cast(Object *obj) {
   134         assert(!obj || obj->is(MapKind_MetaArray));
   135         return reinterpret_cast<ArrayMap *>(obj);
   136     }
   137 };
   138 
   139 inline int *
   140 Array::int32Vec()
   141 {
   142     assert(type()->levels() == 1);
   143     assert(type()->contained()->isInt32());
   144     return reinterpret_cast<int *>(vec());
   145 }
   146 
   147 inline float *
   148 Array::floatVec()
   149 {
   150     assert(type()->levels() == 1);
   151     assert(type()->contained()->isFloat());
   152     return reinterpret_cast<float *>(vec());
   153 }
   154 
   155 inline Object **
   156 Array::objVec()
   157 {
   158     assert(type()->levels() > 1);
   159     return reinterpret_cast<Object **>(vec());
   160 }
   161 
   162 inline void *
   163 Array::slotPtr(size_t index)
   164 {
   165     assert(type()->contained()->primitive() == PrimitiveType_Int32 ||
   166            type()->contained()->primitive() == PrimitiveType_Float);
   167     assert(index < nelements());
   168     return reinterpret_cast<int *>(vec()) + index;
   169 }
   170 
   171 inline char *
   172 Array::chars()
   173 {
   174     assert(type()->levels() == 1);
   175     assert(type()->contained()->primitive() == PrimitiveType_Char);
   176     return reinterpret_cast<char *>(vec());
   177 }
   178 
   179 inline Type *
   180 Array::type()
   181 {
   182     return ArrayMap::cast(map())->type();
   183 }
   184 
   185 inline size_t
   186 Array::elementSize()
   187 {
   188     assert(type()->isArray());
   189     if (type()->contained()->isArray())
   190         return sizeof(Object *);
   191     switch (type()->contained()->primitive()) {
   192       case PrimitiveType_Float:
   193         return sizeof(float);
   194       case PrimitiveType_Int32:
   195         return sizeof(int);
   196       default:
   197         assert(type()->contained()->primitive() == PrimitiveType_Char);
   198         return sizeof(char);
   199     }
   200 }
   201 
   202 }
   203 
   204 #endif // _include_jitcraft_array_h_