summaryrefslogtreecommitdiff
path: root/src/test/java/com/seaofnodes/simple/TestC.java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-04-21 14:18:23 -0700
committerCliff Click <cliffc@acm.org>2025-07-03 09:50:14 -0700
commit018379b0cf4e286ceacb1e39f34dd80f770e381e (patch)
treed88eae2d5e2d9609f271ec78fb60aaf08c5aaee5 /src/test/java/com/seaofnodes/simple/TestC.java
parent49534ffa88fedb3a4ebc42094e9edb27d456e6d6 (diff)
downloadSimple-linear-chapter22.tar.gz
Simple-linear-chapter22.zip
Chapter 22: A Hello, World!linear-chapter22
Co-authored-by: godalming123 <68993177+godalming123@users.noreply.github.com> Co-authored-by: Tamás Hadházy <85063808+Hels15@users.noreply.github.com>
Diffstat (limited to 'src/test/java/com/seaofnodes/simple/TestC.java')
-rw-r--r--src/test/java/com/seaofnodes/simple/TestC.java97
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;
}
}