diff options
| author | Cliff Click <cliffc@acm.org> | 2024-10-04 14:18:47 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2024-10-06 08:56:22 -0700 |
| commit | 162558e68e0f8c83ad42a2c1bc676ae0eef2464c (patch) | |
| tree | e42b629f6725d753993450c69b046e0bb70ea92a /chapter15 | |
| parent | a417a50f8f7fefbd40bb39866b8d7db2cbd691c2 (diff) | |
| download | Simple-162558e68e0f8c83ad42a2c1bc676ae0eef2464c.tar.gz Simple-162558e68e0f8c83ad42a2c1bc676ae0eef2464c.zip | |
Force arrays to have a safety check
Improves BrainFuck
Diffstat (limited to 'chapter15')
4 files changed, 35 insertions, 7 deletions
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java index 64cde40f..012a010e 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java @@ -805,13 +805,22 @@ public class Parser { Node val = parseExpression(); // Auto-truncate when storing to narrow fields val = zsMask(val,f._type); - memAlias(f._alias, new StoreNode(name, f._alias, f._type, memAlias(f._alias), expr, off, val, false).peephole()); + Node st = new StoreNode(name, f._alias, f._type, memAlias(f._alias), expr, off, val, false); + // Arrays include control, as a proxy for a safety range check. + // Structs dont need this; they only need a NPE check which is + // done via the type system. + if( base.isAry() ) st.setDef(0,ctrl()); + memAlias(f._alias, st.peephole()); return val; // "obj.a = expr" returns the expression while updating memory } } - Node load = new LoadNode(name, f._alias, f._type, memAlias(f._alias), expr, off).peephole(); - return parsePostfix(load); + Node load = new LoadNode(name, f._alias, f._type, memAlias(f._alias), expr, off); + // Arrays include control, as a proxy for a safety range check + // Structs dont need this; they only need a NPE check which is + // done via the type system. + if( base.isAry() ) load.setDef(0,ctrl()); + return parsePostfix(load.peephole()); } diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/NewNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/NewNode.java index d7220bdc..f06564cd 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/node/NewNode.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/node/NewNode.java @@ -38,10 +38,10 @@ public class NewNode extends Node implements MultiNode { @Override public TypeTuple compute() { - Type[] ts = new Type[nIns()]; + Field[] fs = _ptr._obj._fields; + Type[] ts = new Type[fs.length+2]; ts[0] = Type.CONTROL; ts[1] = _ptr; - Field[] fs = _ptr._obj._fields; for( int i=0; i<fs.length; i++ ) ts[i+2] = TypeMem.make(fs[i]._alias,fs[i]._type.makeInit()).meet( in(i+2)._type ); return TypeTuple.make(ts); diff --git a/chapter15/src/test/java/com/seaofnodes/simple/BrainFuckTest.java b/chapter15/src/test/java/com/seaofnodes/simple/BrainFuckTest.java index 894abbf6..03a22c55 100644 --- a/chapter15/src/test/java/com/seaofnodes/simple/BrainFuckTest.java +++ b/chapter15/src/test/java/com/seaofnodes/simple/BrainFuckTest.java @@ -26,7 +26,7 @@ public class BrainFuckTest { encoded + """ int pc = 0; int d = 0; -u8[] data = new u8[10000]; +u8[] data = new u8[100]; int i=0; while(i < data#) { data[i] = 0; @@ -92,6 +92,6 @@ return result; for (byte b : "Hello Wo".getBytes(StandardCharsets.UTF_8)) { expected = (expected << 8) | b; } - assertEquals(expected, Evaluator.evaluate(stop, 0, 100000)); + assertEquals(expected, Evaluator.evaluate(stop, 0, 10000)); } } diff --git a/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java index 1aee2f0d..266d8a47 100644 --- a/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java +++ b/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java @@ -24,6 +24,25 @@ return 3.14; } @Test + public void testSafetyCheck() { + Parser parser = new Parser( +""" +u8[] old = new u8[0]; +u8[] output = new u8[1]; +int i = 0; +while (i < old#) { + output[i] = old[i]; + i = i + 1; +} +output[i] = 1; +return output; +"""); + StopNode stop = parser.parse(false).iterate(true); + assertEquals("return u8[];", stop.toString()); + assertEquals("Obj<u8[]> {\n #=1\n []=1\n}", Evaluator.evaluate(stop, 0).toString()); + } + + @Test public void testBasic1() { Parser parser = new Parser( """ |
