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

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

Check for element type before filling vectors
(Olof-Joachim Frahm)

Addresses <https://github.com/armedbear/abcl/pull/104>.
Via <https://github.com/armedbear/abcl/pull/104/commits/762cb878a7273fbf82b4415456d88af378934063>.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.1 KB
Line 
1/*
2 * ComplexArray_UnsignedByte32.java
3 *
4 * Copyright (C) 2003-2005 Peter Graves
5 * $Id: ComplexArray_UnsignedByte32.java 15143 2019-11-01 21:23:12Z 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
38public final class ComplexArray_UnsignedByte32 extends AbstractArray
39{
40    private final int[] dimv;
41    private int totalSize;
42
43    // For non-displaced arrays.
44    // FIXME We should really use an array of unboxed values!
45    private LispObject[] data;
46
47    // For displaced arrays.
48    private AbstractArray array;
49    private int displacement;
50
51    public ComplexArray_UnsignedByte32(int[] dimv)
52    {
53        this.dimv = dimv;
54        totalSize = computeTotalSize(dimv);
55        data = new LispObject[totalSize];
56        for (int i = totalSize; i-- > 0;)
57            data[i] = NIL;
58    }
59
60    public ComplexArray_UnsignedByte32(int[] dimv, LispObject initialContents)
61
62    {
63        this.dimv = dimv;
64        final int rank = dimv.length;
65        LispObject rest = initialContents;
66        for (int i = 0; i < rank; i++) {
67            dimv[i] = rest.length();
68            rest = rest.elt(0);
69        }
70        totalSize = computeTotalSize(dimv);
71        data = new LispObject[totalSize];
72        setInitialContents(0, dimv, initialContents, 0);
73    }
74
75    public ComplexArray_UnsignedByte32(int[] dimv, AbstractArray array,
76                                       int displacement)
77    {
78        this.dimv = dimv;
79        this.array = array;
80        this.displacement = displacement;
81        totalSize = computeTotalSize(dimv);
82    }
83
84    private int setInitialContents(int axis, int[] dims, LispObject contents,
85                                   int index)
86
87    {
88        if (dims.length == 0) {
89            try {
90                data[index] = contents;
91            }
92            catch (ArrayIndexOutOfBoundsException e) {
93                error(new LispError("Bad initial contents for array."));
94                return -1;
95            }
96            ++index;
97        } else {
98            int dim = dims[0];
99            if (dim != contents.length()) {
100                error(new LispError("Bad initial contents for array."));
101                return -1;
102            }
103            int[] newDims = new int[dims.length-1];
104            for (int i = 1; i < dims.length; i++)
105                newDims[i-1] = dims[i];
106            if (contents.listp()) {
107                for (int i = contents.length();i-- > 0;) {
108                    LispObject content = contents.car();
109                    index =
110                        setInitialContents(axis + 1, newDims, content, index);
111                    contents = contents.cdr();
112                }
113            } else {
114                AbstractVector v = checkVector(contents);
115                final int length = v.length();
116                for (int i = 0; i < length; i++) {
117                    LispObject content = v.AREF(i);
118                    index =
119                        setInitialContents(axis + 1, newDims, content, index);
120                }
121            }
122        }
123        return index;
124    }
125
126    @Override
127    public LispObject typeOf()
128    {
129        return list(Symbol.ARRAY, UNSIGNED_BYTE_32, getDimensions());
130    }
131
132    @Override
133    public LispObject classOf()
134    {
135        return BuiltInClass.ARRAY;
136    }
137
138    @Override
139    public int getRank()
140    {
141        return dimv.length;
142    }
143
144    @Override
145    public LispObject getDimensions()
146    {
147        LispObject result = NIL;
148        for (int i = dimv.length; i-- > 0;)
149            result = new Cons(Fixnum.getInstance(dimv[i]), result);
150        return result;
151    }
152
153    @Override
154    public int getDimension(int n)
155    {
156        try {
157            return dimv[n];
158        }
159        catch (ArrayIndexOutOfBoundsException e) {
160            error(new TypeError("Bad array dimension " + n + "."));
161            return -1;
162        }
163    }
164
165    @Override
166    public LispObject getElementType()
167    {
168        return UNSIGNED_BYTE_32;
169    }
170
171    @Override
172    public int getTotalSize()
173    {
174        return totalSize;
175    }
176
177    @Override
178    public LispObject arrayDisplacement()
179    {
180        LispObject value1, value2;
181        if (array != null) {
182            value1 = array;
183            value2 = Fixnum.getInstance(displacement);
184        } else {
185            value1 = NIL;
186            value2 = Fixnum.ZERO;
187        }
188        return LispThread.currentThread().setValues(value1, value2);
189    }
190
191    @Override
192    public LispObject AREF(int index)
193    {
194        if (data != null) {
195            try {
196                return data[index];
197            }
198            catch (ArrayIndexOutOfBoundsException e) {
199                return error(new TypeError("Bad row major index " + index + "."));
200            }
201        } else
202            return array.AREF(index + displacement);
203    }
204
205    @Override
206    public void aset(int index, LispObject newValue)
207    {
208        if (data != null) {
209            try {
210                data[index] = newValue;
211            }
212            catch (ArrayIndexOutOfBoundsException e) {
213                error(new TypeError("Bad row major index " + index + "."));
214            }
215        } else
216            array.aset(index + displacement, newValue);
217    }
218
219    @Override
220    public void fill(LispObject obj)
221    {
222        if (!(obj instanceof LispInteger)) {
223            type_error(obj, Symbol.INTEGER);
224            // Not reached.
225            return;
226        }
227        if (obj.isLessThan(Fixnum.ZERO) || obj.isGreaterThan(UNSIGNED_BYTE_32_MAX_VALUE)) {
228            type_error(obj, UNSIGNED_BYTE_32);
229        }
230        if (data != null) {
231            for (int i = data.length; i-- > 0;)
232                data[i] = obj;
233        } else {
234            for (int i = totalSize; i-- > 0;)
235                aset(i, obj);
236        }
237    }
238
239    @Override
240    public String printObject()
241    {
242        return printObject(dimv);
243    }
244
245
246    @Override
247    public AbstractArray adjustArray(int[] dims,
248                                              LispObject initialElement,
249                                              LispObject initialContents)
250            {
251        if (isAdjustable()) {
252            if (initialContents != null)
253                setInitialContents(0, dims, initialContents, 0);
254            else {
255                //### FIXME Take the easy way out: we don't want to reorganize
256                // all of the array code yet
257                SimpleArray_UnsignedByte32 tempArray = new SimpleArray_UnsignedByte32(dims);
258                if (initialElement != null)
259                    tempArray.fill(initialElement);
260                SimpleArray_UnsignedByte32.copyArray(this, tempArray);
261                this.data = tempArray.data;
262
263                for (int i = 0; i < dims.length; i++)
264                    dimv[i] = dims[i];
265            }
266            return this;
267        } else {
268            if (initialContents != null)
269                return new ComplexArray_UnsignedByte32(dims, initialContents);
270            else {
271                ComplexArray_UnsignedByte32 newArray = new ComplexArray_UnsignedByte32(dims);
272                if (initialElement != null)
273                    newArray.fill(initialElement);
274                return newArray;
275            }
276        }
277    }
278
279    @Override
280    public AbstractArray adjustArray(int[] dims,
281                                              AbstractArray displacedTo,
282                                              int displacement)
283            {
284        if (isAdjustable()) {
285            for (int i = 0; i < dims.length; i++)
286                dimv[i] = dims[i];
287
288            this.data = null;
289            this.array = displacedTo;
290            this.displacement = displacement;
291            this.totalSize = computeTotalSize(dims);
292
293            return this;
294        } else {
295            ComplexArray_UnsignedByte32 a = new ComplexArray_UnsignedByte32(dims, displacedTo, displacement);
296
297            return a;
298        }
299    }
300}
Note: See TracBrowser for help on using the repository browser.