classpool: do classloading at central point. omit '.class' when calling `mate'
authorBernhard Urban <lewurm@gmail.com>
Mon, 23 Apr 2012 14:10:21 +0000 (16:10 +0200)
committerBernhard Urban <lewurm@gmail.com>
Mon, 23 Apr 2012 14:10:52 +0000 (16:10 +0200)
Makefile
Mate.hs
Mate/ClassPool.hs [new file with mode: 0644]
Mate/MethodPool.hs
Mate/X86CodeGen.hs
tests/Static1.java [new file with mode: 0644]

index f3a53a4c4f9e2121ac641af2df9217324d4a18fa..6fdae5590af42d1174e8ea8fc29f6ff9c9ad12ee 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,17 +17,18 @@ GHC_LD := -optl-Xlinker -optl-x
 all: mate $(CLASS_FILES)
 
 test: mate $(CLASS_FILES)
-       ./$< tests/Fib.class | grep mainresult
+       ./$< tests/Fib | grep mainresult
        @printf "should be:  0x%08x\n" 0x09de8d6d
-       ./$< tests/Fac.class | grep mainresult
+       ./$< tests/Fac | grep mainresult
        @printf "should be:  0x%08x\n" 0x58980
-       ./$< tests/ArgumentPassing1.class | grep mainresult
+       ./$< tests/ArgumentPassing1 | grep mainresult
        @printf "should be:  0x%08x\n" 0x92
        @printf "should be:  0x%08x\n" $$(((0 - 0x1337) & 0xffffffff))
-       ./$< tests/DifferentClass1.class | grep mainresult
+       ./$< tests/DifferentClass1 | grep mainresult
        @printf "should be:  0x%08x\n" 8
        @printf "should be:  0x%08x\n" 13
-       ./$< tests/Native1.class | egrep -i -e '^printsomething: '
+       ./$< tests/Native1 | egrep -i -e '^printsomething: '
+       ./$< tests/Static1
 
 %.class: %.java
        $(JAVAC) $<
diff --git a/Mate.hs b/Mate.hs
index 35182cc866fa59a9ea582e3d36645b27695679f4..8e63fbf578132bd2c3afeeeae57700583c3fccd8 100644 (file)
--- a/Mate.hs
+++ b/Mate.hs
@@ -17,6 +17,7 @@ import Mate.BasicBlocks
 import Mate.X86CodeGen
 import Mate.MethodPool
 import Mate.Types
+import Mate.ClassPool
 
 main ::  IO ()
 main = do
@@ -25,7 +26,8 @@ main = do
   initMethodPool
   case args of
     [clspath] -> do
-      cls <- parseClassFile clspath
+      let bclspath = B.pack $ map (fromIntegral . ord) clspath
+      cls <- getClassFile bclspath
       dumpClass cls
       hmap <- parseMethod cls "main"
       printMapBB hmap
@@ -35,7 +37,6 @@ main = do
           let method = find (\x -> (methodName x) == "main") methods
           case method of
             Just m -> do
-              let bclspath = B.pack $ map (fromIntegral . ord) (replace ".class" "" clspath)
               entry <- compileBB hmap' (MethodInfo "main" bclspath (methodSignature m))
               printf "executing `main' now:\n"
               executeFuncPtr entry
diff --git a/Mate/ClassPool.hs b/Mate/ClassPool.hs
new file mode 100644 (file)
index 0000000..d14c2f3
--- /dev/null
@@ -0,0 +1,34 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module Mate.ClassPool where
+
+import Data.Binary
+import Data.String.Utils
+import qualified Data.Map as M
+import qualified Data.Set as S
+import qualified Data.ByteString.Lazy as B
+import System.Plugins
+
+import Text.Printf
+
+import Foreign.Ptr
+import Foreign.C.Types
+import Foreign.C.String
+import Foreign.StablePtr
+import Foreign.Marshal.Alloc
+
+import JVM.ClassFile
+import JVM.Converter
+
+import Harpy
+import Harpy.X86Disassembler
+
+import Mate.BasicBlocks
+import Mate.Types
+import Mate.Utilities
+
+
+getClassFile :: B.ByteString -> IO (Class Resolved)
+getClassFile path = do
+  let rpath = toString $ path `B.append` ".class"
+  parseClassFile rpath
index 48afcde650f3b81ff10b7a6862cc3e7c96ac650d..f2ead78bfb2ccc995c42c7b2a21cca9a2a2fbdfc 100644 (file)
@@ -26,6 +26,7 @@ import Mate.BasicBlocks
 import Mate.Types
 import Mate.X86CodeGen
 import Mate.Utilities
