]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
(refs #7567) Added throw function to builtins 34/1134/1
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 20 Oct 2017 08:02:08 +0000 (11:02 +0300)
committerHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 20 Oct 2017 08:02:08 +0000 (11:02 +0300)
Change-Id: I273e5c85b4a842e0ce4dc1603800742f9fbb6ea5

bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/FailFunction.java [deleted file]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/ThrowFunction.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/Builtins.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/SSAStatement.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Throw2.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/statements/LetStatement.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/ModuleRegressionTests.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Throw1.scl [new file with mode: 0644]

diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/FailFunction.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/FailFunction.java
deleted file mode 100644 (file)
index 2a47c39..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.simantics.scl.compiler.constants;
-
-import org.cojen.classfile.TypeDesc;
-import org.simantics.scl.compiler.internal.codegen.references.Val;
-import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
-import org.simantics.scl.compiler.types.TVar;
-import org.simantics.scl.compiler.types.Type;
-import org.simantics.scl.compiler.types.Types;
-import org.simantics.scl.compiler.types.kinds.Kinds;
-
-public class FailFunction extends FunctionValue {
-
-    private static final TVar A = Types.var(Kinds.STAR);
-    public static final FailFunction INSTANCE = 
-            new FailFunction();
-    
-    private FailFunction() {
-        super(new TVar[] {A}, Types.NO_EFFECTS, A, Types.STRING);
-    }
-    
-    private static final TypeDesc RuntimeException = 
-            TypeDesc.forClass(RuntimeException.class);
-    
-    @Override
-    public Type applyExact(MethodBuilder mb, Val[] parameters) {
-        mb.newObject(RuntimeException);
-        mb.dup();
-        mb.push(parameters, parameterTypes);
-        mb.invokeConstructor(RuntimeException, 
-                new TypeDesc[] {TypeDesc.STRING});
-        mb.throwObject();
-        return getReturnType();
-    }
-
-    @Override
-    public String toString() {
-         return "fail";
-    }
-}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/ThrowFunction.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/constants/singletons/ThrowFunction.java
new file mode 100644 (file)
index 0000000..f98e635
--- /dev/null
@@ -0,0 +1,52 @@
+package org.simantics.scl.compiler.constants.singletons;
+
+import org.simantics.scl.compiler.constants.FunctionValue;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAStatement;
+import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw2;
+import org.simantics.scl.compiler.internal.codegen.ssa.statements.LetApply;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+import org.simantics.scl.compiler.internal.codegen.utils.SSASimplificationContext;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+public class ThrowFunction extends FunctionValue {
+
+    private static final TVar A = Types.var(Kinds.STAR);
+    private static final TVar B = Types.var(Kinds.STAR);
+    public static final ThrowFunction INSTANCE = 
+            new ThrowFunction();
+    
+    private ThrowFunction() {
+        super(new TVar[] {A, B}, Types.PROC, B, A);
+    }
+    
+    @Override
+    public Type applyExact(MethodBuilder mb, Val[] parameters) {
+        mb.pushBoxed(parameters[0]);
+        mb.throwObject();
+        return getReturnType();
+    }
+
+    @Override
+    public String toString() {
+         return "throw";
+    }
+    
+    @Override
+    public void inline(SSASimplificationContext context, LetApply apply) {
+        if(apply.getParameters().length != 1)
+            return; // shouldn't be possible
+        
+        SSABlock block = apply.getParent();
+        for(SSAStatement statement=apply.getNext();statement != null;statement=statement.getNext())
+            statement.destroy();
+        apply.getFunction().remove();
+        apply.detachThisAndSuccessors();
+        block.getExit().destroy();
+        block.setExit(new Throw2(apply.getParameters()[0]));
+    }
+}
index 45638c05628043d6553434e1b781059423d573f3..631ef2ddc6d7ac874ca073c6b5c6b4363579a488 100644 (file)
@@ -18,6 +18,7 @@ import org.simantics.scl.compiler.constants.singletons.BindingConstant;
 import org.simantics.scl.compiler.constants.singletons.FailFunction;
 import org.simantics.scl.compiler.constants.singletons.JustConstant;
 import org.simantics.scl.compiler.constants.singletons.NothingConstant;
+import org.simantics.scl.compiler.constants.singletons.ThrowFunction;
 import org.simantics.scl.compiler.constants.singletons.TypeOfConstant;
 import org.simantics.scl.compiler.constants.singletons.TypeOfProxyConstant;
 import org.simantics.scl.compiler.constants.singletons.TypeProxyConstant;
@@ -209,6 +210,8 @@ public class Builtins extends ConcreteModule {
         
         addValue("fail", FailFunction.INSTANCE).documentation =
                 "Throws a runtime exeception with the given string as a description.";
+        addValue("throw", ThrowFunction.INSTANCE).documentation =
+                "Throws a given exception.";
                 
         // *** runProc ***
         
index e957723d35f43ee5fe8b85515a46f4a2e569a78b..a5d0bdc9f0dd32173d4ba33b3feac875ee101928 100644 (file)
@@ -125,4 +125,12 @@ public abstract class SSAStatement implements Printable {
     public abstract void forValRefs(ValRefVisitor visitor);
 
     public abstract void cleanup();
+
+    public void detachThisAndSuccessors() {
+        parent.lastStatement = prev;
+        if(prev == null)
+            parent.firstStatement = null;
+        else
+            prev.next = null;
+    }
 }
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Throw2.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/codegen/ssa/exits/Throw2.java
new file mode 100644 (file)
index 0000000..78353b4
--- /dev/null
@@ -0,0 +1,82 @@
+package org.simantics.scl.compiler.internal.codegen.ssa.exits;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.internal.codegen.continuations.Cont;
+import org.simantics.scl.compiler.internal.codegen.continuations.ContRef;
+import org.simantics.scl.compiler.internal.codegen.references.Val;
+import org.simantics.scl.compiler.internal.codegen.references.ValRef;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSABlock;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAExit;
+import org.simantics.scl.compiler.internal.codegen.ssa.SSAFunction;
+import org.simantics.scl.compiler.internal.codegen.utils.CopyContext;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilder;
+import org.simantics.scl.compiler.internal.codegen.utils.PrintingContext;
+import org.simantics.scl.compiler.internal.codegen.utils.SSAValidationContext;
+import org.simantics.scl.compiler.internal.codegen.utils.ValRefVisitor;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+
+public class Throw2 extends SSAExit {
+
+    ValRef exception;
+    
+    public Throw2(ValRef exception) {
+        this.exception = exception;
+    }
+
+    @Override
+    public void toString(PrintingContext context) {
+        context.append("throw ");
+        context.append(exception);
+        context.append('\n');
+    }
+
+    @Override
+    public void generateCode(MethodBuilder mb) {
+        mb.pushBoxed(exception.getBinding());
+        mb.throwObject();
+    }
+
+    @Override
+    public void validate(SSAValidationContext context) {
+    }
+
+    @Override
+    public void destroy() {
+        exception.remove();
+    }
+
+    @Override
+    public SSAExit copy(CopyContext context) {
+        return new Throw2(exception.copy());
+    }
+    
+    @Override
+    public void replace(TVar[] vars, Type[] replacements) {
+    }
+
+    @Override
+    public void collectFreeVariables(SSAFunction function,
+            ArrayList<ValRef> vars) {
+    }
+    
+    @Override
+    public Cont addParametersInFrontOf(ContRef contRef, Val[] newParameters, Val[] oldParameters,
+            Cont proxy) {
+        return proxy;
+    }
+
+    @Override
+    public SSABlock[] getSuccessors() {
+        return SSABlock.EMPTY_ARRAY;
+    }
+
+    @Override
+    public void forValRefs(ValRefVisitor visitor) {
+    }
+
+    @Override
+    public void cleanup() {
+    }
+}
index 0ae6d8930f3ea36f5e2622c216fd91ee8715eafe..02d8977f692458e3e19f750fcb6d72b5adedd7a1 100644 (file)
@@ -32,7 +32,7 @@ public abstract class LetStatement extends SSAStatement implements BoundVarBinde
     
     @Override
     public void addBoundVariablesTo(SSAValidationContext context) {
-        context.validBoundVariables.add(target);        
+        context.validBoundVariables.add(target);
     }
 
 }
index 2321a93f6e57bc87d8d79d0ad4e696f1b72f7670..0e06e61e3ef57d4704abbbfa8803829c1e4df22d 100644 (file)
@@ -257,6 +257,7 @@ public class ModuleRegressionTests extends TestBase {
     @Test public void StringMatching1() { test(); }
     @Test public void SumOfInverses2() { test(); }
     @Test public void SwitchSimplification() { test(); }
+    @Test public void Throw1() { test(); }
     @Test public void TooManyParametersToSin() { test(); }
     @Test public void Transformation1() { test(); }
     @Test public void Transformation2() { test(); }
diff --git a/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Throw1.scl b/tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/Throw1.scl
new file mode 100644 (file)
index 0000000..bc75889
--- /dev/null
@@ -0,0 +1,10 @@
+import "Prelude"
+
+importJava "java.lang.Exception" where
+    @JavaName "<init>"
+    createException :: String -> <Proc> Exception
+
+main = throw (createException "Foo") `catch` \(e :: Exception) -> print e
+--
+java.lang.Exception: Foo
+()
\ No newline at end of file