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