From: Bernhard Urban Date: Tue, 24 Apr 2012 15:55:55 +0000 (+0200) Subject: static initializer: execute it when loading the class file X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mate.git;a=commitdiff_plain;h=2c988ece91e165480f387e66325de0b274a840eb static initializer: execute it when loading the class file unfortunately, we have a circle dependency now, hence the file `Mate/MethodPool.hs-boot'. --- diff --git a/.gitignore b/.gitignore index 9bca9cd..e57f06e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ tags *.swp *_stub.c *_stub.h +*.hi-boot +*.o-boot diff --git a/Makefile b/Makefile index 74652f5..bbfd256 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ JAVAC := javac JAVA_FILES := $(wildcard tests/*.java) CLASS_FILES := $(JAVA_FILES:.java=.class) HS_FILES := $(wildcard Mate/*.hs) +HS_BOOT := $(wildcard Mate/*.hs-boot) O_FILES = $(shell ls Mate/*.o) $(wildcard ffi/*.o) PACKAGES_ := bytestring harpy hs-java PACKAGES := $(addprefix -package ,$(PACKAGES_)) @@ -37,6 +38,12 @@ test: mate $(CLASS_FILES) @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/Static6 | grep mainresult + @printf "should be: 0x%08x\n" 0x33 + ./$< tests/Static7 | grep mainresult + @printf "should be: 0x%08x\n" $$((0x1337 + 0x555)) + ./$< tests/Static8 | grep mainresult + @printf "should be: 0x%08x 0x%08x\n" 0x33 $$((0x1337 + 0x555)) ./$< tests/CallConv1 | grep mainresult @printf "should be: 0x%08x\n" 0x1337 ./$< tests/CallConv2 | grep mainresult @@ -48,11 +55,11 @@ test: mate $(CLASS_FILES) ffi/native.o: ffi/native.c ghc -Wall -O2 -c $< -o $@ -mate: Mate.hs ffi/trap.c $(HS_FILES) ffi/native.o +mate: Mate.hs ffi/trap.c $(HS_FILES) $(HS_BOOT) ffi/native.o ghc --make $(GHC_OPT) Mate.hs ffi/trap.c -o $@ $(GHC_LD) clean: - rm -f {Mate/,}*.hi {Mate/,ffi/,}*.o mate tests/*.class + rm -f {Mate/,}*.hi {Mate/,ffi/,}*.o Mate/*.{hi,o}-boot mate tests/*.class ghci: mate ghci $(PACKAGES) $(O_FILES) Mate.hs $(GHC_LD) diff --git a/Mate/ClassPool.hs b/Mate/ClassPool.hs index b1618ed..0a4d357 100644 --- a/Mate/ClassPool.hs +++ b/Mate/ClassPool.hs @@ -15,7 +15,10 @@ import Foreign.Marshal.Alloc import JVM.ClassFile import JVM.Converter +import Mate.BasicBlocks +import {-# SOURCE #-} Mate.MethodPool import Mate.Types +import Mate.Utilities getClassInfo :: B.ByteString -> IO ClassInfo getClassInfo path = do @@ -76,4 +79,19 @@ loadClass path = do let new_ci = ClassInfo path cfile fieldbase fieldmap let class_map' = M.insert path new_ci class_map classmap2ptr class_map' >>= set_classmap - return new_ci + -- execute class initializer + case lookupMethod "" cfile of + Just m -> do + hmap <- parseMethod cfile "" + printMapBB hmap + case hmap of + Just hmap' -> do + let mi = (MethodInfo "" path (methodSignature m)) + entry <- compileBB hmap' mi + addMethodRef entry mi [path] + printf "executing static initializer from %s now\n" (toString path) + executeFuncPtr entry + printf "static initializer from %s done\n" (toString path) + return new_ci + Nothing -> error $ "loadClass: static initializer not found (WTF?). abort" + Nothing -> return new_ci diff --git a/Mate/MethodPool.hs b/Mate/MethodPool.hs index 811d1fb..9c3c727 100644 --- a/Mate/MethodPool.hs +++ b/Mate/MethodPool.hs @@ -118,9 +118,9 @@ initMethodPool = do addMethodRef :: Word32 -> MethodInfo -> [B.ByteString] -> IO () -addMethodRef entry mi@(MethodInfo mname _ msig) clsnames = do +addMethodRef entry (MethodInfo mmname _ msig) clsnames = do mmap <- get_methodmap >>= ptr2mmap - let newmap = M.fromList $ map (\x -> ((MethodInfo mname x msig), entry)) clsnames + let newmap = M.fromList $ map (\x -> ((MethodInfo mmname x msig), entry)) clsnames let mmap' = newmap `M.union` newmap mmap2ptr mmap' >>= set_methodmap diff --git a/Mate/MethodPool.hs-boot b/Mate/MethodPool.hs-boot new file mode 100644 index 0000000..f17cfb4 --- /dev/null +++ b/Mate/MethodPool.hs-boot @@ -0,0 +1,13 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ForeignFunctionInterface #-} +module Mate.MethodPool where + +import Data.Binary +import qualified Data.ByteString.Lazy as B + +import Mate.Types + + +addMethodRef :: Word32 -> MethodInfo -> [B.ByteString] -> IO () +compileBB :: MapBB -> MethodInfo -> IO Word32 +executeFuncPtr :: Word32 -> IO () diff --git a/tests/Static6.java b/tests/Static6.java new file mode 100644 index 0000000..49913ad --- /dev/null +++ b/tests/Static6.java @@ -0,0 +1,19 @@ +package tests; + +public class Static6 { + public static int x; + public static int y; + + static { + Static6.x = 0x11; + Static6.y = 0x22; + } + + public static void main(String []args) { + addNumbers(); // 0x33 + } + + public static int addNumbers() { + return Static6.x + Static6.y; + } +} diff --git a/tests/Static7.java b/tests/Static7.java new file mode 100644 index 0000000..d587e08 --- /dev/null +++ b/tests/Static7.java @@ -0,0 +1,16 @@ +package tests; + +public class Static7 extends Static6 { + public static int x; + public static int y; + + static { + Static6.x = 0x1337; + Static6.y = 0x555; + } + + public static void main(String []args) { + addNumbers(); // 0x188c + // System.out.printf("%x\n", addNumbers()); + } +} diff --git a/tests/Static8.java b/tests/Static8.java new file mode 100644 index 0000000..1359642 --- /dev/null +++ b/tests/Static8.java @@ -0,0 +1,32 @@ +package tests; + +public class Static8 extends Static8_local { + public static int x; + public static int y; + + static { + Static8_local.x = 0x1337; + Static8_local.y = 0x555; + } + + public static void main(String []args) { + Static8.addNumbers(); // 0x188c + // System.out.printf("%x\n", Static8.addNumbers()); + } +} + +class Static8_local { + public static int x; + public static int y; + + static { + Static8_local.x = 0x11; + Static8_local.y = 0x22; + Static8_local.addNumbers(); // 0x33 + // System.out.printf("%x\n", addNumbers()); + } + + public static int addNumbers() { + return Static8_local.x + Static8_local.y; + } +}