source: trunk/abcl/src/org/armedbear/lisp/SimpleArray_UnsignedByte32.java

Last change on this file was 15351, checked in by Mark Evenson, 4 years ago

Further (INCOMPLETE) work on byte vectors

GOAL: completely remove allocation of any UnsignedByte32 in

make_array.java. Surprised that it mostly works this way…

Fix directAllocation for SimpleArray_CharBuffer.

TODO: ensure that :nio-buffer argument is used in all cases.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 11.4 KB
Line 
1/*
2 * SimpleArray_UnsignedByte32.java
3 *
4 * Copyright (C) 2003-2005 Peter Graves
5 * $Id: SimpleArray_UnsignedByte32.java 15351 2020-07-23 05:12:10Z mevenson $
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 * As a special exception, the copyright holders of this library give you
22 * permission to link this library with independent modules to produce an
23 * executable, regardless of the license terms of these independent
24 * modules, and to copy and distribute the resulting executable under
25 * terms of your choice, provided that you also meet, for each linked
26 * independent module, the terms and conditions of the license of that
27 * module.  An independent module is a module which is not derived from
28 * or based on this library.  If you modify this library, you may extend
29 * this exception to your version of the library, but you are not
30 * obligated to do so.  If you do not wish to do so, delete this
31 * exception statement from your version.
32 */
33
34package org.armedbear.lisp;
35
36import static org.armedbear.lisp.Lisp.*;
37
38/*
39 N.b. this implementation has problems somewhere with converting bytes
40
41      Not fixing currently, as this type is unused with NIO
42
43(let* ((unspecialized
44         #(2025373960 3099658457 3238582529 148439321
45           3099658456 3238582528 3000000000 1000000000
46           2000000000 2900000000 2400000000 2800000000
47           0 1))
48       (array
49         (make-array (length unspecialized)
50                     :element-type '(unsigned-byte 32)
51                     :initial-contents unspecialized)))
52  (prove:plan (length array))
53  (loop :for i :below (length array)
54        :doing
55           (let ((x0
56                   (elt unspecialized i))
57                 (x1
58                   (elt array i)))
59           (prove:ok
60            (equal x0 x1)
61            (format nil "~a: ~a equals ~a" i x0 x1)))))
62*/
63
64public final class SimpleArray_UnsignedByte32 extends AbstractArray
65{
66    private final int[] dimv;
67    private final int totalSize;
68
69    // FIXME We should really use an array of unboxed values!
70    final LispObject[] data;
71
72    public SimpleArray_UnsignedByte32(int[] dimv)
73    {
74        this.dimv = dimv;
75        totalSize = computeTotalSize(dimv);
76        data = new LispObject[totalSize];
77        for (int i = totalSize; i-- > 0;)
78            data[i] = Fixnum.ZERO;
79    }
80
81    public SimpleArray_UnsignedByte32(int[] dimv, LispObject initialContents)
82
83    {
84        this.dimv = dimv;
85        final int rank = dimv.length;
86        LispObject rest = initialContents;
87        for (int i = 0; i < rank; i++) {
88            dimv[i] = rest.length();
89            rest = rest.elt(0);
90        }
91        totalSize = computeTotalSize(dimv);
92        data = new LispObject[totalSize];
93        setInitialContents(0, dimv, initialContents, 0);
94    }
95
96    public SimpleArray_UnsignedByte32(int rank, LispObject initialContents)
97
98    {
99        if (rank < 2)
100            Debug.assertTrue(false);
101        dimv = new int[rank];
102        LispObject rest = initialContents;
103        for (int i = 0; i < rank; i++) {
104            dimv[i] = rest.length();
105            if (rest == NIL || rest.length() == 0)
106                break;
107            rest = rest.elt(0);
108        }
109        totalSize = computeTotalSize(dimv);
110        data = new LispObject[totalSize];
111        setInitialContents(0, dimv, initialContents, 0);
112    }
113
114    private int setInitialContents(int axis, int[] dims, LispObject contents,
115                                   int index)
116
117    {
118        if (dims.length == 0) {
119            try {
120                data[index] = contents;
121            }
122            catch (ArrayIndexOutOfBoundsException e) {
123                error(new LispError("Bad initial contents for array."));
124                return -1;
125            }
126            ++index;
127        } else {
128            int dim = dims[0];
129            if (dim != contents.length()) {
130                error(new LispError("Bad initial contents for array."));
131                return -1;
132            }
133            int[] newDims = new int[dims.length-1];
134            for (int i = 1; i < dims.length; i++)
135                newDims[i-1] = dims[i];
136            if (contents.listp()) {
137                for (int i = contents.length();i-- > 0;) {
138                    LispObject content = contents.car();
139                    index =
140                        setInitialContents(axis + 1, newDims, content, index);
141                    contents = contents.cdr();
142                }
143            } else {
144                AbstractVector v = checkVector(contents);
145                final int length = v.length();
146                for (int i = 0; i < length; i++) {
147                    LispObject content = v.AREF(i);
148                    index =
149                        setInitialContents(axis + 1, newDims, content, index);
150                }
151            }
152        }
153        return index;
154    }
155
156    @Override
157    public LispObject typeOf()
158    {
159        return list(Symbol.SIMPLE_ARRAY, UNSIGNED_BYTE_32, getDimensions());
160    }
161
162    @Override
163    public LispObject classOf()
164    {
165        return BuiltInClass.SIMPLE_ARRAY;
166    }
167
168    @Override
169    public LispObject typep(LispObject typeSpecifier)
170    {
171        if (typeSpecifier == Symbol.SIMPLE_ARRAY)
172            return T;
173        if (typeSpecifier == BuiltInClass.SIMPLE_ARRAY)
174            return T;
175        return super.typep(typeSpecifier);
176    }
177
178    @Override
179    public int getRank()
180    {
181        return dimv.length;
182    }
183
184    @Override
185    public LispObject getDimensions()
186    {
187        LispObject result = NIL;
188        for (int i = dimv.length; i-- > 0;)
189            result = new Cons(Fixnum.getInstance(dimv[i]), result);
190        return result;
191    }
192
193    @Override
194    public int getDimension(int n)
195    {
196        try {
197            return dimv[n];
198        }
199        catch (ArrayIndexOutOfBoundsException e) {
200            error(new TypeError("Bad array dimension " + n + "."));
201            return -1;
202        }
203    }
204
205    @Override
206    public LispObject getElementType()
207    {
208        return UNSIGNED_BYTE_32;
209    }
210
211    @Override
212    public int getTotalSize()
213    {
214        return totalSize;
215    }
216
217    @Override
218    public boolean isAdjustable()
219    {
220        return false;
221    }
222
223    @Override
224    public LispObject AREF(int index)
225    {
226        try {
227            return data[index];
228        }
229        catch (ArrayIndexOutOfBoundsException e) {
230            return error(new TypeError("Bad row major index " + index + "."));
231        }
232    }
233
234    @Override
235    public void aset(int index, LispObject newValue)
236    {
237        try {
238            data[index] = newValue;
239        }
240        catch (ArrayIndexOutOfBoundsException e) {
241            error(new TypeError("Bad row major index " + index + "."));
242        }
243    }
244
245    @Override
246    public int getRowMajorIndex(int[] subscripts)
247    {
248        final int rank = dimv.length;
249        if (rank != subscripts.length) {
250            StringBuffer sb = new StringBuffer("Wrong number of subscripts (");
251            sb.append(subscripts.length);
252            sb.append(") for array of rank ");
253            sb.append(rank);
254            sb.append('.');
255            program_error(sb.toString());
256        }
257        int sum = 0;
258        int size = 1;
259        for (int i = rank; i-- > 0;) {
260            final int dim = dimv[i];
261            final int lastSize = size;
262            size *= dim;
263            int n = subscripts[i];
264            if (n < 0 || n >= dim) {
265                StringBuffer sb = new StringBuffer("Invalid index ");
266                sb.append(n);
267                sb.append(" for array ");
268                sb.append(this);
269                sb.append('.');
270                program_error(sb.toString());
271            }
272            sum += n * lastSize;
273        }
274        return sum;
275    }
276
277    @Override
278    public LispObject get(int[] subscripts)
279    {
280        try {
281            return data[getRowMajorIndex(subscripts)];
282        }
283        catch (ArrayIndexOutOfBoundsException e) {
284            return error(new TypeError("Bad row major index " +
285                                        getRowMajorIndex(subscripts) + "."));
286        }
287    }
288
289    @Override
290    public void set(int[] subscripts, LispObject newValue)
291
292    {
293        try {
294            data[getRowMajorIndex(subscripts)] = newValue;
295        }
296        catch (ArrayIndexOutOfBoundsException e) {
297            error(new TypeError("Bad row major index " +
298                                 getRowMajorIndex(subscripts) + "."));
299        }
300    }
301
302    @Override
303    public void fill(LispObject obj)
304    {
305        if (!(obj instanceof LispInteger)) {
306            type_error(obj, Symbol.INTEGER);
307            // Not reached.
308            return;
309        }
310        if (obj.isLessThan(Fixnum.ZERO) || obj.isGreaterThan(UNSIGNED_BYTE_32_MAX_VALUE)) {
311            type_error(obj, UNSIGNED_BYTE_32);
312        }
313        for (int i = totalSize; i-- > 0;)
314            data[i] = obj;
315    }
316
317    @Override
318    public String printObject()
319    {
320        if (Symbol.PRINT_READABLY.symbolValue() != NIL) {
321            error(new PrintNotReadable(list(Keyword.OBJECT, this)));
322            // Not reached.
323            return null;
324        }
325        return printObject(dimv);
326    }
327
328    public AbstractArray adjustArray(int[] dimv, LispObject initialElement,
329                                     LispObject initialContents)
330
331    {
332        if (initialContents != null)
333            return new SimpleArray_UnsignedByte32(dimv, initialContents);
334        for (int i = 0; i < dimv.length; i++) {
335            if (dimv[i] != this.dimv[i]) {
336                SimpleArray_UnsignedByte32 newArray =
337                    new SimpleArray_UnsignedByte32(dimv);
338                if (initialElement != null)
339                    newArray.fill(initialElement);
340                copyArray(this, newArray);
341                return newArray;
342            }
343        }
344        // New dimensions are identical to old dimensions.
345        return this;
346    }
347
348    // Copy a1 to a2 for index tuples that are valid for both arrays.
349    static void copyArray(AbstractArray a1, AbstractArray a2)
350
351    {
352        Debug.assertTrue(a1.getRank() == a2.getRank());
353        int[] subscripts = new int[a1.getRank()];
354        int axis = 0;
355        copySubArray(a1, a2, subscripts, axis);
356    }
357
358    private static void copySubArray(AbstractArray a1, AbstractArray a2,
359                                     int[] subscripts, int axis)
360
361    {
362        if (axis < subscripts.length) {
363            final int limit =
364                Math.min(a1.getDimension(axis), a2.getDimension(axis));
365            for (int i = 0; i < limit; i++) {
366                subscripts[axis] = i;
367                copySubArray(a1, a2, subscripts, axis + 1);
368            }
369        } else {
370            int i1 = a1.getRowMajorIndex(subscripts);
371            int i2 = a2.getRowMajorIndex(subscripts);
372            a2.aset(i2, a1.AREF(i1));
373        }
374    }
375
376    public AbstractArray adjustArray(int[] dimv, AbstractArray displacedTo,
377                                     int displacement)
378    {
379        return new ComplexArray(dimv, displacedTo, displacement);
380    }
381}
Note: See TracBrowser for help on using the repository browser.