src/Array.h
author David Anderson <dvander@alliedmods.net>
Sun Nov 18 15:50:41 2012 -0800 (2012-11-18)
changeset 217 c22e983b3b6e
parent 209 5cbec15fadfe
child 234 26e3035cdffc
permissions -rw-r--r--
Get preinc working again.
dvander@187
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@187
     2
 *
dvander@12
     3
 * Copyright (C) 2012 David Anderson
dvander@12
     4
 *
dvander@187
     5
 * This file is part of SourcePawn.
dvander@12
     6
 *
dvander@187
     7
 * SourcePawn is free software: you can redistribute it and/or modify it under
dvander@12
     8
 * the terms of the GNU General Public License as published by the Free
dvander@12
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@12
    10
 * any later version.
dvander@12
    11
 * 
dvander@187
    12
 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@12
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@12
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@12
    15
 *
dvander@12
    16
 * You should have received a copy of the GNU General Public License along with
dvander@187
    17
 * SourcePawn. If not, see http://www.gnu.org/licenses/.
dvander@12
    18
 */
dvander@12
    19
#ifndef _include_jitcraft_array_h_
dvander@12
    20
#define _include_jitcraft_array_h_
dvander@12
    21
dvander@12
    22
#include "Heap.h"
dvander@27
    23
#include "Handles.h"
dvander@12
    24
#include "Types.h"
dvander@188
    25
#include "FixedArray.h"
dvander@12
    26
dvander@59
    27
