changeset 22086:93bfc9602271

Recreate the CallTarget when number of arguments to the createExecute message changes
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Mon, 17 Aug 2015 15:49:18 +0200
parents 9e0ac14f941b
children 5d9e5f866821
files truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/SymbolInvokerImpl.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/SymbolInvoker.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java
diffstat 3 files changed, 30 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/SymbolInvokerImpl.java	Mon Aug 17 15:21:25 2015 +0200
+++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/impl/SymbolInvokerImpl.java	Mon Aug 17 15:49:18 2015 +0200
@@ -46,7 +46,7 @@
             symbolNode = new ConstantRootNode(type, symbol);
         } else {
             Node executeMain = Message.createExecute(arr.length).createNode();
-            symbolNode = new TemporaryRoot(type, executeMain, (TruffleObject) symbol);
+            symbolNode = new TemporaryRoot(type, executeMain, (TruffleObject) symbol, arr.length);
         }
         return Truffle.getRuntime().createCallTarget(symbolNode);
     }
@@ -69,18 +69,24 @@
     private static class TemporaryRoot extends RootNode {
         @Child private Node foreignAccess;
         @Child private ConvertNode convert;
+        private final int argumentLength;
         private final TruffleObject function;
 
-        public TemporaryRoot(Class<? extends TruffleLanguage<?>> lang, Node foreignAccess, TruffleObject function) {
+        public TemporaryRoot(Class<? extends TruffleLanguage<?>> lang, Node foreignAccess, TruffleObject function, int argumentLength) {
             super(lang, null, null);
             this.foreignAccess = foreignAccess;
             this.convert = new ConvertNode();
             this.function = function;
+            this.argumentLength = argumentLength;
         }
 
         @Override
         public Object execute(VirtualFrame frame) {
-            Object tmp = ForeignAccess.execute(foreignAccess, frame, function, frame.getArguments());
+            final Object[] args = frame.getArguments();
+            if (args.length != argumentLength) {
+                throw new ArgumentsMishmashException();
+            }
+            Object tmp = ForeignAccess.execute(foreignAccess, frame, function, args);
             return convert.convert(frame, tmp);
         }
     }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/SymbolInvoker.java	Mon Aug 17 15:21:25 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/SymbolInvoker.java	Mon Aug 17 15:49:18 2015 +0200
@@ -34,4 +34,16 @@
  */
 public abstract class SymbolInvoker {
     protected abstract CallTarget createCallTarget(TruffleLanguage<?> lang, Object symbol, Object... args) throws IOException;
+
+    public static final class ArgumentsMishmashException extends IllegalArgumentException {
+        static final long serialVersionUID = 1L;
+
+        public ArgumentsMishmashException() {
+        }
+
+        @Override
+        public synchronized Throwable fillInStackTrace() {
+            return this;
+        }
+    }
 }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java	Mon Aug 17 15:21:25 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java	Mon Aug 17 15:49:18 2015 +0200
@@ -489,10 +489,16 @@
                     arr.add(thiz);
                 }
                 arr.addAll(Arrays.asList(args));
-                if (target == null) {
-                    target = SPI.createCallTarget(language, obj, arr.toArray());
+                for (;;) {
+                    if (target == null) {
+                        target = SPI.createCallTarget(language, obj, arr.toArray());
+                    }
+                    try {
+                        return target.call(arr.toArray());
+                    } catch (SymbolInvoker.ArgumentsMishmashException ex) {
+                        target = null;
+                    }
                 }
-                return target.call(arr.toArray());
             }
         }
     }