+import Mate.ClassPool
 
 
 foreign import ccall "get_mmap"
@@ -47,7 +48,7 @@ getMethodEntry signal_from ptr_mmap ptr_cmap = do
   let w32_from = fromIntegral signal_from
   let mi@(MethodInfo method cm sig) = cmap M.! w32_from
   -- TODO(bernhard): replace parsing with some kind of classpool
-  cls <- parseClassFile $ toString $ cm `B.append` ".class"
+  cls <- getClassFile cm
   case M.lookup mi mmap of
     Nothing -> do
       printf "getMethodEntry(from 0x%08x): no method \"%s\" found. compile it\n" w32_from (show mi)
@@ -109,7 +110,7 @@ compileBB hmap methodinfo = do
   cmap <- get_cmap >>= ptr2cmap
 
   -- TODO(bernhard): replace parsing with some kind of classpool
-  cls <- parseClassFile $ toString $ (cName methodinfo) `B.append` ".class"
+  cls <- getClassFile (cName methodinfo)
   let ebb = emitFromBB cls hmap
   (_, Right ((entry, _, _, new_cmap), disasm)) <- runCodeGen ebb () ()
   let w32_entry = ((fromIntegral $ ptrToIntPtr entry) :: Word32)
index 2355acdb9266edb77d4a760d4140fd178298f5ed..a28e4bb50d72b1fa67d6caff9639e8e478a54ba1 100644 (file)
@@ -25,6 +25,7 @@ import Harpy.X86Disassembler
 import Mate.BasicBlocks
 import Mate.Types
 import Mate.Utilities
+import Mate.ClassPool
 
 foreign import ccall "dynamic"
    code_int :: FunPtr (CInt -> CInt -> IO CInt) -> (CInt -> CInt -> IO CInt)
@@ -47,7 +48,7 @@ foreign import ccall "set_cmap"
 test_01, test_02, test_03 :: IO ()
 test_01 = do
   register_signal
-  (entry, end) <- testCase "./tests/Fib.class" "fib"
+  (entry, end) <- testCase "./tests/Fib" "fib"
   let entryFuncPtr = ((castPtrToFunPtr entry) :: FunPtr (CInt -> CInt -> IO CInt))
 
   mapM_ (\x -> do
@@ -67,7 +68,7 @@ test_01 = do
 
 
 test_02 = do
-  (entry,_) <- testCase "./tests/While.class" "f"
+  (entry,_) <- testCase "./tests/While" "f"
   let entryFuncPtr = ((castPtrToFunPtr entry) :: FunPtr (CInt -> CInt -> IO CInt))
   result <- code_int entryFuncPtr 5 4
   let iresult :: Int; iresult = fromIntegral result
@@ -81,7 +82,7 @@ test_02 = do
 
 
 test_03 = do
-  (entry,_) <- testCase "./tests/While.class" "g"
+  (entry,_) <- testCase "./tests/While" "g"
   let entryFuncPtr = ((castPtrToFunPtr entry) :: FunPtr (CInt -> CInt -> IO CInt))
   result <- code_int entryFuncPtr 5 4
   let iresult :: Int; iresult = fromIntegral result
@@ -94,9 +95,9 @@ test_03 = do
   printf "result of g(4,3): %3d\t\t%s\n" iresult2 kk2
 
 
-testCase :: String -> B.ByteString -> IO (Ptr Word8, Int)
+testCase :: B.ByteString -> B.ByteString -> IO (Ptr Word8, Int)
 testCase cf method = do
-      cls <- parseClassFile cf
+      cls <- getClassFile cf
       hmap <- parseMethod cls method
       printMapBB hmap
       case hmap of
diff --git a/tests/Static1.java b/tests/Static1.java
new file mode 100644 (file)
index 0000000..5bd8589
--- /dev/null
@@ -0,0 +1,16 @@
+package tests;
+
+public class Static1 {
+       public static int a;
+       public static int b;
+
+       public static void main(String []args) {
+               Static1.a = 0x11;
+               Static1.b = 0x22;
+               addnumbers();
+       }
+
+       public static int addnumbers() {
+               return Static1.a + Static1.b;
+       }
+}