comparison graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/BasicLocations.java @ 18408:2c3666f44855

Truffle: initial commit of object API implementation
author Andreas Woess <andreas.woess@jku.at>
date Tue, 18 Nov 2014 23:19:43 +0100
parents
children e9cbe1618733
comparison
equal deleted inserted replaced
18407:f439fdb137a3 18408:2c3666f44855
1 /*
2 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.truffle.object.basic;
24
25 import java.lang.invoke.*;
26
27 import com.oracle.truffle.api.*;
28 import com.oracle.truffle.api.object.*;
29 import com.oracle.truffle.object.*;
30 import com.oracle.truffle.object.LocationImpl.InternalLongLocation;
31
32 /**
33 * Property location.
34 *
35 * @see Shape
36 * @see Property
37 * @see DynamicObject
38 */
39 public abstract class BasicLocations {
40 static final int LONG_SIZE = 1;
41 static final int OBJECT_SIZE = 1;
42
43 public abstract static class ArrayLocation extends LocationImpl {
44 protected final int index;
45 protected final Location arrayLocation;
46
47 public ArrayLocation(int index, Location arrayLocation) {
48 this.index = index;
49 this.arrayLocation = arrayLocation;
50 }
51
52 protected final Object getArray(DynamicObject store, boolean condition) {
53 // non-null cast
54 return arrayLocation.get(store, condition);
55 }
56
57 @Override
58 public int hashCode() {
59 final int prime = 31;
60 int result = super.hashCode();
61 result = prime * result + index;
62 return result;
63 }
64
65 @Override
66 public boolean equals(Object obj) {
67 if (!super.equals(obj)) {
68 return false;
69 }
70 ArrayLocation other = (ArrayLocation) obj;
71 if (index != other.index) {
72 return false;
73 }
74 return true;
75 }
76
77 public final int getIndex() {
78 return index;
79 }
80
81 @Override
82 protected String getWhereString() {
83 return "[" + index + "]";
84 }
85 }
86
87 public abstract static class FieldLocation extends LocationImpl {
88 private final int index;
89
90 public FieldLocation(int index) {
91 this.index = index;
92 }
93
94 @Override
95 public int hashCode() {
96 final int prime = 31;
97 int result = super.hashCode();
98 result = prime * result + index;
99 return result;
100 }
101
102 @Override
103 public boolean equals(Object obj) {
104 if (!super.equals(obj)) {
105 return false;
106 }
107 FieldLocation other = (FieldLocation) obj;
108 if (index != other.index) {
109 return false;
110 }
111 return true;
112 }
113
114 public final int getIndex() {
115 return index;
116 }
117
118 @Override
119 protected String getWhereString() {
120 return "@" + index;
121 }
122 }
123
124 public abstract static class MethodHandleFieldLocation extends FieldLocation {
125 protected final MethodHandle getter;
126 protected final MethodHandle setter;
127
128 public MethodHandleFieldLocation(int index, MethodHandle getter, MethodHandle setter) {
129 super(index);
130 this.getter = getter;
131 this.setter = setter;
132 }
133 }
134
135 public static class ObjectArrayLocation extends ArrayLocation implements ObjectLocation {
136 public ObjectArrayLocation(int index, Location arrayLocation) {
137 super(index, arrayLocation);
138 }
139
140 @Override
141 public Object get(DynamicObject store, boolean condition) {
142 return ((Object[]) getArray(store, condition))[index];
143 }
144
145 @Override
146 public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
147 ((Object[]) getArray(store, false))[index] = value;
148 }
149
150 @Override
151 public boolean canStore(Object value) {
152 return true;
153 }
154
155 public Class<? extends Object> getType() {
156 return Object.class;
157 }
158
159 public final boolean isNonNull() {
160 return false;
161 }
162
163 @Override
164 public int objectArrayCount() {
165 return OBJECT_SIZE;
166 }
167 }
168
169 public static class ObjectFieldLocation extends MethodHandleFieldLocation implements ObjectLocation {
170
171 public ObjectFieldLocation(int index, MethodHandle getter, MethodHandle setter) {
172 super(index, getter, setter);
173 }
174
175 @Override
176 public Object get(DynamicObject store, boolean condition) {
177 try {
178 return getter.invokeExact(store);
179 } catch (Throwable e) {
180 CompilerDirectives.transferToInterpreter();
181 throw new IllegalStateException(e);
182 }
183 }
184
185 @Override
186 public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
187 try {
188 setter.invokeExact(store, value);
189 } catch (Throwable e) {
190 CompilerDirectives.transferToInterpreter();
191 throw new IllegalStateException(e);
192 }
193 }
194
195 @Override
196 public boolean canStore(Object value) {
197 return true;
198 }
199
200 public Class<? extends Object> getType() {
201 return Object.class;
202 }
203
204 public boolean isNonNull() {
205 return false;
206 }
207
208 @Override
209 public int objectFieldCount() {
210 return OBJECT_SIZE;
211 }
212 }
213
214 public abstract static class SimpleObjectFieldLocation extends FieldLocation implements ObjectLocation {
215
216 public SimpleObjectFieldLocation(int index) {
217 super(index);
218 }
219
220 @Override
221 public abstract Object get(DynamicObject store, boolean condition);
222
223 @Override
224 public abstract void setInternal(DynamicObject store, Object value);
225
226 @Override
227 public boolean canStore(Object value) {
228 return true;
229 }
230
231 public Class<? extends Object> getType() {
232 return Object.class;
233 }
234
235 public boolean isNonNull() {
236 return false;
237 }
238
239 @Override
240 public int objectFieldCount() {
241 return OBJECT_SIZE;
242 }
243 }
244
245 public static class LongArrayLocation extends ArrayLocation implements InternalLongLocation {
246 protected final boolean allowInt;
247
248 public LongArrayLocation(int index, Location arrayLocation, boolean allowInt) {
249 super(index, arrayLocation);
250 this.allowInt = allowInt;
251 }
252
253 public LongArrayLocation(int index, Location arrayLocation) {
254 this(index, arrayLocation, false);
255 }
256
257 @Override
258 public final Object get(DynamicObject store, boolean condition) {
259 return getLong(store, condition);
260 }
261
262 @Override
263 public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
264 if (canStore(value)) {
265 setLongInternal(store, ((Number) value).longValue());
266 } else {
267 throw incompatibleLocation();
268 }
269 }
270
271 @Override
272 public long getLong(DynamicObject store, boolean condition) {
273 return ((long[]) getArray(store, condition))[index];
274 }
275
276 public final void setLongInternal(DynamicObject store, long value) {
277 ((long[]) getArray(store, false))[index] = value;
278 }
279
280 @Override
281 public void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException {
282 setLongInternal(store, value);
283 }
284
285 @Override
286 public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) {
287 store.setShapeAndGrow(oldShape, newShape);
288 setLongInternal(store, value);
289 }
290
291 @Override
292 public final void setLong(DynamicObject store, long value) throws FinalLocationException {
293 setLong(store, value, null);
294 }
295
296 public final long getLong(DynamicObject store, Shape shape) {
297 return getLong(store, checkShape(store, shape));
298 }
299
300 @Override
301 public final boolean canStore(Object value) {
302 return value instanceof Long || (allowInt && value instanceof Integer);
303 }
304
305 public Class<Long> getType() {
306 return long.class;
307 }
308
309 @Override
310 public int primitiveArrayCount() {
311 return LONG_SIZE;
312 }
313 }
314
315 public static class LongFieldLocation extends MethodHandleFieldLocation implements InternalLongLocation {
316 public LongFieldLocation(int index, MethodHandle getter, MethodHandle setter) {
317 super(index, getter, setter);
318 }
319
320 public static LongLocation create(InternalLongLocation longLocation, boolean allowInt) {
321 if ((!allowInt && (longLocation instanceof LongLocationDecorator)) || (longLocation instanceof LongLocationDecorator && ((LongLocationDecorator) longLocation).allowInt == allowInt)) {
322 return longLocation;
323 } else {
324 return new LongLocationDecorator(longLocation, allowInt);
325 }
326 }
327
328 @Override
329 public final Object get(DynamicObject store, boolean condition) {
330 return getLong(store, condition);
331 }
332
333 @Override
334 public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
335 if (canStore(value)) {
336 setLongInternal(store, (long) value);
337 } else {
338 throw incompatibleLocation();
339 }
340 }
341
342 @Override
343 public final boolean canStore(Object value) {
344 return value instanceof Long;
345 }
346
347 @Override
348 public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) {
349 store.setShapeAndGrow(oldShape, newShape);
350 setLongInternal(store, value);
351 }
352
353 public long getLong(DynamicObject store, boolean condition) {
354 try {
355 return (long) getter.invokeExact(store);
356 } catch (Throwable e) {
357 CompilerDirectives.transferToInterpreter();
358 throw new IllegalStateException(e);
359 }
360 }
361
362 public void setLong(DynamicObject store, long value, Shape shape) {
363 setLongInternal(store, value);
364 }
365
366 public final void setLong(DynamicObject store, long value) throws FinalLocationException {
367 setLong(store, value, null);
368 }
369
370 public final void setLongInternal(DynamicObject store, long value) {
371 try {
372 setter.invokeExact(store, value);
373 } catch (Throwable e) {
374 CompilerDirectives.transferToInterpreter();
375 throw new IllegalStateException(e);
376 }
377 }
378
379 public final long getLong(DynamicObject store, Shape shape) {
380 return getLong(store, checkShape(store, shape));
381 }
382
383 @Override
384 public final int primitiveFieldCount() {
385 return LONG_SIZE;
386 }
387
388 public Class<Long> getType() {
389 return long.class;
390 }
391 }
392
393 public static class LongLocationDecorator extends PrimitiveLocationDecorator implements InternalLongLocation {
394 protected final boolean allowInt;
395
396 public LongLocationDecorator(InternalLongLocation longLocation, boolean allowInt) {
397 super(longLocation);
398 this.allowInt = allowInt;
399 }
400
401 @Override
402 public final Object get(DynamicObject store, boolean condition) {
403 return getLong(store, condition);
404 }
405
406 @Override
407 public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
408 if (canStore(value)) {
409 setLongInternal(store, ((Number) value).longValue());
410 } else {
411 throw incompatibleLocation();
412 }
413 }
414
415 @Override
416 public final boolean canStore(Object value) {
417 return value instanceof Long || (allowInt && value instanceof Integer);
418 }
419
420 @Override
421 public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) {
422 store.setShapeAndGrow(oldShape, newShape);
423 setLongInternal(store, value);
424 }
425
426 public Class<Long> getType() {
427 return long.class;
428 }
429 }
430
431 public abstract static class SimpleLongFieldLocation extends FieldLocation implements InternalLongLocation {
432
433 public SimpleLongFieldLocation(int index) {
434 super(index);
435 }
436
437 @Override
438 public final Object get(DynamicObject store, boolean condition) {
439 return getLong(store, condition);
440 }
441
442 @Override
443 public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
444 if (canStore(value)) {
445 setLongInternal(store, ((Number) value).longValue());
446 } else {
447 throw incompatibleLocation();
448 }
449 }
450
451 @Override
452 public final boolean canStore(Object value) {
453 return value instanceof Long;
454 }
455
456 @Override
457 public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) {
458 store.setShapeAndGrow(oldShape, newShape);
459 setLongInternal(store, value);
460 }
461
462 public abstract long getLong(DynamicObject store, boolean condition);
463
464 public final long getLong(DynamicObject store, Shape shape) {
465 return getLong(store, checkShape(store, shape));
466 }
467
468 public final void setLong(DynamicObject store, long value) {
469 setLong(store, value, null);
470 }
471
472 public void setLong(DynamicObject store, long value, Shape shape) {
473 setLongInternal(store, value);
474 }
475
476 public abstract void setLongInternal(DynamicObject store, long value);
477
478 @Override
479 public final int primitiveFieldCount() {
480 return LONG_SIZE;
481 }
482
483 public Class<Long> getType() {
484 return long.class;
485 }
486 }
487
488 public abstract static class PrimitiveLocationDecorator extends LocationImpl {
489 private final InternalLongLocation longLocation;
490
491 public PrimitiveLocationDecorator(InternalLongLocation longLocation) {
492 this.longLocation = longLocation;
493 }
494
495 public final long getLong(DynamicObject store, Shape shape) {
496 return longLocation.getLong(store, shape);
497 }
498
499 public final long getLong(DynamicObject store, boolean condition) {
500 return longLocation.getLong(store, condition);
501 }
502
503 public final void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException {
504 longLocation.setLong(store, value, shape);
505 }
506
507 public final void setLong(DynamicObject store, long value) throws FinalLocationException {
508 longLocation.setLong(store, value);
509 }
510
511 public final void setLongInternal(DynamicObject store, long value) {
512 longLocation.setLongInternal(store, value);
513 }
514
515 @Override
516 public final int primitiveFieldCount() {
517 return ((LocationImpl) longLocation).primitiveFieldCount();
518 }
519
520 @Override
521 public final int primitiveArrayCount() {
522 return ((LocationImpl) longLocation).primitiveArrayCount();
523 }
524 }
525
526 public static class IntLocationDecorator extends PrimitiveLocationDecorator implements IntLocation {
527 public IntLocationDecorator(InternalLongLocation longLocation) {
528 super(longLocation);
529 }
530
531 @Override
532 public final Object get(DynamicObject store, boolean condition) {
533 return getInt(store, condition);
534 }
535
536 public int getInt(DynamicObject store, boolean condition) {
537 return (int) getLong(store, condition);
538 }
539
540 public void setInt(DynamicObject store, int value, Shape shape) throws FinalLocationException {
541 setLong(store, value, shape);
542 }
543
544 @Override
545 public final void setInt(DynamicObject store, int value) throws FinalLocationException {
546 setInt(store, value, null);
547 }
548
549 @Override
550 public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
551 if (canStore(value)) {
552 setLongInternal(store, (int) value);
553 } else {
554 throw incompatibleLocation();
555 }
556 }
557
558 public final int getInt(DynamicObject store, Shape shape) {
559 return getInt(store, checkShape(store, shape));
560 }
561
562 @Override
563 public final boolean canStore(Object value) {
564 return value instanceof Integer;
565 }
566
567 @Override
568 public final void setInt(DynamicObject store, int value, Shape oldShape, Shape newShape) {
569 store.setShapeAndGrow(oldShape, newShape);
570 setLongInternal(store, value);
571 }
572
573 public Class<Integer> getType() {
574 return int.class;
575 }
576 }
577
578 public static class DoubleLocationDecorator extends PrimitiveLocationDecorator implements DoubleLocation {
579 private final boolean allowInt;
580
581 public DoubleLocationDecorator(InternalLongLocation longLocation, boolean allowInt) {
582 super(longLocation);
583 this.allowInt = allowInt;
584 }
585
586 @Override
587 public final Object get(DynamicObject store, boolean condition) {
588 return getDouble(store, condition);
589 }
590
591 public double getDouble(DynamicObject store, boolean condition) {
592 return Double.longBitsToDouble(getLong(store, condition));
593 }
594
595 public void setDouble(DynamicObject store, double value, Shape shape) {
596 setLongInternal(store, Double.doubleToRawLongBits(value));
597 }
598
599 public void setDouble(DynamicObject store, double value) {
600 setDouble(store, value, null);
601 }
602
603 @Override
604 public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
605 if (canStore(value)) {
606 setDouble(store, ((Number) value).doubleValue(), null);
607 } else {
608 throw incompatibleLocation();
609 }
610 }
611
612 public final double getDouble(DynamicObject store, Shape shape) {
613 return getDouble(store, checkShape(store, shape));
614 }
615
616 @Override
617 public final boolean canStore(Object value) {
618 return value instanceof Double || (allowInt && value instanceof Integer);
619 }
620
621 @Override
622 public final void setDouble(DynamicObject store, double value, Shape oldShape, Shape newShape) {
623 store.setShapeAndGrow(oldShape, newShape);
624 setDouble(store, value, newShape);
625 }
626
627 public Class<Double> getType() {
628 return double.class;
629 }
630 }
631
632 public static class BooleanLocationDecorator extends PrimitiveLocationDecorator implements BooleanLocation {
633 public BooleanLocationDecorator(InternalLongLocation longLocation) {
634 super(longLocation);
635 }
636
637 @Override
638 public final Object get(DynamicObject store, boolean condition) {
639 return getBoolean(store, condition);
640 }
641
642 public boolean getBoolean(DynamicObject store, boolean condition) {
643 return getLong(store, condition) != 0;
644 }
645
646 public void setBoolean(DynamicObject store, boolean value, Shape shape) {
647 setLongInternal(store, value ? 1 : 0);
648 }
649
650 public void setBoolean(DynamicObject store, boolean value) {
651 setBoolean(store, value, null);
652 }
653
654 @Override
655 public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
656 if (canStore(value)) {
657 setBoolean(store, (boolean) value, null);
658 } else {
659 throw incompatibleLocation();
660 }
661 }
662
663 public final boolean getBoolean(DynamicObject store, Shape shape) {
664 return getBoolean(store, checkShape(store, shape));
665 }
666
667 @Override
668 public final boolean canStore(Object value) {
669 return value instanceof Boolean;
670 }
671
672 @Override
673 public final void setBoolean(DynamicObject store, boolean value, Shape oldShape, Shape newShape) {
674 store.setShapeAndGrow(oldShape, newShape);
675 setBoolean(store, value, newShape);
676 }
677
678 public Class<Boolean> getType() {
679 return boolean.class;
680 }
681 }
682 }