From a82f30acddd8106364e8f22051cc26899028841f Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Mon, 23 Apr 2012 22:38:00 +0200 Subject: [PATCH] classpool: copy field members refs from superclass --- Makefile | 2 ++ Mate/ClassPool.hs | 27 +++++++++++++++++---------- Mate/Types.hs | 2 +- tests/Static1.java | 8 ++++++-- tests/Static2.java | 2 +- tests/Static3.java | 26 ++++++++++++++++++++++++++ 6 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 tests/Static3.java diff --git a/Makefile b/Makefile index 82ff90a..4346835 100644 --- a/Makefile +++ b/Makefile @@ -32,6 +32,8 @@ test: mate $(CLASS_FILES) @printf "should be: 0x%08x\n" 0x33 ./$< tests/Static2 | grep mainresult @printf "should be: 0x%08x\n" 0x55 + ./$< tests/Static3 | grep mainresult + @printf "should be: 0x%08x\n" 0x6dd %.class: %.java $(JAVAC) $< diff --git a/Mate/ClassPool.hs b/Mate/ClassPool.hs index eb97e21..b1618ed 100644 --- a/Mate/ClassPool.hs +++ b/Mate/ClassPool.hs @@ -30,6 +30,8 @@ getClassFile path = do (ClassInfo _ cfile _ _) <- getClassInfo path return cfile +-- TODO(bernhard): I think we don't need that anymore. also remove fieldbase +-- entry in ClassInfo getFieldBase :: B.ByteString -> IO (CUInt) getFieldBase path = do (ClassInfo _ _ fs _) <- getClassInfo path @@ -48,24 +50,29 @@ getFieldAddr from ptr_trapmap = do let sfi = trapmap M.! w32_from case sfi of (SFI (StaticFieldInfo cls field)) -> do - off <- getFieldOffset cls field - base <- getFieldBase cls - return $ base + off + getFieldOffset cls field _ -> error $ "getFieldAddr: no trapInfo. abort" loadClass :: B.ByteString -> IO ClassInfo loadClass path = do - ptr_classmap <- get_classmap - class_map <- ptr2classmap ptr_classmap + printf "loadClass: \"%s\"\n" $ toString path let rpath = toString $ path `B.append` ".class" cfile <- parseClassFile rpath - printf "class fieldlength: %d\n" $ classFieldsCount cfile + superclass <- case (path /= "java/lang/Object") of + True -> do + sc <- loadClass $ superClass cfile + return $ Just $ sc + False -> return $ Nothing + class_map <- get_classmap >>= ptr2classmap -- TODO(bernhard): correct sizes. int only atm let filteredfields = filter (S.member ACC_STATIC . fieldAccessFlags) (classFields cfile) - let fm = zipWith (\x y -> (fieldName y, x)) [0,4..] filteredfields - let fieldmap = M.fromList fm - fieldbase <- mallocBytes ((fromIntegral $ M.size fieldmap) * 4) - putStrLn $ "fieldmap: " ++ (show fieldmap) + fieldbase <- mallocBytes ((fromIntegral $ length filteredfields) * 4) + let i_fb = fromIntegral $ ptrToIntPtr $ fieldbase + let fm = zipWith (\x y -> (fieldName y, x + i_fb)) [0,4..] filteredfields + let sc_fm = case superclass of Just x -> clFieldMap x; Nothing -> M.empty + -- new fields "overwrite" old ones, if they have the same name + let fieldmap = (M.fromList fm) `M.union` sc_fm + printf "fieldmap: %s @ %s\n" (show fieldmap) (toString path) let new_ci = ClassInfo path cfile fieldbase fieldmap let class_map' = M.insert path new_ci class_map classmap2ptr class_map' >>= set_classmap diff --git a/Mate/Types.hs b/Mate/Types.hs index 6918084..130c293 100644 --- a/Mate/Types.hs +++ b/Mate/Types.hs @@ -49,7 +49,7 @@ type FieldMap = M.Map B.ByteString Int32 data ClassInfo = ClassInfo { clName :: B.ByteString, clFile :: Class Resolved, - clField :: Ptr Int32, + clFieldBase :: Ptr Int32, clFieldMap :: FieldMap } data MethodInfo = MethodInfo { diff --git a/tests/Static1.java b/tests/Static1.java index 726da7d..74ca4fd 100644 --- a/tests/Static1.java +++ b/tests/Static1.java @@ -5,12 +5,16 @@ public class Static1 { public static int y; public static void main(String []args) { + setNumbers(); + addNumbers(); // 0x33 + } + + public static void setNumbers() { Static1.x = 0x11; Static1.y = 0x22; - addnumbers(); } - public static int addnumbers() { + public static int addNumbers() { return Static1.x + Static1.y; } } diff --git a/tests/Static2.java b/tests/Static2.java index 874360d..cfc85dc 100644 --- a/tests/Static2.java +++ b/tests/Static2.java @@ -11,6 +11,6 @@ public class Static2 { // in Static2 as in Static1 Static1.x = 0x33; Static1.y = 0x22; - Static1.addnumbers(); + Static1.addNumbers(); } } diff --git a/tests/Static3.java b/tests/Static3.java new file mode 100644 index 0000000..a5a732c --- /dev/null +++ b/tests/Static3.java @@ -0,0 +1,26 @@ +package tests; + +public class Static3 extends Static1 { + public static int z; + public static int sum; + public static void main(String []args) { + sum = 0; + Static3.x = 0x111; + Static3.y = 0x555; + sum += Static1.addNumbers(); // 0x666 + Static1.setNumbers(); + sum += Static1.addNumbers(); // 0x33 + Static3.z = 0x11; + sum += Static3.addNumbers(); // 0x44 + getSum(); // 0x666 + 0x33 + 0x44 = 0x6dd + // System.out.printf("%x\n", getSum()); + } + + public static int getSum() { + return sum; + } + + public static int addNumbers() { + return x + y + z; + } +} -- 2.25.1