namespace ke {
dvander@12
    28
dvander@12
    29
class ArrayMap;
dvander@12
    30
dvander@12
    31
class Array : public Object
dvander@12
    32
{
dvander@12
    33
    friend class ArrayMap;
dvander@12
    34
dvander@188
    35
    // Note: we do not write barrier |elements_|, since it can be set to
dvander@188
    36
    // arbitrary pointers.
dvander@188
    37
    uint32 length_;
dvander@188
    38
    union {
dvander@188
    39
        void *elements_;
dvander@188
    40
        Object *objelements_;
dvander@188
    41
    };
dvander@188
    42
dvander@188
    43
  private:
dvander@188
    44
    void updateLengthAndElements(Zone *zone, unsigned length, Object *array) {
dvander@188
    45
        length_ = length;
dvander@188
    46
        write(zone, &objelements_, array);
dvander@188
    47
    }
dvander@12
    48
dvander@12
    49
  public:
dvander@187
    50
    static Array *NewFixed(Zone *zone, Handle<ArrayMap> map, Heap::Tenure = Heap::Tenure_Default);
dvander@169
    51
    static Array *NewString(Zone *zone, Handle<ArrayMap> map, Address buffer, size_t length, Heap::Tenure = Heap::Tenure_Default);
dvander@187
    52
    static Array *NewSized(Zone *zone, Handle<ArrayMap> map, int sizes[MAX_ARRAY_DEPTH], Heap::Tenure = Heap::Tenure_Default);
dvander@12
    53
dvander@187
    54
    static Array *New1D(Zone *zone, Handle<ArrayMap> map, uint32 elements, Heap::Tenure tenure = Heap::Tenure_Default);
dvander@187
    55
    static Array *NewEmpty(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
dvander@187
    56
    static Array *NewRaw(Zone *zone, Handle<ArrayMap> map, unsigned nelements, Heap::Tenure tenure);
dvander@187
    57
dvander@188
    58
    static Array *NewExternal(Zone *zone,
dvander@188
    59
                              Handle<ArrayMap> map,
dvander@188
    60
                              void *buffer,
dvander@188
    61
                              unsigned length,
dvander@188
    62
                              Heap::Tenure tenure = Heap::Tenure_Default);
dvander@188
    63
dvander@155
    64
    uint32 length() {
dvander@188
    65
        return length_;
dvander@12
    66
    }
dvander@188
    67
dvander@209
    68
    inline ArrayType *type();
dvander@21
    69
dvander@12
    70
    inline int *int32Vec();
dvander@12
    71
    inline float *floatVec();
dvander@21
    72
    inline char *chars();
dvander@188
    73
    inline void *bytes();
dvander@188
    74
dvander@21
    75
dvander@209
    76
    static inline size_t SizeForElement(ArrayType *type) {
dvander@188
    77
        if (type->contained()->isTraceable())
dvander@188
    78
            return sizeof(ke::Object *);
dvander@188
    79
        if (type->contained()->isInt32())
dvander@188
    80
            return sizeof(int);
dvander@188
    81
        if (type->contained()->primitive() == PrimitiveType_Char)
dvander@188
    82
            return sizeof(char);
dvander@188
    83
        assert(type->contained()->isFloat());
dvander@188
    84
        return sizeof(float);
dvander@188
    85
    }
dvander@188
    86
dvander@188
    87
    inline size_t objSize(ArrayMap *map);
dvander@12
    88
dvander@12
    89
    int readInt32(size_t index) {
dvander@155
    90
        assert(index < length());
dvander@12
    91
        return int32Vec()[index];
dvander@12
    92
    }
dvander@12
    93
    void writeInt32(size_t index, int i) {
dvander@155
    94
        assert(index < length());
dvander@12
    95
        int32Vec()[index] = i;
dvander@12
    96
    }
dvander@21
    97
    char readChar(size_t index) {
dvander@155
    98
        assert(index < length());
dvander@21
    99
        return chars()[index];
dvander@21
   100
    }
dvander@21
   101
    void writeChar(size_t index, char c) {
dvander@155
   102
        assert(index < length());
dvander@21
   103
        chars()[index] = c;
dvander@21
   104
    }
dvander@12
   105
    float readFloat(size_t index) {
dvander@155
   106
        assert(index < length());
dvander@12
   107
        return floatVec()[index];
dvander@12
   108
    }
dvander@12
   109
    void writeFloat(size_t index, float f) {
dvander@155
   110
        assert(index < length());
dvander@12
   111
        floatVec()[index] = f;
dvander@12
   112
    }
dvander@12
   113
    Object *readObject(size_t index) {
dvander@188
   114
        return FixedArray::cast(objelements_)->at(index);
dvander@12
   115
    }
dvander@12
   116
    void writeObject(Zone *zone, size_t index, Object *ptr) {
dvander@188
   117
        FixedArray::cast(objelements_)->set(zone, index, ptr);
dvander@12
   118
    }
dvander@12
   119
dvander@188
   120
    // GC Descriptor.
dvander@188
   121
    static inline size_t offsetOfElements() {
dvander@188
   122
        return offsetof(Array, objelements_);
dvander@65
   123
    }
dvander@188
   124
    // End GC Descriptor.
dvander@44
   125
dvander@12
   126
    static Array *cast(Object *obj) {
dvander@31
   127
        assert(!obj || obj->is(MapKind_Array));
dvander@12
   128
        return reinterpret_cast<Array *>(obj);
dvander@12
   129
    }
dvander@12
   130
};
dvander@12
   131
dvander@12
   132
class ArrayMap : public Map
dvander@12
   133
{
dvander@209
   134
    Barriered<ArrayType> type_;
dvander@12
   135
dvander@12
   136
  public:
dvander@209
   137
    static ArrayMap *New(Zone *zone, Handle<ArrayType> type);
dvander@209
   138
    static ArrayMap *Attach(Zone *zone, Handle<ArrayType> type);
dvander@12
   139
dvander@209
   140
    ArrayType *type() {
dvander@13
   141
        return type_;
dvander@12
   142
    }
dvander@44
   143
dvander@44
   144
    // GC Descriptor.
dvander@44
   145
    static inline size_t offsetOfType() {
danderson@91
   146
        return OFFSETOF(ArrayMap, type_);
dvander@44
   147
    }
dvander@44
   148
    // End GC Descriptor.
dvander@12
   149
    
dvander@12
   150
    static ArrayMap *cast(Object *obj) {
dvander@12
   151
        assert(!obj || obj->is(MapKind_MetaArray));
dvander@12
   152
        return reinterpret_cast<ArrayMap *>(obj);
dvander@12
   153
    }
dvander@12
   154
};
dvander@12
   155
dvander@188
   156
inline void *
dvander@188
   157
Array::bytes()
dvander@188
   158
{
dvander@188
   159
    assert(!type()->contained()->isTraceable());
dvander@188
   160
    assert(type()->hasInlineElements() ||
dvander@188
   161
           type()->isExternalArray() ||
dvander@188
   162
           !length() ||
dvander@188
   163
           ByteArray::cast((Object *)elements_));
dvander@188
   164
dvander@188
   165
    return Address(elements_) + ByteArray::offsetToElements();
dvander@188
   166
}
dvander@188
   167
dvander@12
   168
inline int *
dvander@12
   169
Array::int32Vec()
dvander@12
   170
{
dvander@21
   171
    assert(type()->contained()->isInt32());
dvander@188
   172
    return reinterpret_cast<int *>(bytes());
dvander@12
   173
}
dvander@12
   174
dvander@12
   175
inline float *
dvander@12
   176
Array::floatVec()
dvander@12
   177
{
dvander@21
   178
    assert(type()->contained()->isFloat());
dvander@188
   179
    return reinterpret_cast<float *>(bytes());
dvander@17
   180
}
dvander@17
   181
dvander@21
   182
inline char *
dvander@21
   183
Array::chars()
dvander@21
   184
{
dvander@188
   185
    assert(type()->isCharArray());
dvander@188
   186
    return reinterpret_cast<char *>(bytes());
dvander@21
   187
}
dvander@21
   188
dvander@209
   189
inline ArrayType *
dvander@21
   190
Array::type()
dvander@21
   191
{
dvander@21
   192
    return ArrayMap::cast(map())->type();
dvander@21
   193
}
dvander@21
   194
dvander@21
   195
inline size_t
dvander@188
   196
Array::objSize(ArrayMap *map)
dvander@21
   197
{
dvander@188
   198
    assert(this->map() == map);
dvander@188
   199
    if (map->type()->hasInlineElements())
dvander@188
   200
        return sizeof(Array) + Array::SizeForElement(map->type()) * length();
dvander@188
   201
    return sizeof(Array);
dvander@21
   202
}
dvander@21
   203
dvander@12
   204
}
dvander@12
   205
dvander@12
   206
#endif // _include_jitcraft_array_h_