src/Array.h
changeset 86 32ad0523b309
parent 72 40746ab0a30b
child 91 5f4402180204
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/Array.h	Tue Jul 24 23:53:34 2012 -0700
     1.3 @@ -0,0 +1,204 @@
     1.4 +/*
     1.5 + * Copyright (C) 2012 David Anderson
     1.6 + *
     1.7 + * This file is part of JITCraft.
     1.8 + *
     1.9 + * JITCraft is free software: you can redistribute it and/or modify it under
    1.10 + * the terms of the GNU General Public License as published by the Free
    1.11 + * Software Foundation, either version 3 of the License, or (at your option)
    1.12 + * any later version.
    1.13 + * 
    1.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    1.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License along with
    1.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
    1.20 + */
    1.21 +#ifndef _include_jitcraft_array_h_
    1.22 +#define _include_jitcraft_array_h_
    1.23 +
    1.24 +#include "Heap.h"
    1.25 +#include "Handles.h"
    1.26 +#include "Types.h"
    1.27 +
    1.28 +namespace ke {
    1.29 +
    1.30 +class ArrayMap;
    1.31 +
    1.32 +class Array : public Object
    1.33 +{
    1.34 +    friend class ArrayMap;
    1.35 +
    1.36 +    uint32 nelements_;
    1.37 +    void *elements_;
    1.38 +
    1.39 +  public:
    1.40 +    static Array *New(Zone *zone, Handle<ArrayMap> map, uint32 elements,
    1.41 +                      Heap::Tenure = Heap::Tenure_Default);
    1.42 +    static Array *NewExternal(Zone *zone, Handle<ArrayMap> map, uint32 nelements,
    1.43 +                              void *elements, Heap::Tenure = Heap::Tenure_Default);
    1.44 +
    1.45 +    uint32 nelements() {
    1.46 +        return nelements_;
    1.47 +    }
    1.48 +    void *vec() {
    1.49 +        return elements_;
    1.50 +    }
    1.51 +
    1.52 +    inline int *int32Vec();
    1.53 +    inline float *floatVec();
    1.54 +    inline Object **objVec();
    1.55 +    inline char *chars();
    1.56 +
    1.57 +    inline Type *type();
    1.58 +    inline size_t elementSize();
    1.59 +
    1.60 +    int readInt32(size_t index) {
    1.61 +        assert(index < nelements());
    1.62 +        return int32Vec()[index];
    1.63 +    }
    1.64 +    void writeInt32(size_t index, int i) {
    1.65 +        assert(index < nelements());
    1.66 +        int32Vec()[index] = i;
    1.67 +    }
    1.68 +    char readChar(size_t index) {
    1.69 +        assert(index < nelements());
    1.70 +        return chars()[index];
    1.71 +    }
    1.72 +    void writeChar(size_t index, char c) {
    1.73 +        assert(index < nelements());
    1.74 +        chars()[index] = c;
    1.75 +    }
    1.76 +    float readFloat(size_t index) {
    1.77 +        assert(index < nelements());
    1.78 +        return floatVec()[index];
    1.79 +    }
    1.80 +    void writeFloat(size_t index, float f) {
    1.81 +        assert(index < nelements());
    1.82 +        floatVec()[index] = f;
    1.83 +    }
    1.84 +    inline void *slotPtr(size_t index);
    1.85 +    Object *readObject(size_t index) {
    1.86 +        assert(index < nelements());
    1.87 +        return objVec()[index];
    1.88 +    }
    1.89 +    void writeObject(Zone *zone, size_t index, Object *ptr) {
    1.90 +        assert(index < nelements());
    1.91 +        write(zone, &objVec()[index], ptr);
    1.92 +    }
    1.93 +
    1.94 +    bool isExternal() {
    1.95 +        // Inline arrays always have their elements pointing at the next slot.
    1.96 +        Address buffer = reinterpret_cast<Address>(elements_);
    1.97 +        return buffer != reinterpret_cast<Address>(this + 1);
    1.98 +    }
    1.99 +
   1.100 +    static inline size_t SizeOf(Array *array) {
   1.101 +        if (array->isExternal())
   1.102 +            return sizeof(Array);
   1.103 +        return sizeof(Array) + array->nelements() * array->elementSize();
   1.104 +    }
   1.105 +
   1.106 +    static Array *cast(Object *obj) {
   1.107 +        assert(!obj || obj->is(MapKind_Array));
   1.108 +        return reinterpret_cast<Array *>(obj);
   1.109 +    }
   1.110 +};
   1.111 +
   1.112 +class ArrayMap : public Map
   1.113 +{
   1.114 +    Barriered<Type> type_;
   1.115 +    Barriered<ArrayMap> contained_;
   1.116 +
   1.117 +  public:
   1.118 +    static ArrayMap *New(Zone *zone, Handle<Type> type, Handle<ArrayMap> contained);
   1.119 +
   1.120 +    Type *type() {
   1.121 +        return type_;
   1.122 +    }
   1.123 +    ArrayMap *contained() {
   1.124 +        return contained_;
   1.125 +    }
   1.126 +
   1.127 +    // GC Descriptor.
   1.128 +    static inline size_t offsetOfType() {
   1.129 +        return offsetof(ArrayMap, type_);
   1.130 +    }
   1.131 +    static inline size_t offsetOfContained() {
   1.132 +        return offsetof(ArrayMap, contained_);
   1.133 +    }
   1.134 +    // End GC Descriptor.
   1.135 +    
   1.136 +    static ArrayMap *cast(Object *obj) {
   1.137 +        assert(!obj || obj->is(MapKind_MetaArray));
   1.138 +        return reinterpret_cast<ArrayMap *>(obj);
   1.139 +    }
   1.140 +};
   1.141 +
   1.142 +inline int *
   1.143 +Array::int32Vec()
   1.144 +{
   1.145 +    assert(type()->levels() == 1);
   1.146 +    assert(type()->contained()->isInt32());
   1.147 +    return reinterpret_cast<int *>(vec());
   1.148 +}
   1.149 +
   1.150 +inline float *
   1.151 +Array::floatVec()
   1.152 +{
   1.153 +    assert(type()->levels() == 1);
   1.154 +    assert(type()->contained()->isFloat());
   1.155 +    return reinterpret_cast<float *>(vec());
   1.156 +}
   1.157 +
   1.158 +inline Object **
   1.159 +Array::objVec()
   1.160 +{
   1.161 +    assert(type()->levels() > 1);
   1.162 +    return reinterpret_cast<Object **>(vec());
   1.163 +}
   1.164 +
   1.165 +inline void *
   1.166 +Array::slotPtr(size_t index)
   1.167 +{
   1.168 +    assert(type()->contained()->primitive() == PrimitiveType_Int32 ||
   1.169 +           type()->contained()->primitive() == PrimitiveType_Float);
   1.170 +    assert(index < nelements());
   1.171 +    return reinterpret_cast<int *>(vec()) + index;
   1.172 +}
   1.173 +
   1.174 +inline char *
   1.175 +Array::chars()
   1.176 +{
   1.177 +    assert(type()->levels() == 1);
   1.178 +    assert(type()->contained()->primitive() == PrimitiveType_Char);
   1.179 +    return reinterpret_cast<char *>(vec());
   1.180 +}
   1.181 +
   1.182 +inline Type *
   1.183 +Array::type()
   1.184 +{
   1.185 +    return ArrayMap::cast(map())->type();
   1.186 +}
   1.187 +
   1.188 +inline size_t
   1.189 +Array::elementSize()
   1.190 +{
   1.191 +    assert(type()->isArray());
   1.192 +    if (type()->contained()->isArray())
   1.193 +        return sizeof(Object *);
   1.194 +    switch (type()->contained()->primitive()) {
   1.195 +      case PrimitiveType_Float:
   1.196 +        return sizeof(float);
   1.197 +      case PrimitiveType_Int32:
   1.198 +        return sizeof(int);
   1.199 +      default:
   1.200 +        assert(type()->contained()->primitive() == PrimitiveType_Char);
   1.201 +        return sizeof(char);
   1.202 +    }
   1.203 +}
   1.204 +
   1.205 +}
   1.206 +
   1.207 +#endif // _include_jitcraft_array_h_