refactor: store amount of arguments of a method in RawMethod
[mate.git] / Mate.hs
1 {-# LANGUAGE CPP #-}
2 {-# LANGUAGE OverloadedStrings #-}
3 #include "debug.h"
4 module Main where
5
6 import System.Environment
7 import Data.Char
8 import Data.List
9 import Data.List.Split
10 import qualified Data.ByteString.Lazy as B
11 import Control.Monad
12
13 #ifdef DEBUG
14 import Text.Printf
15 #endif
16 import JVM.ClassFile
17 import Java.JAR
18
19 import Mate.BasicBlocks
20 import Mate.MethodPool
21 import Mate.Types
22 import Mate.ClassPool
23 import Mate.X86TrapHandling
24
25 main ::  IO ()
26 main = do
27   args <- getArgs
28   register_signal
29   parseArgs args False
30
31 parseArgs :: [String] -> Bool -> IO ()
32 parseArgs ("-jar":jarpath:_) stdcp = do
33   unless stdcp $ addClassPath "./"
34   addClassPathJAR jarpath
35   res <- readMainClass jarpath
36   case res of
37     Nothing -> error "JAR: no MainClass entry found. Try to pass the jar file via -cp instead."
38     Just mc -> do
39       let bclspath = B.pack $ map (fromIntegral . ord) mc
40       cls <- getClassFile bclspath
41       executeMain bclspath cls
42 parseArgs ("-cp":cps) cpset = parseArgs ("-classpath":cps) cpset
43 parseArgs ("-classpath":cps:xs) False = do
44   let paths = splitOn ":" cps
45   mapM_ addStuff paths
46   parseArgs xs True
47     where
48       addStuff :: String -> IO ()
49       addStuff x
50         | ".jar" `isSuffixOf` x = addClassPathJAR x
51         | otherwise = addClassPath $ x ++ "/"
52 parseArgs ("-classpath":xs) _ = parseArgs ("-":xs) True -- usage
53 parseArgs (('-':_):_) _ = error "Usage: mate [-cp|-classpath <cp1:cp2:..>] [<class-file> | -jar <jar-file>]"
54 -- first argument which isn't prefixed by '-' should be a class file
55 parseArgs (clspath:_) stdcp = do
56   unless stdcp $ addClassPath "./"
57   let bclspath = B.pack $ map (fromIntegral . ord) clspath
58   cls <- getClassFile bclspath
59   executeMain bclspath cls
60 parseArgs _ _ = parseArgs ["-"] False
61
62
63 executeMain :: B.ByteString -> Class Direct -> IO ()
64 executeMain bclspath cls = do
65   let methods = classMethods cls; methods :: [Method Direct]
66   case find (\x -> methodName x == "main") methods of
67     Just m -> do
68       let mi = MethodInfo "main" bclspath $ methodSignature m
69       rawmethod <- parseMethod cls "main" $ methodSignature m
70       entry <- compileBB rawmethod mi
71       addMethodRef entry mi [bclspath]
72 #ifdef DEBUG
73       printf "executing `main' now:\n"
74 #endif
75       executeFuncPtr entry
76     Nothing -> error "main not found"