static methods: add inheritance capability
authorBernhard Urban <lewurm@gmail.com>
Tue, 24 Apr 2012 09:10:42 +0000 (11:10 +0200)
committerBernhard Urban <lewurm@gmail.com>
Tue, 24 Apr 2012 09:11:48 +0000 (11:11 +0200)
if the method isn't found when compiling, check the superclasses for
this certain method. if one is found eventually, add an map entry
for each class to the same method entry.

see tests/Static5.java

Makefile
Mate.hs
Mate/MethodPool.hs
tests/Static5.java [new file with mode: 0644]

index 38fee4449cdec32e21b4fc6d70b6dc6e3875b0a0..74652f5cac55276a79e7beb7db0c38dedd20af14 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -35,6 +35,8 @@ test: mate $(CLASS_FILES)
        @printf "should be:  0x%08x\n" 0x6dd
        ./$< tests/Static4 | grep mainresult
        @printf "should be:  0x%08x 0x%08x\n" 0x33 0x77
+       ./$< tests/Static5 | grep mainresult
+       @printf "should be:  0x%08x 0x%08x\n" 0x33 0x33
        ./$< tests/CallConv1 | grep mainresult
        @printf "should be:  0x%08x\n" 0x1337
        ./$< tests/CallConv2 | grep mainresult
diff --git a/Mate.hs b/Mate.hs
index 946b6921893c0f32dce67c3010f7bbcd1350b041..eb7c76529dbc3bf31ea2758b7a5793dc6c2d58cb 100644 (file)
--- a/Mate.hs
+++ b/Mate.hs
@@ -35,7 +35,9 @@ main = do
           let method = find (\x -> (methodName x) == "main") methods
           case method of
             Just m -> do
-              entry <- compileBB hmap' (MethodInfo "main" bclspath (methodSignature m))
+              let mi = (MethodInfo "main" bclspath (methodSignature m))
+              entry <- compileBB hmap' mi
+              addMethodRef entry mi [bclspath]
               printf "executing `main' now:\n"
               executeFuncPtr entry
             Nothing -> error "main not found"
index c76cf914b553cdafd052feac883b439ee88588d9..811d1fb7cc678d084fb9d62d1dbf395dbf27b755 100644 (file)
@@ -6,6 +6,7 @@ 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
@@ -44,18 +45,19 @@ getMethodEntry signal_from ptr_mmap ptr_tmap = do
         Nothing -> do
           cls <- getClassFile cm
           printf "getMethodEntry(from 0x%08x): no method \"%s\" found. compile it\n" w32_from (show mi')
-          let mm = lookupMethod method cls
+          mm <- lookupMethodRecursive method [] cls
           case mm of
-            Just mm' -> do
+            Just (mm', clsnames, cls') -> do
                 let flags = methodAccessFlags mm'
                 case S.member ACC_NATIVE flags of
                   False -> do
-                    hmap <- parseMethod cls method
+                    hmap <- parseMethod cls' method
                     printMapBB hmap
                     case hmap of
                       Just hmap' -> do
-                        entry <- compileBB hmap' mi'
-                        return $ fromIntegral $ ((fromIntegral $ ptrToIntPtr entry) :: Word32)
+                        entry <- compileBB hmap' (MethodInfo method (thisClass cls') sig)
+                        addMethodRef entry mi' clsnames
+                        return $ fromIntegral entry
                       Nothing -> error $ (show method) ++ " not found. abort"
                   True -> do
                     let symbol = (replace "/" "_" $ toString cm) ++ "__" ++ (toString method) ++ "__" ++ (replace "(" "_" (replace ")" "_" $ toString $ encode sig))
@@ -69,6 +71,22 @@ getMethodEntry signal_from ptr_mmap ptr_tmap = do
         Just w32 -> return (fromIntegral w32)
     _ -> error $ "getMethodEntry: no trapInfo. abort"
 
+lookupMethodRecursive :: B.ByteString -> [B.ByteString] -> Class Resolved
+                         -> IO (Maybe ((Method Resolved, [B.ByteString], Class Resolved)))
+lookupMethodRecursive name clsnames cls = do
+  case res of
+    Just x -> return $ Just (x, nextclsn, cls)
+    Nothing -> if thisname == "java/lang/Object"
+      then return $ Nothing
+      else do
+        supercl <- getClassFile (superClass cls)
+        lookupMethodRecursive name nextclsn supercl
+  where
+  res = lookupMethod name cls
+  thisname = thisClass cls
+  nextclsn :: [B.ByteString]
+  nextclsn = thisname:clsnames
+
 -- TODO(bernhard): UBERHAX.  ghc patch?
 foreign import ccall safe "lookupSymbol"
    c_lookupSymbol :: CString -> IO (Ptr a)
@@ -98,20 +116,24 @@ initMethodPool = do
   tmap2ptr M.empty >>= set_trapmap
   classmap2ptr M.empty >>= set_classmap
 
-compileBB :: MapBB -> MethodInfo -> IO (Ptr Word8)
-compileBB hmap methodinfo = do
+
+addMethodRef :: Word32 -> MethodInfo -> [B.ByteString] -> IO ()
+addMethodRef entry mi@(MethodInfo mname _ msig) clsnames = do
   mmap <- get_methodmap >>= ptr2mmap
+  let newmap = M.fromList $ map (\x -> ((MethodInfo mname x msig), entry)) clsnames
+  let mmap' = newmap `M.union` newmap
+  mmap2ptr mmap' >>= set_methodmap
+
+
+compileBB :: MapBB -> MethodInfo -> IO Word32
+compileBB hmap methodinfo = do
   tmap <- get_trapmap >>= ptr2tmap
 
-  -- TODO(bernhard): replace parsing with some kind of classpool
   cls <- getClassFile (cName methodinfo)
   let ebb = emitFromBB (methName methodinfo) cls hmap
   (_, Right ((entry, _, _, new_tmap), disasm)) <- runCodeGen ebb () ()
-  let w32_entry = ((fromIntegral $ ptrToIntPtr entry) :: Word32)
 
-  let mmap' = M.insert methodinfo w32_entry mmap
   let tmap' = M.union tmap new_tmap -- prefers elements in cmap
-  mmap2ptr mmap' >>= set_methodmap
   tmap2ptr tmap' >>= set_trapmap
 
   printf "disasm:\n"
@@ -122,8 +144,9 @@ compileBB hmap methodinfo = do
   -- (2) on getLine, press ctrl+c
   -- (3) `br *0x<addr>'; obtain the address from the disasm above
   -- (4) `cont' and press enter
-  return entry
+  return $ fromIntegral $ ptrToIntPtr entry
 
 
-executeFuncPtr :: Ptr Word8 -> IO ()
-executeFuncPtr entry = code_void $ ((castPtrToFunPtr entry) :: FunPtr (IO ()))
+executeFuncPtr :: Word32 -> IO ()
+executeFuncPtr entry =
+  code_void $ ((castPtrToFunPtr $ intPtrToPtr $ fromIntegral entry) :: FunPtr (IO ()))
diff --git a/tests/Static5.java b/tests/Static5.java
new file mode 100644 (file)
index 0000000..14c41d4
--- /dev/null
@@ -0,0 +1,13 @@
+package tests;
+
+public class Static5 extends Static1 {
+       public static int x;
+       public static int y;
+
+       public static void main(String []args) {
+               Static5.setNumbers();
+               Static5.addNumbers(); // 0x33
+               Static1.addNumbers(); // 0x33
+               // System.out.printf("%x\n", Static5.addNumbers());
+       }
+}