summaryrefslogtreecommitdiff
path: root/chapter15/src
diff options
context:
space:
mode:
Diffstat (limited to 'chapter15/src')
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/Parser.java2
-rw-r--r--chapter15/src/main/java/com/seaofnodes/simple/node/ReturnNode.java3
-rw-r--r--chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java28
-rw-r--r--chapter15/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java4
4 files changed, 35 insertions, 2 deletions
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
index d9726d28..ec040b4f 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java
@@ -711,6 +711,8 @@ public class Parser {
private Node newArray(Type t) {
Node len = parseExpression().keep();
+ if( !(len._type instanceof TypeInteger) )
+ throw error("Cannot allocate an array with length "+len._type);
TypeStruct ary = (TypeStruct)TYPES.get("[]"+t.str());
if( ary == null ) {
TYPES.put("[]"+t.str(), ary = TypeStruct.makeAry(TypeInteger.BOT,ALIAS++,t,ALIAS++));
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/ReturnNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/ReturnNode.java
index 444b76a8..e12f1fef 100644
--- a/chapter15/src/main/java/com/seaofnodes/simple/node/ReturnNode.java
+++ b/chapter15/src/main/java/com/seaofnodes/simple/node/ReturnNode.java
@@ -17,7 +17,8 @@ public class ReturnNode extends CFGNode {
public ReturnNode(Node ctrl, Node data, ScopeNode scope) {
super(ctrl, data);
- // We lookup memory slices by the naming convention that they start with $
+ // Add memory slices to Return, so all memory updates are live-on-exit.
+ // We look up memory slices by the naming convention that they start with $.
// We could also use implicit knowledge that all memory projects are at offset >= 2
if( scope != null ) {
String[] names = scope.reverseNames();
diff --git a/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java
index 2955361a..a3dd48d0 100644
--- a/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java
+++ b/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java
@@ -89,4 +89,32 @@ int is = new int[2];
try { parser.parse(false).iterate(false); fail(); }
catch( Exception e ) { assertEquals("Type *[]int is not of declared type int",e.getMessage()); }
}
+
+ @Test
+ public void testBad2() {
+ Parser parser = new Parser(
+"""
+int[] is = new int[3.14];
+return is[1];
+""");
+ try { parser.parse(false).iterate(false); fail(); }
+ catch( Exception e ) { assertEquals("Cannot allocate an array with length 3.14",e.getMessage()); }
+ }
+
+ @Test
+ public void testBad3() {
+ Parser parser = new Parser(
+"""
+int[] is = new int[arg];
+return is[1];
+""");
+ StopNode stop = parser.parse(false).iterate(false);
+ assertEquals("return 0;", stop.toString());
+ assertEquals(0L, Evaluator.evaluate(stop, 4));
+ try { Evaluator.evaluate(stop,0); }
+ catch( ArrayIndexOutOfBoundsException e ) { assertEquals("Array index 1 out of bounds for array length 0",e.getMessage()); }
+ try { Evaluator.evaluate(stop,-1); }
+ catch( NegativeArraySizeException e ) { assertEquals("-1",e.getMessage()); }
+ }
+
}
diff --git a/chapter15/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java b/chapter15/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java
index 40d73b19..e59017e7 100644
--- a/chapter15/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java
+++ b/chapter15/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java
@@ -91,6 +91,8 @@ public class Evaluator {
int base = alloc._ptr._obj.aryBase();
int scale = alloc._ptr._obj.aryScale();
long n = (sz-base)>>scale;
+ if( n < 0 )
+ throw new NegativeArraySizeException(""+n);
body = new Object[(int)n+1]; // Array body
body[0] = n; // Array length
} else {
@@ -113,7 +115,7 @@ public class Evaluator {
int scale = from.struct.aryScale();
long i = ((Long)off - base)>>scale;
if( i < 0 || i >= len )
- throw new RuntimeException("Array index out of bounds " + off + " <= " + len);
+ throw new ArrayIndexOutOfBoundsException("Array index out of bounds " + off + " <= " + len);
return from.fields[(int)i+1];
} else