summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java4
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/Parser.java4
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/node/LoadNode.java14
-rw-r--r--chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java2
-rw-r--r--chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java34
-rw-r--r--chapter18/src/test/java/com/seaofnodes/simple/Eval2.java2
6 files changed, 51 insertions, 9 deletions
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java b/chapter18/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java
index bacbd538..69434472 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java
@@ -192,6 +192,10 @@ public abstract class GlobalCodeMotion {
assert late[st._nid]!=null;
lca = anti_dep(load,late[st._nid],st.cfg0(),lca,st);
break;
+ case CallNode st:
+ assert late[st._nid]!=null;
+ lca = anti_dep(load,late[st._nid],st.cfg0(),lca,st);
+ break;
case PhiNode phi:
// Repeat anti-dep for matching Phi inputs.
// No anti-dep edges but may raise the LCA.
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/Parser.java b/chapter18/src/main/java/com/seaofnodes/simple/Parser.java
index 9da49e7d..9bce5a5c 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/Parser.java
@@ -844,7 +844,7 @@ public class Parser {
Type t0 = type(); // Either return or first arg
if( t0==null ) return posT(old); // Not a function
if( match("}") ) // No-arg function { -> type }
- throw Utils.TODO();
+ return TypeFunPtr.make(match("?"),TypeTuple.BOT,t0);
Ary<Type> ts = new Ary<>(Type.class);
ts.push(t0); // First argument
while( true ) {
@@ -1113,6 +1113,8 @@ public class Parser {
if( t==null ) throw error("Expected a type");
// Parse ary[ length_expr ]
if( match("[") ) {
+ if( !t.makeZero().isa(t) )
+ throw error("Cannot allocate a non-nullable, since arrays always zero/null fill");
Node len = parseAsgn();
if( !(len._type instanceof TypeInteger) )
throw error("Cannot allocate an array with length "+len._type);
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/node/LoadNode.java b/chapter18/src/main/java/com/seaofnodes/simple/node/LoadNode.java
index 09494c15..ce481f49 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/node/LoadNode.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/node/LoadNode.java
@@ -84,17 +84,21 @@ public class LoadNode extends MemOpNode {
phi.addDep(this);
break outer;
case ConstantNode top: break outer; // Assume shortly dead
- case ProjNode mproj:
- if( mproj.in(0) instanceof NewNode nnn1 ) {
+
+ case ProjNode mproj: // Memory projection
+ switch( mproj.in(0) ) {
+ case NewNode nnn1:
if( ptr instanceof ProjNode pproj && pproj.in(0) == mproj.in(0) )
return castRO(nnn1.in(nnn1.findAlias(_alias))); // Load from New init
if( !(ptr instanceof ProjNode pproj && pproj.in(0) instanceof NewNode nnn2) )
break outer; // Cannot tell, ptr not related to New
mem = nnn1.in(_alias);// Bypass unrelated New
break;
- } else if( mproj.in(0) instanceof StartNode ) {
- break outer;
- } else throw Utils.TODO();
+ case StartNode start: break outer;
+ case CallEndNode cend: break outer; // TODO: Bypass no-alias call
+ default: throw Utils.TODO();
+ }
+ break;
default:
throw Utils.TODO();
}
diff --git a/chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java b/chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java
index 908b191b..576f8d92 100644
--- a/chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java
+++ b/chapter18/src/main/java/com/seaofnodes/simple/node/StoreNode.java
@@ -116,7 +116,7 @@ public class StoreNode extends MemOpNode {
Parser.ParseException err = super.err();
if( err != null ) return err;
TypeMemPtr tmp = (TypeMemPtr)ptr()._type;
- if( tmp._obj.field(_name)._final )
+ if( tmp._obj.field(_name)._final && !"[]".equals(_name) )
return Parser.error("Cannot modify final field '"+_name+"'",_loc);
Type t = val()._type;
return _init || t.isa(_declaredType) ? null : Parser.error("Cannot store "+t+" into field "+_declaredType+" "+_name,_loc);
diff --git a/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java
index aaeaab9e..39da0c72 100644
--- a/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java
+++ b/chapter18/src/test/java/com/seaofnodes/simple/Chapter18Test.java
@@ -77,7 +77,8 @@ return sq(arg)+sq(3);
assertEquals("13", Eval2.eval(code, 2));
}
- @Ignore @Test
+ // Recursive factorial test
+ @Test
public void testFcn2() {
CodeGen code = new CodeGen("val fact = { int x -> x <= 1 ? 1 : x*fact(x-1); }; return fact(arg);");
code.parse().opto();
@@ -88,4 +89,35 @@ return sq(arg)+sq(3);
assertEquals( "6", Eval2.eval(code, 3));
assertEquals("24", Eval2.eval(code, 4));
}
+
+
+
+ @Ignore @Test
+ public void testFcn3() {
+ CodeGen code = new CodeGen(
+"""
+val counter = { ->
+ int cnt;
+ val rez = new {int}?[2];
+ rez[0] = { -> cnt; };
+ rez[1] = { -> ++cnt; };
+ return rez;
+};
+val A = counter();
+val B = counter();
+int[] rez = new int[5];
+rez[0] = A[0](); // Value of counter A
+rez[1] = A[1](); // Increment counter A
+rez[2] = B[0](); // Value of counter B
+B[1](); // Increment B
+B[1](); // Increment B
+rez[3] = B[0](); // Value of counter B
+rez[4] = A[0]() * 10 + B[0]();
+return rez;
+""");
+ code.parse().opto();
+ assertEquals("Stop[ return (const)[int]; return (const)[{ -> int #ALL}?]; return 0; return 1; ]", code._stop.toString());
+ assertEquals("13", Eval2.eval(code, 0));
+ }
+
}
diff --git a/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java
index 181f3649..757699e4 100644
--- a/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java
+++ b/chapter18/src/test/java/com/seaofnodes/simple/Eval2.java
@@ -330,7 +330,7 @@ public abstract class Eval2 {
} else if (elem instanceof TypeFloat) {
Arrays.fill( ary, 0D );
} else {
- assert elem instanceof TypeMemPtr;
+ assert elem instanceof TypeMemPtr || elem instanceof TypeFunPtr;
}
return ary;
}