src/Array.h
author David Anderson <dvander@alliedmods.net>
Sun Jan 06 13:52:21 2013 -0800 (2013-01-06)
changeset 256 3c184218462d
parent 247 7721042bdb67
child 263 ba85a47ee414
permissions -rw-r--r--
Initial implementation of module imports.
[email protected]
     1
/* vim: set ts=4 sw=4 tw=99 et:
[email protected]
     2
 *
[email protected]
     3
 * Copyright (C) 2012 David Anderson
[email protected]
     4
 *
[email protected]
     5
 * This file is part of SourcePawn.
[email protected]
     6
 *
[email protected]
     7
 * SourcePawn is free software: you can redistribute it and/or modify it under
[email protected]
     8
 * the terms of the GNU General Public License as published by the Free
[email protected]
     9
 * Software Foundation, either version 3 of the License, or (at your option)
[email protected]
    10
 * any later version.
[email protected]
    11
 * 
[email protected]
    12
 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
[email protected]
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
[email protected]
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
[email protected]
    15
 *
[email protected]
    16
 * You should have received a copy of the GNU General Public License along with
[email protected]
    17
 * SourcePawn. If not, see http://www.gnu.org/licenses/.
[email protected]
    18
 */
[email protected]
    19
#ifndef _include_jitcraft_array_h_
[email protected]
    20
#define _include_jitcraft_array_h_
[email protected]
    21
[email protected]
    22
#include "Heap.h"
[email protected]
    23
#include "Handles.h"
[email protected]
    24
#include "Types.h"
[email protected]
    25
#include "FixedArray.h"
[email protected]
    26
[email protected]
    27
