# HG changeset patch # User Thomas Wuerthinger # Date 1366724046 -7200 # Node ID 07f8d136a05e7dbbb07e49f8183ac1251ce22390 # Parent 542712a4732ab3ee675b4962e948cb11e3801cc9 Truffle API changes for the Frame API. Introduction of Assumptions class. diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -34,12 +34,7 @@ *

* Dynamically typed languages can speculate on the type of a frame slot and only fall back at run * time to a more generic type if necessary. The new type of a frame slot can be set using the - * {@link FrameSlot#setType(Class)} method. It is the responsibility of the language implementor to - * update the content of currently active frames (using {@link Frame#updateToLatestVersion()}). - * Also, nodes that depend a specific type of a frame slot must be replaced. Such node can register - * a listener that implements {@link FrameSlotTypeListener} using - * {@link FrameSlot#registerOneShotTypeListener(FrameSlotTypeListener)}. The event of a type change - * on the frame slot will fire only once for the next upcoming change. + * {@link FrameSlot#setType(Class)} method. *

* *

@@ -53,10 +48,10 @@ public void test() { TruffleRuntime runtime = Truffle.getRuntime(); FrameDescriptor frameDescriptor = new FrameDescriptor(); - FrameSlot slot = frameDescriptor.addFrameSlot("localVar", Integer.class); + FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class); TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); - Assert.assertEquals(Integer.class, slot.getType()); + Assert.assertEquals(int.class, slot.getType()); Object result = target.call(); Assert.assertEquals("42", result); Assert.assertEquals(Object.class, slot.getType()); @@ -102,35 +97,29 @@ } - class IntAssignLocal extends FrameSlotNode implements FrameSlotTypeListener { + class IntAssignLocal extends FrameSlotNode { @Child private TestChildNode value; IntAssignLocal(FrameSlot slot, TestChildNode value) { super(slot); this.value = adoptChild(value); - slot.registerOneShotTypeListener(this); } @Override Object execute(VirtualFrame frame) { Object o = value.execute(frame); if (o instanceof Integer) { - frame.setInt(slot, (Integer) o); - } else { - slot.setType(Object.class); - frame.updateToLatestVersion(); - frame.setObject(slot, o); + try { + frame.setInt(slot, (Integer) o); + } catch (FrameSlotTypeException e) { + // fall through + } } + FrameUtil.setObjectSafe(frame, slot, o); + this.replace(new ObjectAssignLocal(slot, value)); return null; } - - @Override - public void typeChanged(FrameSlot changedSlot, Class oldType) { - if (changedSlot.getType() == Object.class) { - this.replace(new ObjectAssignLocal(changedSlot, value)); - } - } } class ObjectAssignLocal extends FrameSlotNode { @@ -145,27 +134,27 @@ @Override Object execute(VirtualFrame frame) { Object o = value.execute(frame); - frame.setObject(slot, o); + try { + frame.setObject(slot, o); + } catch (FrameSlotTypeException e) { + FrameUtil.setObjectSafe(frame, slot, o); + } return null; } } - class IntReadLocal extends FrameSlotNode implements FrameSlotTypeListener { + class IntReadLocal extends FrameSlotNode { IntReadLocal(FrameSlot slot) { super(slot); - slot.registerOneShotTypeListener(this); } @Override Object execute(VirtualFrame frame) { - return frame.getInt(slot); - } - - @Override - public void typeChanged(FrameSlot changedSlot, Class oldType) { - if (changedSlot.getType() == Object.class) { - this.replace(new ObjectReadLocal(changedSlot)); + try { + return frame.getInt(slot); + } catch (FrameSlotTypeException e) { + return this.replace(new ObjectReadLocal(slot)).execute(frame); } } } @@ -178,7 +167,11 @@ @Override Object execute(VirtualFrame frame) { - return frame.getObject(slot); + try { + return frame.getObject(slot); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(e); + } } } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -64,7 +64,7 @@ public void test() { TruffleRuntime runtime = Truffle.getRuntime(); FrameDescriptor frameDescriptor = new FrameDescriptor(); - FrameSlot slot = frameDescriptor.addFrameSlot("localVar", Integer.class); + FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class); TestRootNode rootNode = new TestRootNode(new AssignLocal(slot), new ReadLocal(slot)); CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); Object result = target.call(); @@ -109,7 +109,11 @@ @Override int execute(VirtualFrame frame) { - frame.setInt(slot, 42); + try { + frame.setInt(slot, 42); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(e); + } return 0; } } @@ -122,7 +126,11 @@ @Override int execute(VirtualFrame frame) { - return frame.getInt(slot); + try { + return frame.getInt(slot); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(e); + } } } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java --- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -47,10 +47,10 @@ public void test() { TruffleRuntime runtime = Truffle.getRuntime(); FrameDescriptor frameDescriptor = new FrameDescriptor(); - FrameSlot slot = frameDescriptor.addFrameSlot("localVar", Integer.class); + FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class); TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); - Assert.assertEquals(Integer.class, slot.getType()); + Assert.assertEquals(int.class, slot.getType()); Object result = target.call(); Assert.assertEquals("42", result); Assert.assertEquals(Object.class, slot.getType()); @@ -104,34 +104,31 @@ } - class IntAssignLocal extends FrameSlotNode implements FrameSlotTypeListener { + class IntAssignLocal extends FrameSlotNode { @Child private TestChildNode value; IntAssignLocal(FrameSlot slot, TestChildNode value) { super(slot); this.value = adoptChild(value); - slot.registerOneShotTypeListener(this); } @Override Object execute(VirtualFrame frame) { try { - frame.setInt(slot, value.executeInt(frame)); + int result = value.executeInt(frame); + try { + frame.setInt(slot, result); + } catch (FrameSlotTypeException e) { + FrameUtil.setObjectSafe(frame, slot, result); + replace(new ObjectAssignLocal(slot, value)); + } } catch (UnexpectedResultException e) { - slot.setType(Object.class); - frame.updateToLatestVersion(); - frame.setObject(slot, e.getResult()); + FrameUtil.setObjectSafe(frame, slot, e.getResult()); + replace(new ObjectAssignLocal(slot, value)); } return null; } - - @Override - public void typeChanged(FrameSlot changedSlot, Class oldType) { - if (changedSlot.getType() == Object.class) { - this.replace(new ObjectAssignLocal(changedSlot, value)); - } - } } class ObjectAssignLocal extends FrameSlotNode { @@ -146,32 +143,36 @@ @Override Object execute(VirtualFrame frame) { Object o = value.execute(frame); - frame.setObject(slot, o); + try { + frame.setObject(slot, o); + } catch (FrameSlotTypeException e) { + FrameUtil.setObjectSafe(frame, slot, o); + } return null; } } - class IntReadLocal extends FrameSlotNode implements FrameSlotTypeListener { + class IntReadLocal extends FrameSlotNode { IntReadLocal(FrameSlot slot) { super(slot); - slot.registerOneShotTypeListener(this); } @Override Object execute(VirtualFrame frame) { - return executeInt(frame); + try { + return frame.getInt(slot); + } catch (FrameSlotTypeException e) { + return replace(new ObjectReadLocal(slot)).execute(frame); + } } @Override - int executeInt(VirtualFrame frame) { - return frame.getInt(slot); - } - - @Override - public void typeChanged(FrameSlot changedSlot, Class oldType) { - if (changedSlot.getType() == Object.class) { - this.replace(new ObjectReadLocal(changedSlot)); + int executeInt(VirtualFrame frame) throws UnexpectedResultException { + try { + return frame.getInt(slot); + } catch (FrameSlotTypeException e) { + return replace(new ObjectReadLocal(slot)).executeInt(frame); } } } @@ -184,7 +185,11 @@ @Override Object execute(VirtualFrame frame) { - return frame.getObject(slot); + try { + return frame.getObject(slot); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(e); + } } } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Assumption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Assumption.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2012, 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.api; + +import com.oracle.truffle.api.nodes.*; + +public interface Assumption { + + void check() throws InvalidAssumptionException; + + void invalidate(); + + String getName(); +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/LoopCountReceiver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/LoopCountReceiver.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2012, 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.api; + +public interface LoopCountReceiver { + + void reportLoopCount(int count); +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Tue Apr 23 15:34:06 2013 +0200 @@ -60,6 +60,21 @@ CallTarget createCallTarget(RootNode rootNode, FrameDescriptor frameDescriptor); /** + * Creates a new assumption object that can be checked and invalidated. + * + * @return the newly created assumption object + */ + Assumption createAssumption(); + + /** + * Creates a new assumption object with a given name that can be checked and invalidated. + * + * @param name the name for the new assumption + * @return the newly created assumption object + */ + Assumption createAssumption(String name); + + /** * Creates a new materialized frame object that can be used to store values. * * @return the newly created materialized frame object diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/DefaultTypeConversion.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/DefaultTypeConversion.java Tue Apr 23 15:08:11 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2012, 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.api.frame; - -/** - * Default type conversion semantics where a conversion is without changing any data. - */ -public final class DefaultTypeConversion implements TypeConversion { - - private static DefaultTypeConversion instance = new DefaultTypeConversion(); - - public static TypeConversion getInstance() { - return instance; - } - - private DefaultTypeConversion() { - - } - - @Override - public Class getTopType() { - return Object.class; - } - - @Override - public Object convertTo(Class targetType, Object value) { - return value; - } -} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java Tue Apr 23 15:34:06 2013 +0200 @@ -46,7 +46,7 @@ * @param slot the slot of the local variable * @return the current value of the local variable */ - Object getObject(FrameSlot slot); + Object getObject(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type {@link Object}. @@ -54,7 +54,7 @@ * @param slot the slot of the local variable * @param value the new value of the local variable */ - void setObject(FrameSlot slot, Object value); + void setObject(FrameSlot slot, Object value) throws FrameSlotTypeException; /** * Read access to a local variable of type boolean. @@ -62,7 +62,7 @@ * @param slot the slot of the local variable * @return the current value of the local variable */ - boolean getBoolean(FrameSlot slot); + boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type boolean. @@ -70,7 +70,7 @@ * @param slot the slot of the local variable * @param value the new value of the local variable */ - void setBoolean(FrameSlot slot, boolean value); + void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException; /** * Read access to a local variable of type int. @@ -78,7 +78,7 @@ * @param slot the slot of the local variable * @return the current value of the local variable */ - int getInt(FrameSlot slot); + int getInt(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type int. @@ -86,7 +86,7 @@ * @param slot the slot of the local variable * @param value the new value of the local variable */ - void setInt(FrameSlot slot, int value); + void setInt(FrameSlot slot, int value) throws FrameSlotTypeException; /** * Read access to a local variable of type long. @@ -94,7 +94,7 @@ * @param slot the slot of the local variable * @return the current value of the local variable */ - long getLong(FrameSlot slot); + long getLong(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type long. @@ -102,7 +102,7 @@ * @param slot the slot of the local variable * @param value the new value of the local variable */ - void setLong(FrameSlot slot, long value); + void setLong(FrameSlot slot, long value) throws FrameSlotTypeException; /** * Read access to a local variable of type float. @@ -110,7 +110,7 @@ * @param slot the slot of the local variable * @return the current value of the local variable */ - float getFloat(FrameSlot slot); + float getFloat(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type float. @@ -118,7 +118,7 @@ * @param slot the slot of the local variable * @param value the new value of the local variable */ - void setFloat(FrameSlot slot, float value); + void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException; /** * Read access to a local variable of type double. @@ -126,7 +126,7 @@ * @param slot the slot of the local variable * @return the current value of the local variable */ - double getDouble(FrameSlot slot); + double getDouble(FrameSlot slot) throws FrameSlotTypeException; /** * Write access to a local variable of type double. @@ -134,9 +134,15 @@ * @param slot the slot of the local variable * @param value the new value of the local variable */ - void setDouble(FrameSlot slot, double value); + void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException; - void updateToLatestVersion(); + /** + * Read access to a local variable of any type. + * + * @param slot the slot of the local variable + * @return the current value of the local variable or defaultValue if unset + */ + Object getValue(FrameSlot slot); /** * Converts this virtual frame into a packed frame that has no longer direct access to the local diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java Tue Apr 23 15:34:06 2013 +0200 @@ -24,30 +24,33 @@ import java.util.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.impl.*; + /** * Descriptor of the slots of frame objects. Multiple frame instances are associated with one such * descriptor. */ -public final class FrameDescriptor { +public final class FrameDescriptor implements Cloneable { - protected final TypeConversion typeConversion; + private final FrameTypeConversion typeConversion; private final ArrayList slots; - private FrameVersionImpl lastVersion; private final HashMap identifierToSlotMap; + private Assumption version; public FrameDescriptor() { - this(DefaultTypeConversion.getInstance()); + this(DefaultFrameTypeConversion.getInstance()); } - public FrameDescriptor(TypeConversion typeConversion) { + public FrameDescriptor(FrameTypeConversion typeConversion) { this.typeConversion = typeConversion; slots = new ArrayList<>(); identifierToSlotMap = new HashMap<>(); - lastVersion = new FrameVersionImpl(); + version = createVersion(); } public FrameSlot addFrameSlot(Object identifier) { - return addFrameSlot(identifier, typeConversion.getTopType()); + return addFrameSlot(identifier, null); } public FrameSlot addFrameSlot(Object identifier, Class type) { @@ -55,6 +58,7 @@ FrameSlotImpl slot = new FrameSlotImpl(this, identifier, slots.size(), type); slots.add(slot); identifierToSlotMap.put(identifier, slot); + updateVersion(); return slot; } @@ -70,8 +74,12 @@ return addFrameSlot(identifier); } - public FrameVersion getCurrentVersion() { - return lastVersion; + public FrameSlot findOrAddFrameSlot(Object identifier, Class type) { + FrameSlot result = findFrameSlot(identifier); + if (result != null) { + return result; + } + return addFrameSlot(identifier, type); } public int getSize() { @@ -82,121 +90,42 @@ return Collections.unmodifiableList(slots); } - protected void appendVersion(FrameVersionImpl newVersion) { - lastVersion.next = newVersion; - lastVersion = newVersion; - } -} - -class FrameVersionImpl implements FrameVersion { - - protected FrameVersionImpl next; - - @Override - public final FrameVersion getNext() { - return next; - } -} - -class TypeChangeFrameVersionImpl extends FrameVersionImpl implements FrameVersion.TypeChange { - - private final FrameSlotImpl slot; - private final Class oldType; - private final Class newType; - - protected TypeChangeFrameVersionImpl(FrameSlotImpl slot, Class oldType, Class newType) { - this.slot = slot; - this.oldType = oldType; - this.newType = newType; - } - - @Override - public final void applyTransformation(Frame frame) { - Object value = slot.getValue(oldType, frame); - slot.setValue(newType, frame, value); - } -} - -class FrameSlotImpl implements FrameSlot { - - private final FrameDescriptor descriptor; - private final Object identifier; - private final int index; - private Class type; - private ArrayList listeners; - - protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, Class type) { - this.descriptor = descriptor; - this.identifier = identifier; - this.index = index; - this.type = type; - assert type != null; - } - - public Object getIdentifier() { - return identifier; - } - - public int getIndex() { - return index; + /** + * (db) to retrieve the list of all the identifiers associated with this frame descriptor. + * + * @return the list of all the identifiers in this frame descriptor + */ + public Set getIdentifiers() { + return Collections.unmodifiableSet(identifierToSlotMap.keySet()); } - public Class getType() { - return type; - } - - protected Object getValue(Class accessType, Frame frame) { - if (accessType == Integer.class) { - return frame.getInt(this); - } else if (accessType == Long.class) { - return frame.getLong(this); - } else if (accessType == Float.class) { - return frame.getFloat(this); - } else if (accessType == Double.class) { - return frame.getDouble(this); - } else { - return frame.getObject(this); + /** + * (db): this method is used for creating a clone of the {@link FrameDescriptor} object ready + * for parallel execution. + */ + public FrameDescriptor copy() { + FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.typeConversion); + for (int i = 0; i < this.getSlots().size(); i++) { + Object identifier = this.getSlots().get(i).getIdentifier(); + clonedFrameDescriptor.addFrameSlot(identifier); } + return clonedFrameDescriptor; } - protected void setValue(Class accessType, Frame frame, Object value) { - Object newValue = descriptor.typeConversion.convertTo(accessType, value); - if (accessType == Integer.class) { - frame.setInt(this, (Integer) newValue); - } else if (accessType == Long.class) { - frame.setLong(this, (Long) newValue); - } else if (accessType == Float.class) { - frame.setFloat(this, (Float) newValue); - } else if (accessType == Double.class) { - frame.setDouble(this, (Double) newValue); - } else { - frame.setObject(this, newValue); - } + void updateVersion() { + version.invalidate(); + version = createVersion(); + } + + public Assumption getVersion() { + return version; } - public void setType(final Class type) { - final Class oldType = this.type; - this.type = type; - ArrayList oldListeners = this.listeners; - this.listeners = null; - if (oldListeners != null) { - for (FrameSlotTypeListener listener : oldListeners) { - listener.typeChanged(this, oldType); - } - } - descriptor.appendVersion(new TypeChangeFrameVersionImpl(this, oldType, type)); + private static Assumption createVersion() { + return Truffle.getRuntime().createAssumption("frame version"); } - @Override - public String toString() { - return "[" + index + "," + identifier + "]"; - } - - @Override - public void registerOneShotTypeListener(FrameSlotTypeListener listener) { - if (listeners == null) { - listeners = new ArrayList<>(); - } - listeners.add(listener); + public FrameTypeConversion getTypeConversion() { + return typeConversion; } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java Tue Apr 23 15:34:06 2013 +0200 @@ -25,7 +25,7 @@ /** * A slot in a frame that can store a value of a given type. */ -public interface FrameSlot { +public interface FrameSlot extends Cloneable { Object getIdentifier(); @@ -35,5 +35,5 @@ void setType(Class type); - void registerOneShotTypeListener(FrameSlotTypeListener listener); + FrameDescriptor getFrameDescriptor(); } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012, 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.api.frame; + +public final class FrameSlotImpl implements FrameSlot { + + private final FrameDescriptor descriptor; + private final Object identifier; + private final int index; + private Class type; + + protected FrameSlotImpl(FrameDescriptor descriptor, Object identifier, int index, Class type) { + this.descriptor = descriptor; + this.identifier = identifier; + this.index = index; + this.type = type; + } + + public Object getIdentifier() { + return identifier; + } + + public int getIndex() { + return index; + } + + public Class getType() { + return type; + } + + public void setType(final Class type) { + assert this.type != type; + this.type = type; + this.descriptor.updateVersion(); + } + + @Override + public String toString() { + return "[" + index + "," + identifier + "," + type + "]"; + } + + @Override + public FrameDescriptor getFrameDescriptor() { + return this.descriptor; + } +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotTypeException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotTypeException.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, 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.api.frame; + +import com.oracle.truffle.api.nodes.*; + +/** + * Exception thrown if the frame slot type does not match the access type. + */ +public final class FrameSlotTypeException extends SlowPathException { + + private static final long serialVersionUID = 6972120475215757452L; + + public FrameSlotTypeException() { + } +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotTypeListener.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotTypeListener.java Tue Apr 23 15:08:11 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2012, 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.api.frame; - -/** - * Listener for the event of a type change of a frame slot. - */ -public interface FrameSlotTypeListener { - - void typeChanged(FrameSlot slot, Class oldType); -} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameTypeConversion.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameTypeConversion.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2013, 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.api.frame; + +/** + * Interface for defining type conversions for frame slot values. + */ +public interface FrameTypeConversion { + + Object getDefaultValue(); + + void updateFrameSlot(Frame frame, FrameSlot slot, Object value); +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013, 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.api.frame; + +public final class FrameUtil { + + /** + * Write access to a local variable of type {@link Object}. + * + * Sets the frame slot type to {@link Object} if it isn't already. + * + * @param slot the slot of the local variable + * @param value the new value of the local variable + */ + public static void setObjectSafe(Frame frame, FrameSlot slot, Object value) { + if (slot.getType() != Object.class) { + slot.setType(Object.class); + } + try { + frame.setObject(slot, value); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(); + } + } + + /** + * Write access to a local variable of type {@code boolean}. + * + * Sets the frame slot type to {@code boolean} if it isn't already. + * + * @param slot the slot of the local variable + * @param value the new value of the local variable + */ + public static void setBooleanSafe(Frame frame, FrameSlot slot, boolean value) { + if (slot.getType() != boolean.class) { + slot.setType(boolean.class); + } + try { + frame.setBoolean(slot, value); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(); + } + } + + /** + * Write access to a local variable of type {@code int}. + * + * Sets the frame slot type to {@code int} if it isn't already. + * + * @param slot the slot of the local variable + * @param value the new value of the local variable + */ + public static void setIntSafe(Frame frame, FrameSlot slot, int value) { + if (slot.getType() != int.class) { + slot.setType(int.class); + } + try { + frame.setInt(slot, value); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(); + } + } + + /** + * Write access to a local variable of type {@code long}. + * + * Sets the frame slot type to {@code long} if it isn't already. + * + * @param slot the slot of the local variable + * @param value the new value of the local variable + */ + public static void setLongSafe(Frame frame, FrameSlot slot, long value) { + if (slot.getType() != long.class) { + slot.setType(long.class); + } + try { + frame.setLong(slot, value); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(); + } + } + + /** + * Write access to a local variable of type {@code float}. + * + * Sets the frame slot type to {@code float} if it isn't already. + * + * @param slot the slot of the local variable + * @param value the new value of the local variable + */ + public static void setFloatSafe(Frame frame, FrameSlot slot, float value) { + if (slot.getType() != float.class) { + slot.setType(float.class); + } + try { + frame.setFloat(slot, value); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(); + } + } + + /** + * Write access to a local variable of type {@code double}. + * + * Sets the frame slot type to {@code double} if it isn't already. + * + * @param slot the slot of the local variable + * @param value the new value of the local variable + */ + public static void setDoubleSafe(Frame frame, FrameSlot slot, double value) { + if (slot.getType() != double.class) { + slot.setType(double.class); + } + try { + frame.setDouble(slot, value); + } catch (FrameSlotTypeException e) { + throw new IllegalStateException(); + } + } +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameVersion.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameVersion.java Tue Apr 23 15:08:11 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2012, 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.api.frame; - -/** - * Represents a specific version of a frame. - */ -public interface FrameVersion { - - FrameVersion getNext(); - - public interface Resize { - - int getNewSize(); - } - - public interface TypeChange { - - void applyTransformation(Frame frame); - } -} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/MaterializedFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/MaterializedFrame.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/MaterializedFrame.java Tue Apr 23 15:34:06 2013 +0200 @@ -30,4 +30,5 @@ * also does not provide access to the caller frame. */ public interface MaterializedFrame extends Frame { + } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java Tue Apr 23 15:34:06 2013 +0200 @@ -104,6 +104,11 @@ } @Override + public Object getValue(FrameSlot slot) { + throw new UnsupportedOperationException("native frame"); + } + + @Override public PackedFrame pack() { return this; } @@ -124,10 +129,6 @@ } @Override - public void updateToLatestVersion() { - } - - @Override public FrameDescriptor getFrameDescriptor() { throw new UnsupportedOperationException("native frame"); } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/TypeConversion.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/TypeConversion.java Tue Apr 23 15:08:11 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2012, 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.api.frame; - -/** - * Interface for defining type conversions for frame slot values. - */ -public interface TypeConversion { - - Class getTopType(); - - Object convertTo(Class targetType, Object value); -} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractAssumption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractAssumption.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, 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.api.impl; + +import com.oracle.truffle.api.*; + +public abstract class AbstractAssumption implements Assumption { + + protected final String name; + protected boolean isValid; + + protected AbstractAssumption(String name) { + this.name = name; + this.isValid = true; + } + + @Override + public String getName() { + return name; + } + + @Override + public String toString() { + return "Assumption: " + name; + } +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultAssumption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultAssumption.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2012, 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.api.impl; + +import com.oracle.truffle.api.nodes.*; + +public final class DefaultAssumption extends AbstractAssumption { + + public DefaultAssumption(String name) { + super(name); + } + + @Override + public void check() throws InvalidAssumptionException { + if (!isValid) { + throw new InvalidAssumptionException(); + } + } + + @Override + public void invalidate() { + isValid = false; + } +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Tue Apr 23 15:34:06 2013 +0200 @@ -31,14 +31,15 @@ protected final RootNode rootNode; protected final FrameDescriptor frameDescriptor; - protected DefaultCallTarget(RootNode function, FrameDescriptor frameDescriptor) { + public DefaultCallTarget(RootNode function, FrameDescriptor frameDescriptor) { this.rootNode = function; this.frameDescriptor = frameDescriptor; + this.rootNode.setCallTarget(this); } @Override public String toString() { - return "DefaultCallTarget " + rootNode; + return "CallTarget " + rootNode; } @Override @@ -46,4 +47,8 @@ VirtualFrame frame = new DefaultVirtualFrame(frameDescriptor, caller, args); return rootNode.execute(frame); } + + public RootNode getRootNode() { + return rootNode; + } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultFrameTypeConversion.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultFrameTypeConversion.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, 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.api.impl; + +import com.oracle.truffle.api.frame.*; + +/** + * Interface for defining type conversions for frame slot values. + */ +public class DefaultFrameTypeConversion implements FrameTypeConversion { + + private static final DefaultFrameTypeConversion INSTANCE = new DefaultFrameTypeConversion(); + + @Override + public Object getDefaultValue() { + return null; + } + + @Override + public void updateFrameSlot(Frame frame, FrameSlot slot, Object value) { + FrameUtil.setObjectSafe(frame, slot, value); + } + + public static DefaultFrameTypeConversion getInstance() { + return INSTANCE; + } +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java Tue Apr 23 15:34:06 2013 +0200 @@ -39,68 +39,68 @@ } @Override - public Object getObject(FrameSlot slot) { + public Object getObject(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getObject(slot); } @Override - public void setObject(FrameSlot slot, Object value) { + public void setObject(FrameSlot slot, Object value) throws FrameSlotTypeException { wrapped.setObject(slot, value); } @Override - public boolean getBoolean(FrameSlot slot) { + public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getBoolean(slot); } @Override - public void setBoolean(FrameSlot slot, boolean value) { + public void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException { wrapped.setBoolean(slot, value); } @Override - public int getInt(FrameSlot slot) { + public int getInt(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getInt(slot); } @Override - public void setInt(FrameSlot slot, int value) { + public void setInt(FrameSlot slot, int value) throws FrameSlotTypeException { wrapped.setInt(slot, value); } @Override - public long getLong(FrameSlot slot) { + public long getLong(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getLong(slot); } @Override - public void setLong(FrameSlot slot, long value) { + public void setLong(FrameSlot slot, long value) throws FrameSlotTypeException { wrapped.setLong(slot, value); } @Override - public float getFloat(FrameSlot slot) { + public float getFloat(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getFloat(slot); } @Override - public void setFloat(FrameSlot slot, float value) { + public void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException { wrapped.setFloat(slot, value); } @Override - public double getDouble(FrameSlot slot) { + public double getDouble(FrameSlot slot) throws FrameSlotTypeException { return wrapped.getDouble(slot); } @Override - public void setDouble(FrameSlot slot, double value) { + public void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException { wrapped.setDouble(slot, value); } @Override - public void updateToLatestVersion() { - wrapped.updateToLatestVersion(); + public Object getValue(FrameSlot slot) { + return wrapped.getValue(slot); } @Override diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Tue Apr 23 15:34:06 2013 +0200 @@ -38,13 +38,13 @@ } @Override - public CallTarget createCallTarget(RootNode rootNode, FrameDescriptor frameDescriptor) { - return new DefaultCallTarget(rootNode, frameDescriptor); + public CallTarget createCallTarget(RootNode rootNode) { + return createCallTarget(rootNode, new FrameDescriptor()); } @Override - public CallTarget createCallTarget(RootNode rootNode) { - return createCallTarget(rootNode, new FrameDescriptor()); + public CallTarget createCallTarget(RootNode rootNode, FrameDescriptor frameDescriptor) { + return new DefaultCallTarget(rootNode, frameDescriptor); } @Override @@ -56,4 +56,14 @@ public MaterializedFrame createMaterializedFrame(Arguments arguments, FrameDescriptor frameDescriptor) { return new DefaultMaterializedFrame(new DefaultVirtualFrame(frameDescriptor, null, arguments)); } + + @Override + public Assumption createAssumption() { + return createAssumption(null); + } + + @Override + public Assumption createAssumption(String name) { + return new DefaultAssumption(name); + } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java Tue Apr 23 15:34:06 2013 +0200 @@ -29,29 +29,18 @@ public final class DefaultVirtualFrame implements VirtualFrame { - private static final Object UNDEFINED_OBJECT = null; - private static final Boolean UNDEFINED_BOOLEAN = false; - private static final Integer UNDEFINED_INTEGER = 0; - private static final Float UNDEFINED_FLOAT = 0.0f; - private static final Long UNDEFINED_LONG = 0L; - private static final Double UNDEFINED_DOUBLE = 0.0d; - private final FrameDescriptor descriptor; private final PackedFrame caller; private final Arguments arguments; - private FrameVersion currentVersion; - protected Object[] locals; - protected Class[] tags; + private Object[] locals; + private Class[] tags; public DefaultVirtualFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments arguments) { this.descriptor = descriptor; this.caller = caller; this.arguments = arguments; - this.currentVersion = descriptor.getCurrentVersion(); this.locals = new Object[descriptor.getSize()]; - // The tags are only needed for assertion checking, so initialize the field only when - // assertions are enabled - assert (this.tags = new Class[descriptor.getSize()]) != null; + this.tags = new Class[descriptor.getSize()]; } @Override @@ -75,126 +64,139 @@ } @Override - public Object getObject(FrameSlot slot) { - return get(slot, Object.class, UNDEFINED_OBJECT); - } - - @Override - public void setObject(FrameSlot slot, Object value) { - set(slot, Object.class, value); + public Object getObject(FrameSlot slot) throws FrameSlotTypeException { + verifyGet(slot, Object.class); + return locals[slot.getIndex()]; } @Override - public boolean getBoolean(FrameSlot slot) { - return (Boolean) get(slot, Boolean.class, UNDEFINED_BOOLEAN); - } - - @Override - public void setBoolean(FrameSlot slot, boolean value) { - set(slot, Boolean.class, value); - } - - @Override - public int getInt(FrameSlot slot) { - return (Integer) get(slot, Integer.class, UNDEFINED_INTEGER); + public void setObject(FrameSlot slot, Object value) throws FrameSlotTypeException { + verifySet(slot, Object.class); + locals[slot.getIndex()] = value; } @Override - public void setInt(FrameSlot slot, int value) { - set(slot, Integer.class, value); - } - - @Override - public long getLong(FrameSlot slot) { - return (Long) get(slot, Long.class, UNDEFINED_LONG); + public boolean getBoolean(FrameSlot slot) throws FrameSlotTypeException { + verifyGet(slot, boolean.class); + return (boolean) locals[slot.getIndex()]; } @Override - public void setLong(FrameSlot slot, long value) { - set(slot, Long.class, value); + public void setBoolean(FrameSlot slot, boolean value) throws FrameSlotTypeException { + verifySet(slot, boolean.class); + locals[slot.getIndex()] = value; } @Override - public float getFloat(FrameSlot slot) { - return (Float) get(slot, Float.class, UNDEFINED_FLOAT); - } - - @Override - public void setFloat(FrameSlot slot, float value) { - set(slot, Float.class, value); - } - - @Override - public double getDouble(FrameSlot slot) { - return (Double) get(slot, Double.class, UNDEFINED_DOUBLE); + public int getInt(FrameSlot slot) throws FrameSlotTypeException { + verifyGet(slot, int.class); + return (int) locals[slot.getIndex()]; } @Override - public void setDouble(FrameSlot slot, double value) { - set(slot, Double.class, value); - } - - private Object get(FrameSlot slot, Class accessType, Object defaultValue) { - Object value = locals[slot.getIndex()]; - assert verifyGet(slot, accessType, value); - if (value == null) { - return defaultValue; - } else { - return value; - } + public void setInt(FrameSlot slot, int value) throws FrameSlotTypeException { + verifySet(slot, int.class); + locals[slot.getIndex()] = value; } - private boolean verifyGet(FrameSlot slot, Class accessType, Object value) { - assert descriptor.getSlots().get(slot.getIndex()) == slot; - Class tag = tags[slot.getIndex()]; - if (value == null) { - assert tag == null || tag == Object.class; - } else { - assert tag == accessType : "Local variable " + slot + " was written with set" + tag.getSimpleName() + ", but is read with get" + accessType.getSimpleName(); - } - return true; + @Override + public long getLong(FrameSlot slot) throws FrameSlotTypeException { + verifyGet(slot, long.class); + return (long) locals[slot.getIndex()]; } - private void set(FrameSlot slot, Class accessType, Object value) { - assert verifySet(slot, accessType, value); + @Override + public void setLong(FrameSlot slot, long value) throws FrameSlotTypeException { + verifySet(slot, long.class); locals[slot.getIndex()] = value; } - private boolean verifySet(FrameSlot slot, Class accessType, Object value) { - assert descriptor.getSlots().get(slot.getIndex()) == slot; - tags[slot.getIndex()] = accessType; - assert accessType.isAssignableFrom(slot.getType()) : "Local variable " + slot + ": " + accessType + " is not assignable from " + slot.getType(); - if (value == null) { - assert accessType == Object.class; - } else { - assert slot.getType().isAssignableFrom(value.getClass()) : "Local variable " + slot + ": " + slot.getType() + " is not assignable from " + value.getClass(); - } - return true; + @Override + public float getFloat(FrameSlot slot) throws FrameSlotTypeException { + verifyGet(slot, float.class); + return (float) locals[slot.getIndex()]; } @Override - public void updateToLatestVersion() { - if (currentVersion.getNext() != null) { - doUpdateToLatestVersion(); - } + public void setFloat(FrameSlot slot, float value) throws FrameSlotTypeException { + verifySet(slot, float.class); + locals[slot.getIndex()] = value; } - private void doUpdateToLatestVersion() { - FrameVersion version = currentVersion; - while (version.getNext() != null) { - version = version.getNext(); - if (version instanceof FrameVersion.TypeChange) { - ((FrameVersion.TypeChange) version).applyTransformation(this); - } else if (version instanceof FrameVersion.Resize) { - int newSize = ((FrameVersion.Resize) version).getNewSize(); - locals = Arrays.copyOf(locals, newSize); - } - } - currentVersion = version; + @Override + public double getDouble(FrameSlot slot) throws FrameSlotTypeException { + verifyGet(slot, double.class); + return (double) locals[slot.getIndex()]; + } + + @Override + public void setDouble(FrameSlot slot, double value) throws FrameSlotTypeException { + verifySet(slot, double.class); + locals[slot.getIndex()] = value; } @Override public FrameDescriptor getFrameDescriptor() { return this.descriptor; } + + @Override + public Object getValue(FrameSlot slot) { + int index = slot.getIndex(); + if (index >= tags.length) { + assert index >= 0 && index < descriptor.getSize(); + return descriptor.getTypeConversion().getDefaultValue(); + } + Class tag = tags[index]; + if (tag == null) { + return descriptor.getTypeConversion().getDefaultValue(); + } else { + return locals[index]; + } + } + + private void verifySet(FrameSlot slot, Class accessType) throws FrameSlotTypeException { + if (slot.getType() != accessType) { + throw new FrameSlotTypeException(); + } + int slotIndex = slot.getIndex(); + if (slotIndex >= tags.length) { + resize(); + } + tags[slotIndex] = accessType; + } + + private void verifyGet(FrameSlot slot, Class accessType) throws FrameSlotTypeException { + Class slotType = slot.getType(); + int slotIndex = slot.getIndex(); + if (slotType != accessType) { + if (slotType == null) { + slot.setType(Object.class); + this.setObject(slot, descriptor.getTypeConversion().getDefaultValue()); + if (accessType != Object.class) { + throw new FrameSlotTypeException(); + } + } else { + throw new FrameSlotTypeException(); + } + } + if (slotIndex >= tags.length) { + resize(); + } + Class tag = tags[slotIndex]; + if (tag != slotType) { + descriptor.getTypeConversion().updateFrameSlot(this, slot, getValue(slot)); + if (tags[slotIndex] != slotType) { + throw new FrameSlotTypeException(); + } + } + } + + private void resize() { + int newSize = descriptor.getSize(); + if (newSize > tags.length) { + locals = Arrays.copyOf(locals, newSize); + tags = Arrays.copyOf(tags, newSize); + } + } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/intrinsics/TruffleIntrinsics.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/intrinsics/TruffleIntrinsics.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/intrinsics/TruffleIntrinsics.java Tue Apr 23 15:34:06 2013 +0200 @@ -44,4 +44,11 @@ throw new RuntimeException("Timeout"); } } + + public static void mustNotReachHere() { + } + + public static void interpreterOnly(Runnable runnable) { + runnable.run(); + } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/InvalidAssumptionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/InvalidAssumptionException.java Tue Apr 23 15:34:06 2013 +0200 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2012, 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.api.nodes; + +/** + * An exception that should be thrown if an assumption is checked and the check fails. The Truffle + * optimizer has special knowledge of this exception class and will never compile a catch block that + * catches this exception type. + */ +public final class InvalidAssumptionException extends SlowPathException { + + private static final long serialVersionUID = -6801338218909717979L; + +} diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Apr 23 15:34:06 2013 +0200 @@ -99,6 +99,21 @@ this.parentOffset = parentOffsetTemp; } + + /** + * (db) getters added to support AST cloning for parallel execution. + */ + public long getParentOffset() { + return parentOffset; + } + + public long[] getNodeFieldOffsets() { + return nodeFieldOffsets; + } + + public long[] getNodeArrayFieldOffsets() { + return nodeArrayFieldOffsets; + } } public static class NodeIterator implements Iterator { @@ -180,7 +195,7 @@ return array; } - private static final Unsafe unsafe = getUnsafe(); + protected static final Unsafe unsafe = getUnsafe(); private static Unsafe getUnsafe() { try { diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Tue Apr 23 15:34:06 2013 +0200 @@ -39,4 +39,14 @@ * @return the value of the execution */ public abstract Object execute(VirtualFrame frame); + + private CallTarget callTarget; + + public CallTarget getCallTarget() { + return callTarget; + } + + public void setCallTarget(CallTarget callTarget) { + this.callTarget = callTarget; + } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/SlowPathException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/SlowPathException.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/SlowPathException.java Tue Apr 23 15:34:06 2013 +0200 @@ -33,7 +33,36 @@ /** * Creates an exception thrown to enter a slow path. */ + public SlowPathException() { + } + + /** + * Creates an exception thrown to enter a slow path. + */ public SlowPathException(String message, Throwable cause) { super(message, cause); } + + /** + * Creates an exception thrown to enter a slow path. + */ + public SlowPathException(String message) { + super(message); + } + + /** + * Creates an exception thrown to enter a slow path. + */ + public SlowPathException(Throwable cause) { + super(cause); + } + + /** + * For performance reasons, this exception does not record any stack trace information. + */ + @SuppressWarnings("sync-override") + @Override + public Throwable fillInStackTrace() { + return null; + } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/UnexpectedResultException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/UnexpectedResultException.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/UnexpectedResultException.java Tue Apr 23 15:34:06 2013 +0200 @@ -39,7 +39,6 @@ * @param result the alternative result */ public UnexpectedResultException(Object result) { - super(null, null); assert !(result instanceof Throwable); this.result = result; } @@ -50,13 +49,4 @@ public Object getResult() { return result; } - - /** - * For performance reasons, this exception does not record any stack trace information. - */ - @SuppressWarnings("sync-override") - @Override - public Throwable fillInStackTrace() { - return null; - } } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java Tue Apr 23 15:34:06 2013 +0200 @@ -45,7 +45,6 @@ private final TypeMirror frame; private final DeclaredType childAnnotation; private final DeclaredType childrenAnnotation; - private final TypeMirror typeConversion; private final TypeMirror truffleIntrinsics; private final List errors = new ArrayList<>(); @@ -57,7 +56,6 @@ frame = getRequired(context, VirtualFrame.class); childAnnotation = getRequired(context, Child.class); childrenAnnotation = getRequired(context, Children.class); - typeConversion = getRequired(context, TypeConversion.class); truffleIntrinsics = getRequired(context, TruffleIntrinsics.class); } @@ -85,10 +83,6 @@ return truffleIntrinsics; } - public TypeMirror getTypeConversion() { - return typeConversion; - } - public TypeMirror getNode() { return node; } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Tue Apr 23 15:34:06 2013 +0200 @@ -676,15 +676,17 @@ } private CodeVariableElement createChildField(NodeChildData child) { + CodeVariableElement var = new CodeVariableElement(child.getNodeType(), child.getName()); + var.getModifiers().add(Modifier.PROTECTED); + DeclaredType annotationType; if (child.getCardinality() == Cardinality.MANY) { + var.getModifiers().add(Modifier.FINAL); annotationType = getContext().getTruffleTypes().getChildrenAnnotation(); } else { annotationType = getContext().getTruffleTypes().getChildAnnotation(); } - CodeVariableElement var = new CodeVariableElement(child.getNodeType(), child.getName()); - var.getModifiers().add(Modifier.PROTECTED); var.getAnnotationMirrors().add(new CodeAnnotationMirror(annotationType)); return var; } @@ -1498,6 +1500,7 @@ builder.startCall(factoryClassName(node), "createSpecialized").string("this").string("null").end(); } builder.end().end(); + emitSpecializationListeners(builder, node); return builder.getRoot(); } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java Tue Apr 23 15:34:06 2013 +0200 @@ -79,15 +79,10 @@ String name = typeName(typeSystem); CodeTypeElement clazz = createClass(typeSystem, modifiers(PUBLIC), name, typeSystem.getTemplateType().asType(), false); - clazz.getImplements().add(getContext().getTruffleTypes().getTypeConversion()); - clazz.add(createConstructorUsingFields(modifiers(PROTECTED), clazz)); CodeVariableElement singleton = createSingleton(clazz); clazz.add(singleton); - clazz.add(createGetTopType(typeSystem)); - clazz.add(createConvertTo(typeSystem, singleton)); - for (TypeData type : typeSystem.getTypes()) { if (!type.isGeneric()) { CodeExecutableElement isType = createIsTypeMethod(type); @@ -125,58 +120,6 @@ return new ArrayList<>(sourceTypes); } - private CodeExecutableElement createConvertTo(TypeSystemData typeSystem, CodeVariableElement singleton) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(Object.class), "convertTo"); - method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "targetType")); - method.addParameter(new CodeVariableElement(getContext().getType(Object.class), "value")); - - CodeTreeBuilder builder = method.createBuilder(); - - boolean first = true; - for (TypeData type : typeSystem.getTypes()) { - if (first) { - builder.startIf(); - first = false; - } else { - builder.startElseIf(); - } - builder.string("targetType").string(" == ").typeLiteral(type.getBoxedType()); - builder.end(); // if - builder.startBlock(); - - builder.startReturn(); - - if (typeEquals(type.getBoxedType(), getContext().getType(Object.class))) { - builder.string("value"); - } else { - builder.string(singleton.getName()).string(".").startCall(asTypeMethodName(type)).string("value").end(); - } - - builder.end(); // return - - builder.end(); // block - } - - builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).end().end(); - - return method; - } - - private CodeExecutableElement createGetTopType(TypeSystemData typeSystem) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(Class.class), "getTopType"); - - CodeTreeBuilder builder = method.createBuilder(); - builder.startReturn(); - if (!typeSystem.getTypes().isEmpty()) { - builder.typeLiteral(typeSystem.getTypes().get(0).getBoxedType()); - } else { - builder.null_(); - } - builder.end(); // return - - return method; - } - private static String typeName(TypeSystemData typeSystem) { String name = getSimpleName(typeSystem.getTemplateType()); return name + "Gen"; diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -62,4 +62,5 @@ System.setErr(origErr); Assert.assertEquals(repeat(concat(expectedOutput), REPEATS), new String(out.toByteArray())); } + } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AddTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AddTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AddTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -28,25 +28,25 @@ public class AddTest extends AbstractTest { private static String[] INPUT = new String[] { -"function main { ", -" print 3 + 4; ", -" print 3 + \"4\"; ", -" print \"3\" + 4; ", -" print \"3\" + \"4\"; ", -" print 3 + 4000000000000; ", -" print 3000000000000 + 4; ", -" print 3000000000000 + 4000000000000; ", -"} ", + "function main { ", + " print 3 + 4; ", + " print 3 + \"4\"; ", + " print \"3\" + 4; ", + " print \"3\" + \"4\"; ", + " print 3 + 4000000000000; ", + " print 3000000000000 + 4; ", + " print 3000000000000 + 4000000000000; ", + "} ", }; private static String[] OUTPUT = new String[] { -"7", -"34", -"34", -"34", -"4000000000003", -"3000000000004", -"7000000000000", + "7", + "34", + "34", + "34", + "4000000000003", + "3000000000004", + "7000000000000", }; @Test diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/ComparisonTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/ComparisonTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/ComparisonTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -28,25 +28,25 @@ public class ComparisonTest extends AbstractTest { private static String[] INPUT = new String[] { -"function main { ", -" print 4 < 20; ", -" print 4 < \"20\"; ", -" print \"4\" < 20; ", -" print \"4\" < \"20\"; ", -" print 4 < 20000000000000; ", -" print 4000000000000 < 20; ", -" print 4000000000000 < 20000000000000; ", -"} ", + "function main { ", + " print 4 < 20; ", + " print 4 < \"20\"; ", + " print \"4\" < 20; ", + " print \"4\" < \"20\"; ", + " print 4 < 20000000000000; ", + " print 4000000000000 < 20; ", + " print 4000000000000 < 20000000000000; ", + "} ", }; private static String[] OUTPUT = new String[] { -"true", -"false", -"false", -"false", -"true", -"false", -"true", + "true", + "false", + "false", + "false", + "true", + "false", + "true", }; @Test diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/DivTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/DivTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/DivTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -28,19 +28,19 @@ public class DivTest extends AbstractTest { private static String[] INPUT = new String[] { -"function main { ", -" print 4 / 2; ", -" print 4 / 4000000000000; ", -" print 3000000000000 / 3; ", -" print 3000000000000 / 3000000000000; ", -"} ", + "function main { ", + " print 4 / 2; ", + " print 4 / 4000000000000; ", + " print 3000000000000 / 3; ", + " print 3000000000000 / 3000000000000; ", + "} ", }; private static String[] OUTPUT = new String[] { -"2", -"0", -"1000000000000", -"1", + "2", + "0", + "1000000000000", + "1", }; @Test diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopPrintTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopPrintTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopPrintTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -28,17 +28,17 @@ public class LoopPrintTest extends AbstractTest { private static String[] INPUT = new String[] { -"function main { ", -" i = 0; ", -" while (i < 1000) { ", -" i = i + 1; ", -" } ", -" print i; ", -"} ", + "function main { ", + " i = 0; ", + " while (i < 1000) { ", + " i = i + 1; ", + " } ", + " print i; ", + "} ", }; private static String[] OUTPUT = new String[] { -"1000", + "1000", }; @Test diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -28,17 +28,17 @@ public class LoopTest extends AbstractTest { private static String[] INPUT = new String[] { -"function main { ", -" i = 0; ", -" while (i < 1000) { ", -" i = i + 1; ", -" } ", -" return i; ", -"} ", + "function main { ", + " i = 0; ", + " while (i < 1000) { ", + " i = i + 1; ", + " } ", + " return i; ", + "} ", }; private static String[] OUTPUT = new String[] { -"1000", + "1000", }; @Test diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/MulTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/MulTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/MulTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -28,19 +28,19 @@ public class MulTest extends AbstractTest { private static String[] INPUT = new String[] { -"function main { ", -" print 3 * 4; ", -" print 3 * 4000000000000; ", -" print 3000000000000 * 4; ", -" print 3000000000000 * 4000000000000; ", -"} ", + "function main { ", + " print 3 * 4; ", + " print 3 * 4000000000000; ", + " print 3000000000000 * 4; ", + " print 3000000000000 * 4000000000000; ", + "} ", }; private static String[] OUTPUT = new String[] { -"12", -"12000000000000", -"12000000000000", -"12000000000000000000000000", + "12", + "12000000000000", + "12000000000000", + "12000000000000000000000000", }; @Test diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SubTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SubTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SubTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -28,19 +28,19 @@ public class SubTest extends AbstractTest { private static String[] INPUT = new String[] { -"function main { ", -" print 3 - 4; ", -" print 3 - 4000000000000; ", -" print 3000000000000 - 4; ", -" print 3000000000000 - 4000000000000; ", -"} ", + "function main { ", + " print 3 - 4; ", + " print 3 - 4000000000000; ", + " print 3000000000000 - 4; ", + " print 3000000000000 - 4000000000000; ", + "} ", }; private static String[] OUTPUT = new String[] { -"-1", -"-3999999999997", -"2999999999996", -"-1000000000000", + "-1", + "-3999999999997", + "2999999999996", + "-1000000000000", }; @Test diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SumTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SumTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SumTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -28,19 +28,19 @@ public class SumTest extends AbstractTest { private static String[] INPUT = new String[] { -"function main { ", -" i = 0; ", -" sum = 0; ", -" while (i < 100000) { ", -" sum = sum + 1000000; ", -" i = i + 1; ", -" } ", -" return sum; ", -"} ", + "function main { ", + " i = 0; ", + " sum = 0; ", + " while (i < 100000) { ", + " sum = sum + 1000000; ", + " i = i + 1; ", + " } ", + " return sum; ", + "} ", }; private static String[] OUTPUT = new String[] { -"100000000000", + "100000000000", }; @Test diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/TernaryTest.java --- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/TernaryTest.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/TernaryTest.java Tue Apr 23 15:34:06 2013 +0200 @@ -28,13 +28,13 @@ public class TernaryTest extends AbstractTest { private static String[] INPUT = new String[] { -"function main { " + -" print #(1 < 2) ? 1 : 2;" + -" print #(2 < 1) ? 100000000000000 : 1; ", -" print #(1 < 2) ? 100000000000000 : 1; ", -" print #(2 < 1) ? \"wrong\" : \"true\";", -" print #(2 < 1) ? \"wrong\" : 1;", -"} ", + "function main { " + + " print #(1 < 2) ? 1 : 2;" + + " print #(2 < 1) ? 100000000000000 : 1; ", + " print #(1 < 2) ? 100000000000000 : 1; ", + " print #(2 < 1) ? \"wrong\" : \"true\";", + " print #(2 < 1) ? \"wrong\" : 1;", + "} ", }; private static String[] OUTPUT = new String[] { diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java Tue Apr 23 15:34:06 2013 +0200 @@ -51,7 +51,7 @@ } public void startFunction() { - frameDescriptor = new FrameDescriptor(SLTypesGen.SLTYPES); + frameDescriptor = new FrameDescriptor(); } public void createFunction(StatementNode body, String name) { @@ -59,7 +59,7 @@ } public TypedNode createLocal(String name) { - return ReadLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name)); + return ReadLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, Integer.class)); } public TypedNode createStringLiteral(String value) { @@ -67,7 +67,7 @@ } public StatementNode createAssignment(String name, TypedNode right) { - return WriteLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name), right); + return WriteLocalNodeFactory.create(frameDescriptor.findOrAddFrameSlot(name, Integer.class), right); } public StatementNode createPrint(List expressions) { @@ -123,7 +123,7 @@ } public StatementNode createReturn(TypedNode value) { - FrameSlot slot = frameDescriptor.findOrAddFrameSlot(""); + FrameSlot slot = frameDescriptor.findOrAddFrameSlot("", Integer.class); if (returnValue == null) { returnValue = ReadLocalNodeFactory.create(slot); } diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FrameSlotNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FrameSlotNode.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FrameSlotNode.java Tue Apr 23 15:34:06 2013 +0200 @@ -24,20 +24,12 @@ import com.oracle.truffle.api.frame.*; -public abstract class FrameSlotNode extends TypedNode implements FrameSlotTypeListener { +public abstract class FrameSlotNode extends TypedNode { protected final FrameSlot slot; public FrameSlotNode(FrameSlot slot) { this.slot = slot; - slot.registerOneShotTypeListener(this); - } - - @Override - public void typeChanged(FrameSlot changedSlot, Class oldType) { - if (getParent() != null) { - replace(specialize(changedSlot.getType())); - } } protected abstract FrameSlotNode specialize(Class clazz); diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadLocalNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadLocalNode.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadLocalNode.java Tue Apr 23 15:34:06 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.truffle.sl.nodes; -import java.math.*; - import com.oracle.truffle.api.codegen.*; import com.oracle.truffle.api.frame.*; @@ -37,29 +35,23 @@ this(specialized.slot); } - @Specialization - public int doInteger(VirtualFrame frame) { + @Specialization(rewriteOn = {FrameSlotTypeException.class}) + public int doInteger(VirtualFrame frame) throws FrameSlotTypeException { return frame.getInt(slot); } - @Specialization - public BigInteger doBigInteger(VirtualFrame frame) { - return (BigInteger) frame.getObject(slot); - } - - @Specialization - public boolean doBoolean(VirtualFrame frame) { + @Specialization(rewriteOn = {FrameSlotTypeException.class}) + public boolean doBoolean(VirtualFrame frame) throws FrameSlotTypeException { return frame.getBoolean(slot); } - @Specialization - public String doString(VirtualFrame frame) { - return (String) frame.getObject(slot); - } - - @Generic - public Object doGeneric(VirtualFrame frame) { - return frame.getObject(slot); + @Generic(useSpecializations = false) + public Object doObject(VirtualFrame frame) { + try { + return frame.getObject(slot); + } catch (FrameSlotTypeException e) { + throw new RuntimeException("uninitialized variable " + slot.getIdentifier()); + } } @Override diff -r 542712a4732a -r 07f8d136a05e graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java --- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java Tue Apr 23 15:08:11 2013 +0200 +++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java Tue Apr 23 15:34:06 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.truffle.sl.nodes; -import java.math.*; - import com.oracle.truffle.api.codegen.*; import com.oracle.truffle.api.frame.*; @@ -38,42 +36,44 @@ this(node.slot); } - @Specialization - public int write(VirtualFrame frame, int right) { - frame.setInt(slot, right); + @Specialization(rewriteOn = FrameSlotTypeException.class) + public int write(VirtualFrame frame, int right) throws FrameSlotTypeException { + try { + frame.setInt(slot, right); + } catch (FrameSlotTypeException e) { + if (slot.getType() == null) { + FrameUtil.setIntSafe(frame, slot, right); + } else { + throw e; + } + } return right; } - @Specialization - public BigInteger write(VirtualFrame frame, BigInteger right) { - frame.setObject(slot, right); - return right; - } - - @Specialization - public boolean write(VirtualFrame frame, boolean right) { - frame.setBoolean(slot, right); - return right; - } - - @Specialization - public String write(VirtualFrame frame, String right) { - frame.setObject(slot, right); + @Specialization(rewriteOn = FrameSlotTypeException.class) + public boolean write(VirtualFrame frame, boolean right) throws FrameSlotTypeException { + try { + frame.setBoolean(slot, right); + } catch (FrameSlotTypeException e) { + if (slot.getType() == null) { + FrameUtil.setBooleanSafe(frame, slot, right); + } else { + throw e; + } + } return right; } @Generic(useSpecializations = false) public Object writeGeneric(VirtualFrame frame, Object right) { - frame.setObject(slot, right); + try { + frame.setObject(slot, right); + } catch (FrameSlotTypeException e) { + FrameUtil.setObjectSafe(frame, slot, right); + } return right; } - @SpecializationListener - protected void onSpecialize(VirtualFrame frame, Object value) { - slot.setType(value.getClass()); - frame.updateToLatestVersion(); - } - @Override protected FrameSlotNode specialize(Class clazz) { return WriteLocalNodeFactory.createSpecialized(this, clazz);