Support for loading field/method signatures in Generate monad.
authorIlya V. Portnov <i.portnov@compassplus.ru>
Tue, 4 Oct 2011 05:43:58 +0000 (11:43 +0600)
committerIlya Portnov <portnov84@rambler.ru>
Wed, 5 Oct 2011 17:43:43 +0000 (23:43 +0600)
Hello.java
JVM/Builder/Monad.hs
JVM/ClassFile.hs
TestGen.hs

index 33b7645b9ad0094c3717da6db8dfa50289207da2..bf7d547bf6b263e8a5a4969619fad2a1caa0e830 100644 (file)
@@ -1,11 +1,10 @@
 public class Hello {
   public static void main(String[] args) {
-    hello(5);
+    hello();
   }
 
-  static void hello(int n) {
-    System.out.println("Здравствуй, мир!");
-    System.out.printf("Argument: %d", n);
+  static void hello() {
+    System.out.println("Hello Java world!");
   }
 }
 
index f5b1d74dbb2b081f99c8f14663502923270e830e..623a44e2c2c3a3bbd8c2e39cc2c19f06f9dd8e44 100644 (file)
@@ -9,6 +9,8 @@ module JVM.Builder.Monad
    i0, i1, i8,
    newMethod,
    setStackSize, setMaxLocals,
+   withClassPath,
+   getClassField, getClassMethod,
    generate
   ) where
 
@@ -200,6 +202,31 @@ newMethod flags name args ret gen = do
   endMethod
   return (NameType name sig)
 
+getClass :: String -> Generate (Class Direct)
+getClass name = do
+  cp <- St.gets classPath
+  res <- liftIO $ getEntry cp name
+  case res of
+    Just (NotLoaded p) -> fail $ "Class file was not loaded: " ++ p
+    Just (Loaded _ c) -> return c
+    Just (NotLoadedJAR p c) -> fail $ "Class was not loaded from JAR " ++ p ++ ": " ++ c
+    Just (LoadedJAR _ c) -> return c
+    Nothing -> fail $ "No such class in ClassPath: " ++ name
+
+getClassField :: String -> B.ByteString -> Generate (NameType Field)
+getClassField clsName fldName = do
+  cls <- getClass clsName
+  case lookupField fldName cls of
+    Just fld -> return (fieldNameType fld)
+    Nothing  -> fail $ "No such field in class " ++ clsName ++ ": " ++ toString fldName
+
+getClassMethod :: String -> B.ByteString -> Generate (NameType Method)
+getClassMethod clsName mName = do
+  cls <- getClass clsName
+  case lookupMethod mName cls of
+    Just m -> return (methodNameType m)
+    Nothing  -> fail $ "No such method in class " ++ clsName ++ ": " ++ toString mName
+
 -- | Convert Generator state to method Code.
 genCode :: GState -> Code
 genCode st = Code {
index 623585a6e1069cc3ca94ea86b23b5ae670fb80ed..02a7adaf60aec86bb253ef42cd872d020c96f4b6 100644 (file)
@@ -24,6 +24,7 @@ module JVM.ClassFile
    HasSignature (..), HasAttributes (..),
    NameType (..),
    fieldNameType, methodNameType,
+   lookupField, lookupMethod,
    toString,
    className,
    apsize, arsize, arlist
@@ -511,6 +512,14 @@ deriving instance Eq (Field Direct)
 deriving instance Show (Field File)
 deriving instance Show (Field Direct)
 
+lookupField :: B.ByteString -> Class Direct -> Maybe (Field Direct)
+lookupField name cls = look (classFields cls)
+  where
+    look [] = Nothing
+    look (f:fs)
+      | fieldName f == name = Just f
+      | otherwise           = look fs
+
 fieldNameType :: Field Direct -> NameType Field
 fieldNameType f = NameType (fieldName f) (fieldSignature f)
 
@@ -546,6 +555,14 @@ deriving instance Show (Method Direct)
 methodNameType :: Method Direct -> NameType Method
 methodNameType m = NameType (methodName m) (methodSignature m)
 
+lookupMethod :: B.ByteString -> Class Direct -> Maybe (Method Direct)
+lookupMethod name cls = look (classMethods cls)
+  where
+    look [] = Nothing
+    look (f:fs)
+      | methodName f == name = Just f
+      | otherwise           = look fs
+
 instance Binary (Method File) where
   put (Method {..}) = do
     put methodAccessFlags
index 900a422dd5778892483b970457018cfd32094ad0..0e5ff90184b7f05fea5e31c167707559e8f24554 100644 (file)
@@ -6,12 +6,18 @@ import JVM.ClassFile
 import JVM.Converter
 import JVM.Assembler
 import JVM.Builder
+import Java.ClassPath
 
 import qualified Java.Lang
 import qualified Java.IO
 
 test :: Generate ()
 test = do
+  withClassPath $ do
+      addDirectory "."
+
+  helloJava <- getClassMethod "./Hello" "hello"
+
   newMethod [ACC_PUBLIC] "<init>" [] ReturnsVoid $ do
       setStackSize 1
 
@@ -35,6 +41,7 @@ test = do
       invokeStatic Java.Lang.integer Java.Lang.valueOfInteger
       aastore
       invokeVirtual Java.IO.printStream Java.IO.printf
+      invokeStatic "Hello" helloJava
       pop
       i0 RETURN