namespace ke {
[email protected]
    28
[email protected]
    29
class ArrayMap;
[email protected]
    30
[email protected]
    31
class Array : public Object
[email protected]
    32
{
[email protected]
    33
    friend class ArrayMap;
[email protected]
    34
[email protected]
    35
  protected:
[email protected]
    36
    // Note: we do not write barrier |elements_|, since it can be set to
[email protected]
    37
    // arbitrary pointers.
[email protected]
    38
    uint32 length_;
[email protected]
    39
    union {
[email protected]
    40
        void *elements_;
[email protected]
    41
        Object *objelements_;
[email protected]
    42
    };
[email protected]
    43
[email protected]
    44
  protected:
[email protected]
    45
    void updateLengthAndElements(Zone *zone, unsigned length, Object *array) {
[email protected]
    46
        length_ = length;
[email protected]
    47
        write(zone, &objelements_, array);
[email protected]
    48
    }
[email protected]
    49
[email protected]
    50
  public:
[email protected]
    51
    static Array *NewFixed(Zone *zone, Handle<ArrayMap> map, Heap::Tenure = Heap::Tenure_Default);
[email protected]
    52
    static Array *NewString(Zone *zone, Handle<ArrayMap> map, char *buffer, size_t length, Heap::Tenure = Heap::Tenure_Default);
[email protected]
    53
    static Array *NewSized(Zone *zone, Handle<ArrayMap> map, int sizes[MAX_ARRAY_DEPTH], Heap::Tenure = Heap::Tenure_Default);
[email protected]
    54
[email protected]
    55
    static Array *New1D(Zone *zone, Handle<ArrayMap> map, uint32 elements, Heap::Tenure tenure = Heap::Tenure_Default);
[email protected]
    56
    static Array *NewEmpty(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
[email protected]
    57
    static Array *NewRaw(Zone *zone, Handle<ArrayMap> map, unsigned nelements, Heap::Tenure tenure);
[email protected]
    58
[email protected]
    59
    static Array *NewExternal(Zone *zone,
[email protected]
    60
                              Handle<ArrayMap> map,
[email protected]
    61
                              void *buffer,
[email protected]
    62
                              unsigned length,
[email protected]
    63
                              Heap::Tenure tenure = Heap::Tenure_Default);
[email protected]
    64
[email protected]
    65
    // Copies an array from one reference to another, obeying language semantics.
[email protected]
    66
    static bool ShallowCopy(Zone *zone, Handle<Array> dest, Handle<Array> source);
[email protected]
    67
[email protected]
    68
    // Creates a full duplicate of an array, following all array references as if
[email protected]
    69
    // they were fixed. Array references inside structs or objects use ShallowCopy
[email protected]
    70
    // semantics, as this is only intended for duplicating array literals, which
[email protected]
    71
    // cannot contain structs.
[email protected]
    72
    static Array *DeepCopy(Zone *zone, Handle<Array> source, Heap::Tenure tenure);
[email protected]
    73
[email protected]
    74
    uint32 length() {
[email protected]
    75
        return length_;
[email protected]
    76
    }
[email protected]
    77
[email protected]
    78
    inline ArrayType *type();
[email protected]
    79
[email protected]
    80
    inline int *int32Vec();
[email protected]
    81
    inline float *floatVec();
[email protected]
    82
    inline char *chars();
[email protected]
    83
    inline void *bytes();
[email protected]
    84
[email protected]
    85
    bool resize(Zone *zone, size_t newLength);
[email protected]
    86
[email protected]
    87
    static inline size_t SizeForElement(ArrayType *type) {
[email protected]
    88
        if (type->contained()->isTraceable())
[email protected]
    89
            return sizeof(ke::Object *);
[email protected]
    90
        if (type->contained()->isInt32())
[email protected]
    91
            return sizeof(int);
[email protected]
    92
        if (type->contained()->primitive() == PrimitiveType_Char)
[email protected]
    93
            return sizeof(char);
[email protected]
    94
        assert(type->contained()->isFloat());
[email protected]
    95
        return sizeof(float);
[email protected]
    96
    }
[email protected]
    97
[email protected]
    98
    inline size_t objSize(ArrayMap *map);
[email protected]
    99
[email protected]
   100
    int readInt32(size_t index) {
[email protected]
   101
        assert(index < length());
[email protected]
   102
        return int32Vec()[index];
[email protected]
   103
    }
[email protected]
   104
    void writeInt32(size_t index, int i) {
[email protected]
   105
        assert(index < length());
[email protected]
   106
        int32Vec()[index] = i;
[email protected]
   107
    }
[email protected]
   108
    char readChar(size_t index) {
[email protected]
   109
        assert(index < length());
[email protected]
   110
        return chars()[index];
[email protected]
   111
    }
[email protected]
   112
    void writeChar(size_t index, char c) {
[email protected]
   113
        assert(index < length());
[email protected]
   114
        chars()[index] = c;
[email protected]
   115
    }
[email protected]
   116
    float readFloat(size_t index) {
[email protected]
   117
        assert(index < length());
[email protected]
   118
        return floatVec()[index];
[email protected]
   119
    }
[email protected]
   120
    void writeFloat(size_t index, float f) {
[email protected]
   121
        assert(index < length());
[email protected]
   122
        floatVec()[index] = f;
[email protected]
   123
    }
[email protected]
   124
    Object *readObject(size_t index) {
[email protected]
   125
        return FixedArray::cast(objelements_)->at(index);
[email protected]
   126
    }
[email protected]
   127
    void writeObject(Zone *zone, size_t index, Object *ptr) {
[email protected]
   128
        FixedArray::cast(objelements_)->set(zone, index, ptr);
[email protected]
   129
    }
[email protected]
   130
[email protected]
   131
    // GC Descriptor.
[email protected]
   132
    static inline size_t offsetOfElements() {
[email protected]
   133
        return offsetof(Array, objelements_);
[email protected]
   134
    }
[email protected]
   135
    // End GC Descriptor.
[email protected]
   136
[email protected]
   137
    static Array *cast(Object *obj) {
[email protected]
   138
        assert(!obj ||
[email protected]
   139
               obj->is(MapKind_Array) ||
[email protected]
   140
               obj->is(MapKind_DependentArray));
[email protected]
   141
        return reinterpret_cast<Array *>(obj);
[email protected]
   142
    }
[email protected]
   143
};
[email protected]
   144
[email protected]
   145
class DependentArray : public Array
[email protected]
   146
{
[email protected]
   147
    Barriered<Array> root_;
[email protected]
   148
[email protected]
   149
  public:
[email protected]
   150
    static Array *New(Zone *zone, Handle<Array> source, Handle<ArrayMap> map, unsigned index);
[email protected]
   151
[email protected]
   152
    // GC Descriptor.
[email protected]
   153
    static inline size_t offsetOfRoot() {
[email protected]
   154
        return offsetof(DependentArray, root_);
[email protected]
   155
    }
[email protected]
   156
    // End GC Descriptor.
[email protected]
   157
[email protected]
   158
    static DependentArray *cast(Object *obj) {
[email protected]
   159
        assert(!obj || obj->is(MapKind_DependentArray));
[email protected]
   160
        return reinterpret_cast<DependentArray *>(obj);
[email protected]
   161
    }
[email protected]
   162
};
[email protected]
   163
[email protected]
   164
class ArrayMap : public Map
[email protected]
   165
{
[email protected]
   166
    Barriered<ArrayType> type_;
[email protected]
   167
[email protected]
   168
  public:
[email protected]
   169
    static ArrayMap *New(Zone *zone, Handle<ArrayType> type);
dvande[email protected]
   170
[email protected]
   171
    // DependentArray maps are never attached, and are just free-floating,
[email protected]
   172
    // rooted ultimately by the bytecode. A :TODO: that we might need to
[email protected]
   173
    // cache these, or attach them somewhere saner like ArrayType, which
[email protected]
   174
    // itself will eventually be cached.
[email protected]
   175
    static ArrayMap *NewDependent(Zone *zone, Handle<ArrayType> type);
[email protected]
   176
[email protected]
   177
    ArrayType *type() {
[email protected]
   178
        return type_;
[email protected]
   179
    }
[email protected]
   180
[email protected]
   181
    // GC Descriptor.
[email protected]
   182
    static inline size_t offsetOfType() {
[email protected]
   183
        return OFFSETOF(ArrayMap, type_);
[email protected]
   184
    }
[email protected]
   185
    // End GC Descriptor.
[email protected]
   186
    
[email protected]
   187
    static ArrayMap *cast(Object *obj) {
[email protected]
   188
        assert(!obj || obj->is(MapKind_MetaArray));
[email protected]
   189
        return reinterpret_cast<ArrayMap *>(obj);
[email protected]
   190
    }
[email protected]
   191
};
[email protected]
   192
[email protected]
   193
inline void *
[email protected]
   194
Array::bytes()
[email protected]
   195
{
[email protected]
   196
    assert(!type()->contained()->isTraceable());
[email protected]
   197
    assert(type()->hasInlineElements() ||
[email protected]
   198
           type()->isExternalArray() ||
[email protected]
   199
           is(MapKind_DependentArray) ||
[email protected]
   200
           !length() ||
[email protected]
   201
           ByteArray::cast((Object *)elements_));
[email protected]
   202
[email protected]
   203
    return Address(elements_) + ByteArray::offsetToElements();
[email protected]
   204
}
[email protected]
   205
[email protected]
   206
inline int *
[email protected]
   207
Array::int32Vec()
[email protected]
   208
{
[email protected]
   209
    assert(type()->contained()->isInt32());
[email protected]
   210
    return reinterpret_cast<int *>(bytes());
[email protected]
   211
}
[email protected]
   212
[email protected]
   213
inline float *
[email protected]
   214
Array::floatVec()
[email protected]
   215
{
[email protected]
   216
    assert(type()->contained()->isFloat());
[email protected]
   217
    return reinterpret_cast<float *>(bytes());
[email protected]
   218
}
[email protected]
   219
[email protected]
   220
inline char *
[email protected]
   221
Array::chars()
[email protected]
   222
{
[email protected]
   223
    assert(type()->isCharArray());
[email protected]
   224
    return reinterpret_cast<char *>(bytes());
[email protected]
   225
}
[email protected]
   226
[email protected]
   227
inline ArrayType *
[email protected]
   228
Array::type()
[email protected]
   229
{
[email protected]
   230
    return ArrayMap::cast(map())->type();
[email protected]
   231
}
[email protected]
   232
[email protected]
   233
inline size_t
[email protected]
   234
Array::objSize(ArrayMap *map)
[email protected]
   235
{
[email protected]
   236
    assert(this->map() == map);
[email protected]
   237
    if (map->type()->hasInlineElements())
[email protected]
   238
        return sizeof(Array) + Array::SizeForElement(map->type()) * length();
[email protected]
   239
    return sizeof(Array);
[email protected]
   240
}
[email protected]
   241
[email protected]
   242
}
[email protected]
   243
[email protected]
   244
#endif // _include_jitcraft_array_h_