changeset 9258:07f8d136a05e

Truffle API changes for the Frame API. Introduction of Assumptions class.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 23 Apr 2013 15:34:06 +0200
parents 542712a4732a
children 324dcaedb1ed
files graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Assumption.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/LoopCountReceiver.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/DefaultTypeConversion.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlot.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotImpl.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotTypeException.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameSlotTypeListener.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameTypeConversion.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameUtil.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameVersion.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/MaterializedFrame.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/NativeFrame.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/TypeConversion.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/AbstractAssumption.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultAssumption.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultFrameTypeConversion.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultMaterializedFrame.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultVirtualFrame.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/intrinsics/TruffleIntrinsics.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/InvalidAssumptionException.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/SlowPathException.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/UnexpectedResultException.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/TruffleTypes.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AbstractTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/AddTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/ComparisonTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/DivTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopPrintTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/LoopTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/MulTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SubTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SumTest.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/TernaryTest.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/NodeFactory.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FrameSlotNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/ReadLocalNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/WriteLocalNode.java
diffstat 49 files changed, 1011 insertions(+), 706 deletions(-) [+]
line wrap: on
line diff
--- 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 @@
  * <p>
  * 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.
  * </p>
  * 
  * <p>
@@ -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);
+            }
         }
     }
 }
--- 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);
+            }
         }
     }
 }
--- 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);
+            }
         }
     }
 }
--- /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();
+}
--- /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);
+}
--- 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
--- 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;
-    }
-}
--- 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
--- 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<FrameSlotImpl> slots;
-    private FrameVersionImpl lastVersion;
     private final HashMap<Object, FrameSlotImpl> 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<FrameSlotTypeListener> 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<Object> 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<FrameSlotTypeListener> 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;
     }
 }
--- 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();
 }
--- /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;
+    }
+}
--- /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() {
+    }
+}
--- 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);
-}
--- /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);
+}
--- /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();
+        }
+    }
+}
--- 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);
-    }
-}
--- 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 {
+
 }
--- 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");
     }
--- 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);
-}
--- /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;
+    }
+}
--- /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;
+    }
+}
--- 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;
+    }
 }
--- /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;
+    }
+}
--- 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
--- 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);
+    }
 }
--- 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);
+        }
+    }
 }
--- 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();
+    }
 }
--- /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;
+
+}
--- 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<Node> {
@@ -180,7 +195,7 @@
         return array;
     }
 
-    private static final Unsafe unsafe = getUnsafe();
+    protected static final Unsafe unsafe = getUnsafe();
 
     private static Unsafe getUnsafe() {
         try {
--- 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;
+    }
 }
--- 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;
+    }
 }
--- 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;
-    }
 }
--- 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<String> 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;
     }
--- 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();
         }
 
--- 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";
--- 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()));
     }
+
 }
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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[] {
--- 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<TypedNode> expressions) {
@@ -123,7 +123,7 @@
     }
 
     public StatementNode createReturn(TypedNode value) {
-        FrameSlot slot = frameDescriptor.findOrAddFrameSlot("<retval>");
+        FrameSlot slot = frameDescriptor.findOrAddFrameSlot("<retval>", Integer.class);
         if (returnValue == null) {
             returnValue = ReadLocalNodeFactory.create(slot);
         }
--- 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);
--- 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
--- 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);