diff options
| author | Cliff Click <cliffc@acm.org> | 2025-04-10 17:18:53 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-04-10 17:18:53 -0700 |
| commit | b6765473a3ce3db943355abba8e8ff765a3f8a3b (patch) | |
| tree | 1ec1e549278168065814414a9901e57b8b6f9045 | |
| parent | b68dafa3e6e231bd0d0b0e613986c7e3181349b9 (diff) | |
| download | Simple-b6765473a3ce3db943355abba8e8ff765a3f8a3b.tar.gz Simple-b6765473a3ce3db943355abba8e8ff765a3f8a3b.zip | |
C tests check both Win64 qnd Sys5
NewX86 links against OS-specific `calloc`, uses OS-specific calling convention, and not the declared convention.
Encoding bug, byte-store of SIL, DIL, BPL needs a blank REX.
OBOB errors in Sys5 large-arg-count calling.
14 files changed, 139 insertions, 93 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java index 13abd93b..01faba52 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/NewX86.java @@ -6,14 +6,21 @@ import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.TypeFunPtr; public class NewX86 extends NewNode implements MachNode { + public static final String OS = System.getProperty("os.name"); + public static final RegMask ARG2 = OS.startsWith("Windows") + ? x86_64_v2.callWin64(TypeFunPtr.CALLOC,2) + : x86_64_v2.callSys5 (TypeFunPtr.CALLOC,2); + public static final RegMask ARG3 = OS.startsWith("Windows") + ? x86_64_v2.callWin64(TypeFunPtr.CALLOC,3) + : x86_64_v2.callSys5 (TypeFunPtr.CALLOC,3); + // A pre-zeroed chunk of memory. NewX86( NewNode nnn ) { super(nnn); } @Override public String op() { return "alloc"; } // Size and pointer result in standard calling convention; null for all the // memory aliases edges @Override public RegMask regmap(int i) { - // Any { int->int } signature will do, as they all pick the same registers - return i==1 ? x86_64_v2.callInMask(TypeFunPtr.CALLOC,3) : null; + return i==1 ? ARG2 : null; } @Override public RegMask outregmap(int i) { return i == 1 ? x86_64_v2.RAX_MASK : null; } @Override public RegMask outregmap() { return null; } @@ -21,18 +28,10 @@ public class NewX86 extends NewNode implements MachNode { @Override public void encoding( Encoding enc ) { enc.external(this,"calloc"); - short r1 = x86_64_v2.callInMask(TypeFunPtr.CALLOC,2).firstReg(); + // This has to call the *native* ABI, irregardless of how Simple is + // being compiled, because it links against the native calloc. // ldi rcx,#1 // number of elements to calloc - enc.add1(0xB8 + r1).add4(1); - - //enc.add1(x86_64_v2.rex(0, dst, 0)); - //// opcode; 0x81 or 0x83; 0x69 or 0x6B - //enc.add1( opcode() + 2 ); - //enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, mod(), dst) ); - //// immediate(4 bytes) 32 bits or (1 byte)8 bits - //enc.add1(_imm); - - + enc.add1(0xB8 + ARG3.firstReg()).add4(1); // E8 cd CALL rel32; enc.add1(0xE8); enc.add4(0); // offset diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java index 5fbd1f02..ac5de47d 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java @@ -57,8 +57,10 @@ public class StoreX86 extends MemOpX86 { src -= (short)x86_64_v2.XMM_OFFSET; enc.add1( decl==TypeFloat.F32 ? 0xF3 : 0xF2 ).add1(0x0F).add1(0x11); } else { + // byte stores from sil, dil, bpl, spl need a rex int log = decl.log_size(); - x86_64_v2.rexF(src,ptr,idx,log==3,enc); + if( log == 0 && src >= x86_64_v2.RSP ) enc.add1(x86_64_v2.rex(src,ptr,idx,false)); + else x86_64_v2.rexF(src,ptr,idx,log==3,enc); switch( log ) { case 0: enc .add1(0x88); break; case 1: enc.add1(0x66).add1(0x89); break; diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java index 2f70dc0c..7683177f 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java @@ -221,40 +221,63 @@ public class x86_64_v2 extends Machine { } // Win64 - max *4* args in registers of all kinds; after that on stack. - // Stack args land in increasing memory order. - // foo( int arg0, int arg1, int arg2, int arg3, int stk1, flt stk2, int stk3, ... ) + // Stack args land in increasing memory order with empty/mirror slots for + // every register. + // + // foo( int i0, flt f1, int i2, flt f3, int i4, flt f5, int i6, ... ) // // -- Prior Frame -- - // RPC - // stk3 - // stk2 - // stk1 + // i6 + // f5 + // i4 + // empty mirror, XMM3= f3 + // empty mirror, R08 = i2 + // empty mirror, XMM1= f1 + // empty mirror, RCX = i0 // -- Caller Frame; 16b align -- // RPC - // PAD + // PAD/ALIGN // -- Callee Frame; 16b align -- - static RegMask[] CALLINMASK_WIN64 = new RegMask[] { + static RegMask[] WIN64_CALL = new RegMask[] { RCX_MASK, RDX_MASK, R08_MASK, R09_MASK, }; - private static RegMask callWin64(TypeFunPtr tfp, int idx ) { - // idx 2,3,4,5 passed in registers, with stack slot mirrors - // idx >= 6 passed on stack, starting at slot#1 (#0 reserved for RPC) + static RegMask callWin64(TypeFunPtr tfp, int idx ) { + // idx 2,3,4,5 passed in registers, with stack slot mirrors. + // idx >= 6 passed on stack, starting at slot#1 (#0 reserved for RPC). if( idx >= 6 ) return new RegMask(MAX_REG+1/*RPC*/+(idx-2)); return tfp.arg(idx-2) instanceof TypeFloat - ? XMMS8[idx-2] - : CALLINMASK_WIN64[idx-2]; + ? XMMS8 [idx-2] + : WIN64_CALL[idx-2]; } static short maxArgSlotWin64(TypeFunPtr tfp) { return (short)(1/*RPC*/+ tfp.nargs()); } + // Sys5: max 6 GPRs and 8 FPRS filled first. Extra args land in increasing + // memory order as needed - no mirror space. + // + // foo( int i0, flt f1, int i2, flt f3, int i4, flt f5, int i6, ... ) + // RDI =i0, RSI =i2, RDX =i4, RCX =i6, R08 =i8, R09 =i10 + // XMM0=f1, XMM1=f3, XMM2=f5, XMM3=f7, XMM4=f9, XMM5=f11, XMM6=f13, XMM7=f15 + // + // -- Prior Frame -- + // f18 + // i18 + // f17 + // i16 + // i14 + // i12 + // -- Caller Frame; 16b align -- + // RPC + // PAD/ALIGN + // -- Callee Frame; 16b align -- // SystemV(param passing) - static RegMask[] CALLINMASK_SYSTEMV = new RegMask[] { + static RegMask[] SYS5_CALL = new RegMask[] { RDI_MASK, RSI_MASK, RDX_MASK, @@ -263,7 +286,7 @@ public class x86_64_v2 extends Machine { R09_MASK, }; - private static RegMask callSys5(TypeFunPtr tfp, int idx ) { + static RegMask callSys5(TypeFunPtr tfp, int idx ) { // First 6 integers passed in registers: rdi,rsi,rdx,rcx,r08,r09 // First 8 floats passed in registers: xmm0-xmm7 int icnt=0, fcnt=0; // Count of ints, floats @@ -273,8 +296,8 @@ public class x86_64_v2 extends Machine { } int nstk = Math.max(icnt-6,0)+Math.max(fcnt-8,0); return tfp.arg(idx-2) instanceof TypeFloat - ? fcnt<8 ? XMMS8 [fcnt] : new RegMask(MAX_REG+nstk) - : icnt<6 ? CALLINMASK_SYSTEMV[icnt] : new RegMask(MAX_REG+nstk); + ? fcnt<8 ? XMMS8 [fcnt] : new RegMask(MAX_REG+1/*RPC*/+nstk) + : icnt<6 ? SYS5_CALL[icnt] : new RegMask(MAX_REG+1/*RPC*/+nstk); } static short maxArgSlotSys5(TypeFunPtr tfp) { int icnt=0, fcnt=0; // Count of ints, floats @@ -283,7 +306,7 @@ public class x86_64_v2 extends Machine { else icnt++; } int nstk = Math.max(icnt-6,0)+Math.max(fcnt-8,0); - return (short)(1+nstk); + return (short)(1/*RPC*/+nstk); } // caller saved(systemv) diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java index 631862e9..9d10ed6a 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java @@ -141,7 +141,7 @@ public class Chapter21Test { } @Test public void testArgCount() throws IOException { - String arg_count = "153.900000\n"; + String arg_count = "191.000000\n"; TestC.run("arg_count", arg_count); } } diff --git a/chapter21/src/test/java/com/seaofnodes/simple/TestC.java b/chapter21/src/test/java/com/seaofnodes/simple/TestC.java index e4c69709..160569b1 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/TestC.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/TestC.java @@ -29,26 +29,42 @@ public abstract class TestC { // Compile and run a simple program public static void run( String dir, String file, String expected ) throws IOException { // Files - String cfile = dir+"/"+file+".c" ; - String sfile = dir+"/"+file+".smp"; - String sofile = "build/objs/"+file+"S.o"; - String efile = "build/objs/"+file; + String cfile = dir+"/"+file+".c" ; + String sfile = dir+"/"+file+".smp"; + String efile = "build/objs/"+file; // Compile and export Simple String src = Files.readString(Path.of(sfile)); - CodeGen code = new CodeGen(src).parse().opto().typeCheck().instSelect( CPU_PORT, CALL_CONVENTION).GCM().localSched().regAlloc().encode().exportELF(sofile); + + // On X86, compile both win64 and sys5 variants + if( CPU_PORT.equals("x86_64_v2") ) { + _run(src,"Win64" ,"ms_abi" ,cfile,efile,"W",expected); + _run(src,"SystemV","sysv_abi",cfile,efile,"S",expected); + } else { + _run(src,CALL_CONVENTION,"",cfile,efile,"S",expected); + } + } + + static void _run( String src, String simple_conv, String c_conv, String cfile, String efile, String xtn, String expected ) throws IOException { + String bin = efile+xtn; + String obj = bin+".o"; + // Compile simple, emit ELF + CodeGen code = new CodeGen(src).parse().opto().typeCheck().instSelect( CPU_PORT, simple_conv).GCM().localSched().regAlloc().encode().exportELF(obj); // Compile the C program - var params = new Ary<>(String.class); - //if (USE_WSL) params.add("wsl.exe"); - params.add("gcc"); - params.add(cfile); - params.add(sofile); - params.add("-lm"); - params.add("-g"); - params.add("-o"); - params.add(efile); - Process gcc = new ProcessBuilder(params.toArray(String[]::new)).redirectErrorStream(true).start(); + 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()); @@ -60,7 +76,7 @@ public abstract class TestC { //assertTrue(result.isEmpty()); // No data in error stream // Execute results - Process smp = new ProcessBuilder(efile).redirectErrorStream(true).start(); + 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()); assertEquals( 0, error ); diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/arg_count.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/arg_count.c index f0cae2b8..e247e28a 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/progs/arg_count.c +++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/arg_count.c @@ -1,9 +1,10 @@ #include <stdio.h> -extern double addAll( long long i0, double f1, long long i2, double f3, long long i4, double f5, long long i6, double f7, long long i8, double f9, long long i10, double f11, long long i12, double f13, long long i14, double f15, long long i16, double f17 ); +__attribute__ ((CALL_CONV)) +extern double addAll( long long i0, double f1, long long i2, double f3, long long i4, double f5, long long i6, double f7, long long i8, double f9, long long i10, double f11, long long i12, double f13, long long i14, double f15, long long i16, double f17, long long i18, double f19 ); int main() { - double result = addAll( 0, 1.1, 2, 3.1, 4, 5.1, 6, 7.1, 8, 9.1, 10, 11.1, 12, 13.1, 14, 15.1, 16, 17.1 ); + double result = addAll( 0, 1.1, 2, 3.1, 4, 5.1, 6, 7.1, 8, 9.1, 10, 11.1, 12, 13.1, 14, 15.1, 16, 17.1, 18, 19.1 ); printf("%f\n", result); return 0; } diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/arg_count.smp b/chapter21/src/test/java/com/seaofnodes/simple/progs/arg_count.smp index 102ead99..6b6bc0ae 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/progs/arg_count.smp +++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/arg_count.smp @@ -1,6 +1,6 @@ // -*- mode: java; -*- -val addAll = { int i0, flt f1, int i2, flt f3, int i4, flt f5, int i6, flt f7, int x8, flt f9, int i10, flt f11, int i12, flt f13, int i14, flt f15, int x16, flt f17 -> +val addAll = { int i0, flt f1, int i2, flt f3, int i4, flt f5, int i6, flt f7, int x8, flt f9, int i10, flt f11, int i12, flt f13, int i14, flt f15, int x16, flt f17 int x18, flt f19 -> return i0 + f1+ i2+ f3+ i4+ f5+ i6+ f7+ x8 +f9 + - i10+f11+i12+f13+i14+f15+x16+f17; + i10+f11+i12+f13+i14+f15+x16+f17+x18+f19 ; }; diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/brain_fuck.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/brain_fuck.c index bf981afd..15de1864 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/progs/brain_fuck.c +++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/brain_fuck.c @@ -6,6 +6,7 @@ typedef struct AryInt { unsigned char data[]; } AryInt; +__attribute__ ((CALL_CONV)) extern AryInt* brain_fuck(); int main() { diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/brain_fuck.smp b/chapter21/src/test/java/com/seaofnodes/simple/progs/brain_fuck.smp index d91eb24f..ed90cb84 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/progs/brain_fuck.smp +++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/brain_fuck.smp @@ -1,47 +1,46 @@ // -*- mode: java; -*- val brain_fuck = { -> -u8[] !program = new u8[106];program[0] = 43;program[1] = 43;program[2] = 43;program[3] = 43;program[4] = 43;program[5] = 43;program[6] = 43;program[7] = 43;program[8] = 91;program[9] = 62;program[10] = 43;program[11] = 43;program[12] = 43;program[13] = 43;program[14] = 91;program[15] = 62;program[16] = 43;program[17] = 43;program[18] = 62;program[19] = 43;program[20] = 43;program[21] = 43;program[22] = 62;program[23] = 43;program[24] = 43;program[25] = 43;program[26] = 62;program[27] = 43;program[28] = 60;program[29] = 60;program[30] = 60;program[31] = 60;program[32] = 45;program[33] = 93;program[34] = 62;program[35] = 43;program[36] = 62;program[37] = 43;program[38] = 62;program[39] = 45;program[40] = 62;program[41] = 62;program[42] = 43;program[43] = 91;program[44] = 60;program[45] = 93;program[46] = 60;program[47] = 45;program[48] = 93;program[49] = 62;program[50] = 62;program[51] = 46;program[52] = 62;program[53] = 45;program[54] = 45;program[55] = 45;program[56] = 46;program[57] = 43;program[58] = 43;program[59] = 43;program[60] = 43;program[61] = 43;program[62] = 43;program[63] = 43;program[64] = 46;program[65] = 46;program[66] = 43;program[67] = 43;program[68] = 43;program[69] = 46;program[70] = 62;program[71] = 62;program[72] = 46;program[73] = 60;program[74] = 45;program[75] = 46;program[76] = 60;program[77] = 46;program[78] = 43;program[79] = 43;program[80] = 43;program[81] = 46;program[82] = 45;program[83] = 45;program[84] = 45;program[85] = 45;program[86] = 45;program[87] = 45;program[88] = 46;program[89] = 45;program[90] = 45;program[91] = 45;program[92] = 45;program[93] = 45;program[94] = 45;program[95] = 45;program[96] = 45;program[97] = 46;program[98] = 62;program[99] = 62;program[100] = 43;program[101] = 46;program[102] = 62;program[103] = 43;program[104] = 43;program[105] = 46; -int d = 0; -u8[] !output = new u8[0]; -u8[] !data = new u8[100]; + u8[] !program = new u8[106];program[0] = 43;program[1] = 43;program[2] = 43;program[3] = 43;program[4] = 43;program[5] = 43;program[6] = 43;program[7] = 43;program[8] = 91;program[9] = 62;program[10] = 43;program[11] = 43;program[12] = 43;program[13] = 43;program[14] = 91;program[15] = 62;program[16] = 43;program[17] = 43;program[18] = 62;program[19] = 43;program[20] = 43;program[21] = 43;program[22] = 62;program[23] = 43;program[24] = 43;program[25] = 43;program[26] = 62;program[27] = 43;program[28] = 60;program[29] = 60;program[30] = 60;program[31] = 60;program[32] = 45;program[33] = 93;program[34] = 62;program[35] = 43;program[36] = 62;program[37] = 43;program[38] = 62;program[39] = 45;program[40] = 62;program[41] = 62;program[42] = 43;program[43] = 91;program[44] = 60;program[45] = 93;program[46] = 60;program[47] = 45;program[48] = 93;program[49] = 62;program[50] = 62;program[51] = 46;program[52] = 62;program[53] = 45;program[54] = 45;program[55] = 45;program[56] = 46;program[57] = 43;program[58] = 43;program[59] = 43;program[60] = 43;program[61] = 43;program[62] = 43;program[63] = 43;program[64] = 46;program[65] = 46;program[66] = 43;program[67] = 43;program[68] = 43;program[69] = 46;program[70] = 62;program[71] = 62;program[72] = 46;program[73] = 60;program[74] = 45;program[75] = 46;program[76] = 60;program[77] = 46;program[78] = 43;program[79] = 43;program[80] = 43;program[81] = 46;program[82] = 45;program[83] = 45;program[84] = 45;program[85] = 45;program[86] = 45;program[87] = 45;program[88] = 46;program[89] = 45;program[90] = 45;program[91] = 45;program[92] = 45;program[93] = 45;program[94] = 45;program[95] = 45;program[96] = 45;program[97] = 46;program[98] = 62;program[99] = 62;program[100] = 43;program[101] = 46;program[102] = 62;program[103] = 43;program[104] = 43;program[105] = 46; + int d = 0; + u8[] !output = new u8[0]; + u8[] !data = new u8[100]; -for( int pc = 0; pc < program#; pc++ ) { - var command = program[pc]; - if (command == 62) { - d++; - } else if (command == 60) { - d--; - } else if (command == 43) { - data[d]++; - } else if (command == 45) { - data[d]--; - } else if (command == 46) { - // Output a byte; increase the output array size - var old = output; - output = new u8[output# + 1]; - for( int i = 0; i < old#; i++ ) - output[i] = old[i]; - output[old#] = data[d]; // Add the extra byte on the end - } else if (command == 44) { - data[d] = 42; - } else if (command == 91) { - if (data[d] == 0) { - for( int d = 1; d > 0; ) { - command = program[++pc]; - if (command == 91) d++; - if (command == 93) d--; + for( int pc = 0; pc < program#; pc++ ) { + var command = program[pc]; + if (command == 62) { + d++; + } else if (command == 60) { + d--; + } else if (command == 43) { + data[d]++; + } else if (command == 45) { + data[d]--; + } else if (command == 46) { + // Output a byte; increase the output array size + var old = output; + output = new u8[output# + 1]; + for( int i = 0; i < old#; i++ ) + output[i] = old[i]; + output[old#] = data[d]; // Add the extra byte on the end + } else if (command == 44) { + data[d] = 42; + } else if (command == 91) { + if (data[d] == 0) { + for( int d = 1; d > 0; ) { + command = program[++pc]; + if (command == 91) d++; + if (command == 93) d--; + } } - } - } else if (command == 93) { - if (data[d]) { - for( int d = 1; d > 0; ) { - command = program[--pc]; - if (command == 93) d++; - if (command == 91) d--; + } else if (command == 93) { + if (data[d]) { + for( int d = 1; d > 0; ) { + command = program[--pc]; + if (command == 93) d++; + if (command == 91) d--; + } } } } -} -return output; + return output; }; - diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/fib.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/fib.c index c18b5c23..263d2f13 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/progs/fib.c +++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/fib.c @@ -2,6 +2,7 @@ #include <stdbool.h> +__attribute__ ((CALL_CONV)) extern int fib(int x); int main() { diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/newtonFloat.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/newtonFloat.c index 70c9e426..96947810 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/progs/newtonFloat.c +++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/newtonFloat.c @@ -2,6 +2,7 @@ #include <math.h> #include <stdlib.h> +__attribute__ ((CALL_CONV)) extern double test_sqrt(double); int main( int argc, char** argv ) { diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/person.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/person.c index 8ea0c9f6..df95e1ca 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/progs/person.c +++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/person.c @@ -12,6 +12,7 @@ typedef struct PersonArray { Person* data[]; } PersonArray; +__attribute__ ((CALL_CONV)) extern void fcn(PersonArray* people, int index); int main() { diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.c index b0e85dba..cac4cfa3 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.c +++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.c @@ -3,9 +3,10 @@ typedef struct AryInt { unsigned int len; - int data[]; + unsigned int data[]; } AryInt; +__attribute__ ((CALL_CONV)) extern AryInt *sieve(int N); int main() { diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.c index e0704f74..2c6d0fa9 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.c +++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/stringHash.c @@ -11,6 +11,7 @@ typedef struct String { } String; +__attribute__ ((CALL_CONV)) extern bool equals(String*st1, String*st2); int main() { |
