diff options
Diffstat (limited to 'src/test/java/com/seaofnodes/simple/TestC.java')
| -rw-r--r-- | src/test/java/com/seaofnodes/simple/TestC.java | 97 |
1 files changed, 57 insertions, 40 deletions
diff --git a/src/test/java/com/seaofnodes/simple/TestC.java b/src/test/java/com/seaofnodes/simple/TestC.java index 5609758b..93fa9b66 100644 --- a/src/test/java/com/seaofnodes/simple/TestC.java +++ b/src/test/java/com/seaofnodes/simple/TestC.java @@ -1,10 +1,10 @@ package com.seaofnodes.simple; import com.seaofnodes.simple.codegen.CodeGen; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.io.InputStream; -import java.io.IOException; +import java.util.concurrent.TimeUnit; import static org.junit.Assert.*; // Call a C driver program, which calls a Simple-generated .o, and self-checks. @@ -16,8 +16,8 @@ public abstract class TestC { public static final String CALL_CONVENTION = OS.startsWith("Windows") ? "Win64" : "SystemV"; public static final String CPU_PORT = switch( CPU ) { - case "amd64" -> "x86_64_v2"; - default -> throw Utils.TODO("Map Yer CPU Port Here"); + case "amd64" -> "x86_64_v2"; + default -> throw Utils.TODO("Map Yer CPU Port Here"); }; public static void run( String file, int spills ) throws IOException { run(file,"",spills); } @@ -35,48 +35,16 @@ public abstract class TestC { // Compile and export Simple String src = Files.readString(Path.of(sfile)); - _run(src,CALL_CONVENTION,"",cfile,efile,"S",expected,spills); + run(src,CALL_CONVENTION,"",cfile,efile,"S",expected,spills); } - static void _run( String src, String simple_conv, String c_conv, String cfile, String efile, String xtn, String expected, int spills ) throws IOException { + public static void run( String src, String simple_conv, String c_conv, String cfile, String efile, String xtn, String expected, int spills ) throws IOException { String bin = efile+xtn; String obj = bin+".o"; + String exe = OS.startsWith("Windows") ? bin+".exe" : bin; // Compile simple, emit ELF CodeGen code = new CodeGen(src).driver( CPU_PORT, simple_conv, obj); - - // Compile the C program - var params = new String[] { - //if (USE_WSL) "wsl.exe"; - "gcc", - cfile, - obj, - "-lm", // Picks up 'sqrt' for newtonFloat tests to compare - "-g", - "-o", - bin, - "-D", - "CALL_CONV="+c_conv, - }; - Process gcc = new ProcessBuilder(params).redirectErrorStream(true).start(); - byte error; - try { error = (byte)gcc.waitFor(); } catch( InterruptedException e ) { throw new IOException("interrupted"); } - String result = new String(gcc.getInputStream().readAllBytes()); - if( error!=0 ) { - System.err.println("gcc error code: "+error); - System.err.println(result); - } - assertEquals( 0, error ); - //assertTrue(result.isEmpty()); // No data in error stream - - // Execute results - Process smp = new ProcessBuilder(bin).redirectErrorStream(true).start(); - try { error = (byte)smp.waitFor(); } catch( InterruptedException e ) { throw new IOException("interrupted"); } - result = new String(smp.getInputStream().readAllBytes()); - if( error!=0 ) { - System.err.println("exec error code: "+error); - System.err.println(result); - } - assertEquals( 0, error ); + String result = gcc(obj, c_conv, cfile, false, exe ); assertEquals(expected,result); // Allocation quality not degraded @@ -84,6 +52,55 @@ public abstract class TestC { if( delta==0 ) delta = 1; if( spills != -1 ) assertEquals("Expect spills:",spills,code._regAlloc._spillScaled,delta); + } + + public static String gcc( String obj, String c_conv, String cfile, boolean stdin, String... args ) throws IOException { + + // Compile the C program. Compiling code and constants in the low + // 2Gig. Pointers are 64b BUT since always in the low 2G all the + // high bits are zero - and Simple code can be emitted treating + // pointers as 4bytes. + var params = new Ary<>(String.class); + params.add("gcc"); + if( cfile!=null ) params.add(cfile); // Associated C driver, usually has a `main` + params.addAll(new String[] { + obj, + "-lm", // Picks up 'sqrt' for newtonFloat tests to compare + "-g", + "-o", + args[0], + }); + // Calling convention for C calls, if any + if( cfile!=null ) { + params.add("-D"); + params.add("CALL_CONV="+c_conv); + } + // Run GCC to link (optionally compile C driver code) + Process gcc = new ProcessBuilder(params.asAry()).redirectErrorStream(true).start(); + int exit; + try { + boolean normal = gcc.waitFor(2, TimeUnit.SECONDS); + exit = normal ? gcc.exitValue() : -1; // no exit??? + } catch( InterruptedException e ) { + throw new IOException("interrupted"); + } + String result = new String(gcc.getInputStream().readAllBytes()); + if( exit!=0 ) { + System.err.println("gcc error code: "+exit); + System.err.println(result); + } + assertEquals( 0, exit ); + //assertTrue(result.isEmpty()); // No data in error stream + + // Execute results + ProcessBuilder smp = new ProcessBuilder(args); + if( stdin ) smp.redirectInput(ProcessBuilder.Redirect.INHERIT); + Process p = smp.start(); + try { exit = (byte)p.waitFor(); } catch( InterruptedException e ) { throw new IOException("interrupted"); } + result = new String(p.getInputStream().readAllBytes()); + if( exit!=0 ) + System.err.println("exec exit code: "+exit); + return result; } } |
