From: Bernhard Urban Date: Thu, 26 Apr 2012 15:10:17 +0000 (+0200) Subject: varargs: make printf working X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mate.git;a=commitdiff_plain;h=1675296109f7d45f42b2100cb70a4edb314fe6d6 varargs: make printf working although it's still a hack: WOOOT --- diff --git a/Makefile b/Makefile index f170acc..87aca3b 100644 --- a/Makefile +++ b/Makefile @@ -68,6 +68,7 @@ test: mate $(CLASS_FILES) @printf "should be: 0x%08x 0x%08x\n" 0x264 0x8 ./$< tests/Integer1 | grep mainresult @printf "should be: 0x%08x\n" 0x1337 + ./$< tests/VarArgs1 | grep mainresult %.class: %.java $(JAVAC) $< diff --git a/Mate/X86CodeGen.hs b/Mate/X86CodeGen.hs index 59ccb42..1eb9057 100644 --- a/Mate/X86CodeGen.hs +++ b/Mate/X86CodeGen.hs @@ -234,12 +234,14 @@ emitFromBB method cls hmap = do call (trapaddr - w32_calladdr) add esp (4 :: Word32) emit DUP = push (Disp 0, esp) + emit AASTORE = emit IASTORE emit IASTORE = do pop eax -- value pop ebx -- offset add ebx (1 :: Word32) pop ecx -- aref mov (ecx, ebx, S4) eax + emit AALOAD = emit IALOAD emit IALOAD = do pop ebx -- offset add ebx (1 :: Word32) @@ -248,6 +250,7 @@ emitFromBB method cls hmap = do emit ARRAYLENGTH = do pop eax push (Disp 0, eax) + emit (ANEWARRAY _) = emit (NEWARRAY 10) -- 10 == T_INT emit (NEWARRAY typ) = do let tsize = case decodeS (0 :: Integer) (B.pack [typ]) of T_INT -> 4 @@ -280,6 +283,7 @@ emitFromBB method cls hmap = do emit (ICONST_0) = push (0 :: Word32) emit (ICONST_1) = push (1 :: Word32) emit (ICONST_2) = push (2 :: Word32) + emit (ICONST_3) = push (3 :: Word32) emit (ICONST_4) = push (4 :: Word32) emit (ICONST_5) = push (5 :: Word32) emit (ALOAD_ x) = emit (ILOAD_ x) diff --git a/ffi/native.c b/ffi/native.c index a9aa227..2972a18 100644 --- a/ffi/native.c +++ b/ffi/native.c @@ -1,5 +1,29 @@ #include +static char ascii(char s) { + if(s < 0x20) return '.'; + if(s > 0x7E) return '.'; + return s; +} + +void hexdump(void *d, int len) { + unsigned char *data; + int i, off; + data = (unsigned char*)d; + for (off=0; off=len) printf(" "); + else printf("%02x ",data[off+i]); + + printf(" "); + for(i=0; i<16; i++) + if((i+off)>=len) printf(" "); + else printf("%c",ascii(data[off+i])); + printf("\n"); + } +} + void tests_Native1__printSomething____V(void) { printf("printSomething: woot \\o/\n"); @@ -24,3 +48,39 @@ void java_io_PrintStream__println___Ljava_lang_String__V(const char *a) { printf("%s\n", a); } + +struct integer { + unsigned int method_table_ptr; + int value; +}; + +void java_io_PrintStream__printf_1___Ljava_lang_String_Ljava_lang_Object__V + (struct integer *a1, const char *fmt) +{ + printf(fmt, a1->value); +} + +void java_io_PrintStream__printf_2___Ljava_lang_String_Ljava_lang_Object_Ljava_lang_Object__V + (struct integer *a2, struct integer *a1, const char *fmt) +{ + printf(fmt, a1->value, a2->value); +} + +void +java_io_PrintStream__printf_3___Ljava_lang_String_Ljava_lang_Object_Ljava_lang_Object_Ljava_lang_Object__V + (struct integer *a3, struct integer *a2, struct integer *a1, const char *fmt) +{ + printf(fmt, a1->value, a2->value, a3->value); +} + +void java_io_PrintStream__printf_4___Ljava_lang_String_Ljava_lang_Object_Ljava_lang_Object_Ljava_lang_Object_Ljava_lang_Object__V + (struct integer *a4, struct integer *a3, struct integer *a2, struct integer *a1, const char *fmt) +{ + printf(fmt, a1->value, a2->value, a3->value, a4->value); +} + +void java_io_PrintStream__printf_5___Ljava_lang_String_Ljava_lang_Object_Ljava_lang_Object_Ljava_lang_Object_Ljava_lang_Object_Ljava_lang_Object__V + (struct integer *a5, struct integer *a4, struct integer *a3, struct integer *a2, struct integer *a1, const char *fmt) +{ + printf(fmt, a1->value, a2->value, a3->value, a4->value, a5->value); +} diff --git a/java/io/PrintStream.java b/java/io/PrintStream.java index 89fe534..0e7dafd 100644 --- a/java/io/PrintStream.java +++ b/java/io/PrintStream.java @@ -1,6 +1,29 @@ package java.io; public class PrintStream { - public native void printf(int a); + public PrintStream printf(String format, Object... args) { + /* temporary workaround ;-) */ + int len = args.length; + if (len == 0) { + this.println(format); + } else if (len == 1) { + this.printf_1(format, args[0]); + } else if (len == 2) { + this.printf_2(format, args[0], args[1]); + } else if (len == 3) { + this.printf_3(format, args[0], args[1], args[2]); + } else if (len == 4) { + this.printf_4(format, args[0], args[1], args[2], args[3]); + } else if (len == 5) { + this.printf_5(format, args[0], args[1], args[2], args[3], args[4]); + } + return this; + } + + public native void printf_1(String a, Object b); + public native void printf_2(String a, Object b, Object c); + public native void printf_3(String a, Object b, Object c, Object d); + public native void printf_4(String a, Object b, Object c, Object d, Object e); + public native void printf_5(String a, Object b, Object c, Object d, Object e, Object f); public native void println(String a); } diff --git a/tests/VarArgs1.java b/tests/VarArgs1.java new file mode 100644 index 0000000..c6f2f90 --- /dev/null +++ b/tests/VarArgs1.java @@ -0,0 +1,12 @@ +package tests; + +public class VarArgs1 { + public static void main(String []args) { + System.out.printf("result: nice0r\n"); + System.out.printf("result: 0x%08x\n", 0x1337); + System.out.printf("result: 0x%08x 0x%08x\n", 0x1337, 0x1122); + System.out.printf("result: 0x%08x 0x%08x 0x%08x\n", 0x1, 0x2, 0x3); + System.out.printf("result: 0x%08x 0x%08x 0x%08x 0x%08x\n", 0x1, 0x2, 0x3, 0x4); + System.out.printf("result: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", 0x1, 0x2, 0x3, 0x4, 0x5); + } +}