diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.object.basic/src/com/oracle/truffle/object/basic/BasicLocations.java	Tue Nov 18 23:19:43 2014 +0100
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.object.basic;
+
+import java.lang.invoke.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.object.*;
+import com.oracle.truffle.object.*;
+import com.oracle.truffle.object.LocationImpl.InternalLongLocation;
+
+/**
+ * Property location.
+ *
+ * @see Shape
+ * @see Property
+ * @see DynamicObject
+ */
+public abstract class BasicLocations {
+    static final int LONG_SIZE = 1;
+    static final int OBJECT_SIZE = 1;
+
+    public abstract static class ArrayLocation extends LocationImpl {
+        protected final int index;
+        protected final Location arrayLocation;
+
+        public ArrayLocation(int index, Location arrayLocation) {
+            this.index = index;
+            this.arrayLocation = arrayLocation;
+        }
+
+        protected final Object getArray(DynamicObject store, boolean condition) {
+            // non-null cast
+            return arrayLocation.get(store, condition);
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = super.hashCode();
+            result = prime * result + index;
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!super.equals(obj)) {
+                return false;
+            }
+            ArrayLocation other = (ArrayLocation) obj;
+            if (index != other.index) {
+                return false;
+            }
+            return true;
+        }
+
+        public final int getIndex() {
+            return index;
+        }
+
+        @Override
+        protected String getWhereString() {
+            return "[" + index + "]";
+        }
+    }
+
+    public abstract static class FieldLocation extends LocationImpl {
+        private final int index;
+
+        public FieldLocation(int index) {
+            this.index = index;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = super.hashCode();
+            result = prime * result + index;
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!super.equals(obj)) {
+                return false;
+            }
+            FieldLocation other = (FieldLocation) obj;
+            if (index != other.index) {
+                return false;
+            }
+            return true;
+        }
+
+        public final int getIndex() {
+            return index;
+        }
+
+        @Override
+        protected String getWhereString() {
+            return "@" + index;
+        }
+    }
+
+    public abstract static class MethodHandleFieldLocation extends FieldLocation {
+        protected final MethodHandle getter;
+        protected final MethodHandle setter;
+
+        public MethodHandleFieldLocation(int index, MethodHandle getter, MethodHandle setter) {
+            super(index);
+            this.getter = getter;
+            this.setter = setter;
+        }
+    }
+
+    public static class ObjectArrayLocation extends ArrayLocation implements ObjectLocation {
+        public ObjectArrayLocation(int index, Location arrayLocation) {
+            super(index, arrayLocation);
+        }
+
+        @Override
+        public Object get(DynamicObject store, boolean condition) {
+            return ((Object[]) getArray(store, condition))[index];
+        }
+
+        @Override
+        public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
+            ((Object[]) getArray(store, false))[index] = value;
+        }
+
+        @Override
+        public boolean canStore(Object value) {
+            return true;
+        }
+
+        public Class<? extends Object> getType() {
+            return Object.class;
+        }
+
+        public final boolean isNonNull() {
+            return false;
+        }
+
+        @Override
+        public int objectArrayCount() {
+            return OBJECT_SIZE;
+        }
+    }
+
+    public static class ObjectFieldLocation extends MethodHandleFieldLocation implements ObjectLocation {
+
+        public ObjectFieldLocation(int index, MethodHandle getter, MethodHandle setter) {
+            super(index, getter, setter);
+        }
+
+        @Override
+        public Object get(DynamicObject store, boolean condition) {
+            try {
+                return getter.invokeExact(store);
+            } catch (Throwable e) {
+                CompilerDirectives.transferToInterpreter();
+                throw new IllegalStateException(e);
+            }
+        }
+
+        @Override
+        public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
+            try {
+                setter.invokeExact(store, value);
+            } catch (Throwable e) {
+                CompilerDirectives.transferToInterpreter();
+                throw new IllegalStateException(e);
+            }
+        }
+
+        @Override
+        public boolean canStore(Object value) {
+            return true;
+        }
+
+        public Class<? extends Object> getType() {
+            return Object.class;
+        }
+
+        public boolean isNonNull() {
+            return false;
+        }
+
+        @Override
+        public int objectFieldCount() {
+            return OBJECT_SIZE;
+        }
+    }
+
+    public abstract static class SimpleObjectFieldLocation extends FieldLocation implements ObjectLocation {
+
+        public SimpleObjectFieldLocation(int index) {
+            super(index);
+        }
+
+        @Override
+        public abstract Object get(DynamicObject store, boolean condition);
+
+        @Override
+        public abstract void setInternal(DynamicObject store, Object value);
+
+        @Override
+        public boolean canStore(Object value) {
+            return true;
+        }
+
+        public Class<? extends Object> getType() {
+            return Object.class;
+        }
+
+        public boolean isNonNull() {
+            return false;
+        }
+
+        @Override
+        public int objectFieldCount() {
+            return OBJECT_SIZE;
+        }
+    }
+
+    public static class LongArrayLocation extends ArrayLocation implements InternalLongLocation {
+        protected final boolean allowInt;
+
+        public LongArrayLocation(int index, Location arrayLocation, boolean allowInt) {
+            super(index, arrayLocation);
+            this.allowInt = allowInt;
+        }
+
+        public LongArrayLocation(int index, Location arrayLocation) {
+            this(index, arrayLocation, false);
+        }
+
+        @Override
+        public final Object get(DynamicObject store, boolean condition) {
+            return getLong(store, condition);
+        }
+
+        @Override
+        public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
+            if (canStore(value)) {
+                setLongInternal(store, ((Number) value).longValue());
+            } else {
+                throw incompatibleLocation();
+            }
+        }
+
+        @Override
+        public long getLong(DynamicObject store, boolean condition) {
+            return ((long[]) getArray(store, condition))[index];
+        }
+
+        public final void setLongInternal(DynamicObject store, long value) {
+            ((long[]) getArray(store, false))[index] = value;
+        }
+
+        @Override
+        public void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException {
+            setLongInternal(store, value);
+        }
+
+        @Override
+        public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) {
+            store.setShapeAndGrow(oldShape, newShape);
+            setLongInternal(store, value);
+        }
+
+        @Override
+        public final void setLong(DynamicObject store, long value) throws FinalLocationException {
+            setLong(store, value, null);
+        }
+
+        public final long getLong(DynamicObject store, Shape shape) {
+            return getLong(store, checkShape(store, shape));
+        }
+
+        @Override
+        public final boolean canStore(Object value) {
+            return value instanceof Long || (allowInt && value instanceof Integer);
+        }
+
+        public Class<Long> getType() {
+            return long.class;
+        }
+
+        @Override
+        public int primitiveArrayCount() {
+            return LONG_SIZE;
+        }
+    }
+
+    public static class LongFieldLocation extends MethodHandleFieldLocation implements InternalLongLocation {
+        public LongFieldLocation(int index, MethodHandle getter, MethodHandle setter) {
+            super(index, getter, setter);
+        }
+
+        public static LongLocation create(InternalLongLocation longLocation, boolean allowInt) {
+            if ((!allowInt && (longLocation instanceof LongLocationDecorator)) || (longLocation instanceof LongLocationDecorator && ((LongLocationDecorator) longLocation).allowInt == allowInt)) {
+                return longLocation;
+            } else {
+                return new LongLocationDecorator(longLocation, allowInt);
+            }
+        }
+
+        @Override
+        public final Object get(DynamicObject store, boolean condition) {
+            return getLong(store, condition);
+        }
+
+        @Override
+        public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
+            if (canStore(value)) {
+                setLongInternal(store, (long) value);
+            } else {
+                throw incompatibleLocation();
+            }
+        }
+
+        @Override
+        public final boolean canStore(Object value) {
+            return value instanceof Long;
+        }
+
+        @Override
+        public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) {
+            store.setShapeAndGrow(oldShape, newShape);
+            setLongInternal(store, value);
+        }
+
+        public long getLong(DynamicObject store, boolean condition) {
+            try {
+                return (long) getter.invokeExact(store);
+            } catch (Throwable e) {
+                CompilerDirectives.transferToInterpreter();
+                throw new IllegalStateException(e);
+            }
+        }
+
+        public void setLong(DynamicObject store, long value, Shape shape) {
+            setLongInternal(store, value);
+        }
+
+        public final void setLong(DynamicObject store, long value) throws FinalLocationException {
+            setLong(store, value, null);
+        }
+
+        public final void setLongInternal(DynamicObject store, long value) {
+            try {
+                setter.invokeExact(store, value);
+            } catch (Throwable e) {
+                CompilerDirectives.transferToInterpreter();
+                throw new IllegalStateException(e);
+            }
+        }
+
+        public final long getLong(DynamicObject store, Shape shape) {
+            return getLong(store, checkShape(store, shape));
+        }
+
+        @Override
+        public final int primitiveFieldCount() {
+            return LONG_SIZE;
+        }
+
+        public Class<Long> getType() {
+            return long.class;
+        }
+    }
+
+    public static class LongLocationDecorator extends PrimitiveLocationDecorator implements InternalLongLocation {
+        protected final boolean allowInt;
+
+        public LongLocationDecorator(InternalLongLocation longLocation, boolean allowInt) {
+            super(longLocation);
+            this.allowInt = allowInt;
+        }
+
+        @Override
+        public final Object get(DynamicObject store, boolean condition) {
+            return getLong(store, condition);
+        }
+
+        @Override
+        public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
+            if (canStore(value)) {
+                setLongInternal(store, ((Number) value).longValue());
+            } else {
+                throw incompatibleLocation();
+            }
+        }
+
+        @Override
+        public final boolean canStore(Object value) {
+            return value instanceof Long || (allowInt && value instanceof Integer);
+        }
+
+        @Override
+        public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) {
+            store.setShapeAndGrow(oldShape, newShape);
+            setLongInternal(store, value);
+        }
+
+        public Class<Long> getType() {
+            return long.class;
+        }
+    }
+
+    public abstract static class SimpleLongFieldLocation extends FieldLocation implements InternalLongLocation {
+
+        public SimpleLongFieldLocation(int index) {
+            super(index);
+        }
+
+        @Override
+        public final Object get(DynamicObject store, boolean condition) {
+            return getLong(store, condition);
+        }
+
+        @Override
+        public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
+            if (canStore(value)) {
+                setLongInternal(store, ((Number) value).longValue());
+            } else {
+                throw incompatibleLocation();
+            }
+        }
+
+        @Override
+        public final boolean canStore(Object value) {
+            return value instanceof Long;
+        }
+
+        @Override
+        public final void setLong(DynamicObject store, long value, Shape oldShape, Shape newShape) {
+            store.setShapeAndGrow(oldShape, newShape);
+            setLongInternal(store, value);
+        }
+
+        public abstract long getLong(DynamicObject store, boolean condition);
+
+        public final long getLong(DynamicObject store, Shape shape) {
+            return getLong(store, checkShape(store, shape));
+        }
+
+        public final void setLong(DynamicObject store, long value) {
+            setLong(store, value, null);
+        }
+
+        public void setLong(DynamicObject store, long value, Shape shape) {
+            setLongInternal(store, value);
+        }
+
+        public abstract void setLongInternal(DynamicObject store, long value);
+
+        @Override
+        public final int primitiveFieldCount() {
+            return LONG_SIZE;
+        }
+
+        public Class<Long> getType() {
+            return long.class;
+        }
+    }
+
+    public abstract static class PrimitiveLocationDecorator extends LocationImpl {
+        private final InternalLongLocation longLocation;
+
+        public PrimitiveLocationDecorator(InternalLongLocation longLocation) {
+            this.longLocation = longLocation;
+        }
+
+        public final long getLong(DynamicObject store, Shape shape) {
+            return longLocation.getLong(store, shape);
+        }
+
+        public final long getLong(DynamicObject store, boolean condition) {
+            return longLocation.getLong(store, condition);
+        }
+
+        public final void setLong(DynamicObject store, long value, Shape shape) throws FinalLocationException {
+            longLocation.setLong(store, value, shape);
+        }
+
+        public final void setLong(DynamicObject store, long value) throws FinalLocationException {
+            longLocation.setLong(store, value);
+        }
+
+        public final void setLongInternal(DynamicObject store, long value) {
+            longLocation.setLongInternal(store, value);
+        }
+
+        @Override
+        public final int primitiveFieldCount() {
+            return ((LocationImpl) longLocation).primitiveFieldCount();
+        }
+
+        @Override
+        public final int primitiveArrayCount() {
+            return ((LocationImpl) longLocation).primitiveArrayCount();
+        }
+    }
+
+    public static class IntLocationDecorator extends PrimitiveLocationDecorator implements IntLocation {
+        public IntLocationDecorator(InternalLongLocation longLocation) {
+            super(longLocation);
+        }
+
+        @Override
+        public final Object get(DynamicObject store, boolean condition) {
+            return getInt(store, condition);
+        }
+
+        public int getInt(DynamicObject store, boolean condition) {
+            return (int) getLong(store, condition);
+        }
+
+        public void setInt(DynamicObject store, int value, Shape shape) throws FinalLocationException {
+            setLong(store, value, shape);
+        }
+
+        @Override
+        public final void setInt(DynamicObject store, int value) throws FinalLocationException {
+            setInt(store, value, null);
+        }
+
+        @Override
+        public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
+            if (canStore(value)) {
+                setLongInternal(store, (int) value);
+            } else {
+                throw incompatibleLocation();
+            }
+        }
+
+        public final int getInt(DynamicObject store, Shape shape) {
+            return getInt(store, checkShape(store, shape));
+        }
+
+        @Override
+        public final boolean canStore(Object value) {
+            return value instanceof Integer;
+        }
+
+        @Override
+        public final void setInt(DynamicObject store, int value, Shape oldShape, Shape newShape) {
+            store.setShapeAndGrow(oldShape, newShape);
+            setLongInternal(store, value);
+        }
+
+        public Class<Integer> getType() {
+            return int.class;
+        }
+    }
+
+    public static class DoubleLocationDecorator extends PrimitiveLocationDecorator implements DoubleLocation {
+        private final boolean allowInt;
+
+        public DoubleLocationDecorator(InternalLongLocation longLocation, boolean allowInt) {
+            super(longLocation);
+            this.allowInt = allowInt;
+        }
+
+        @Override
+        public final Object get(DynamicObject store, boolean condition) {
+            return getDouble(store, condition);
+        }
+
+        public double getDouble(DynamicObject store, boolean condition) {
+            return Double.longBitsToDouble(getLong(store, condition));
+        }
+
+        public void setDouble(DynamicObject store, double value, Shape shape) {
+            setLongInternal(store, Double.doubleToRawLongBits(value));
+        }
+
+        public void setDouble(DynamicObject store, double value) {
+            setDouble(store, value, null);
+        }
+
+        @Override
+        public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
+            if (canStore(value)) {
+                setDouble(store, ((Number) value).doubleValue(), null);
+            } else {
+                throw incompatibleLocation();
+            }
+        }
+
+        public final double getDouble(DynamicObject store, Shape shape) {
+            return getDouble(store, checkShape(store, shape));
+        }
+
+        @Override
+        public final boolean canStore(Object value) {
+            return value instanceof Double || (allowInt && value instanceof Integer);
+        }
+
+        @Override
+        public final void setDouble(DynamicObject store, double value, Shape oldShape, Shape newShape) {
+            store.setShapeAndGrow(oldShape, newShape);
+            setDouble(store, value, newShape);
+        }
+
+        public Class<Double> getType() {
+            return double.class;
+        }
+    }
+
+    public static class BooleanLocationDecorator extends PrimitiveLocationDecorator implements BooleanLocation {
+        public BooleanLocationDecorator(InternalLongLocation longLocation) {
+            super(longLocation);
+        }
+
+        @Override
+        public final Object get(DynamicObject store, boolean condition) {
+            return getBoolean(store, condition);
+        }
+
+        public boolean getBoolean(DynamicObject store, boolean condition) {
+            return getLong(store, condition) != 0;
+        }
+
+        public void setBoolean(DynamicObject store, boolean value, Shape shape) {
+            setLongInternal(store, value ? 1 : 0);
+        }
+
+        public void setBoolean(DynamicObject store, boolean value) {
+            setBoolean(store, value, null);
+        }
+
+        @Override
+        public final void setInternal(DynamicObject store, Object value) throws IncompatibleLocationException {
+            if (canStore(value)) {
+                setBoolean(store, (boolean) value, null);
+            } else {
+                throw incompatibleLocation();
+            }
+        }
+
+        public final boolean getBoolean(DynamicObject store, Shape shape) {
+            return getBoolean(store, checkShape(store, shape));
+        }
+
+        @Override
+        public final boolean canStore(Object value) {
+            return value instanceof Boolean;
+        }
+
+        @Override
+        public final void setBoolean(DynamicObject store, boolean value, Shape oldShape, Shape newShape) {
+            store.setShapeAndGrow(oldShape, newShape);
+            setBoolean(store, value, newShape);
+        }
+
+        public Class<Boolean> getType() {
+            return boolean.class;
+        }
+    }
+}