+loadInterface :: B.ByteString -> IO ()
+loadInterface path = do
+ imap <- get_interfacesmap >>= ptr2interfacesmap
+ -- interface already loaded?
+ case M.lookup path imap of
+ Just _ -> return ()
+ Nothing -> do
+#ifdef DEBUG
+ printf "interface: loading \"%s\"\n" $ toString path
+#endif
+ let ifpath = toString $ path `B.append` ".class"
+ cfile <- parseClassFile ifpath
+ -- load "superinterfaces" first
+ sequence_ [ loadInterface i | i <- interfaces cfile ]
+ immap <- get_interfacemethodmap >>= ptr2interfacemethodmap
+
+ -- load map again, because there could be new entries now
+ -- due to loading superinterfaces
+ imap' <- get_interfacesmap >>= ptr2interfacesmap
+ let max_off = fromIntegral $ (M.size immap) * 4
+ -- create index of methods by this interface
+ let mm = zipbase max_off (classMethods cfile)
+
+ -- create for each method from *every* superinterface a entry to,
+ -- but just put in the same offset as it is already in the map
+ let (ifnames, methodnames) = unzip $ concat $
+ [ zip (repeat ifname) (classMethods $ imap' M.! ifname)
+ | ifname <- interfaces cfile ]
+ let sm = zipWith (\x y -> (entry y, immap M.! (getname x y))) ifnames methodnames
+
+ -- merge all offset tables
+ let methodmap = (M.fromList sm) `M.union` (M.fromList mm) `M.union` immap
+ interfacemethodmap2ptr methodmap >>= set_interfacemethodmap
+
+ interfacesmap2ptr (M.insert path cfile imap') >>= set_interfacesmap
+ where
+ zipbase base = zipWith (\x y -> (entry y, x + base)) [0,4..]
+ entry = getname path
+ getname p y = p `B.append` (methodName y) `B.append` (encode $ methodSignature y)
+
+