diff --git a/src/JVM/Data/Analyse/StackMap.hs b/src/JVM/Data/Analyse/StackMap.hs index bf33621..b61c574 100644 --- a/src/JVM/Data/Analyse/StackMap.hs +++ b/src/JVM/Data/Analyse/StackMap.hs @@ -86,8 +86,8 @@ analyseBlockDiff current block = foldl' (flip analyseInstruction) current (takeW if i > genericLength ba.locals then error $ "ILoad index out of bounds. Given: " <> show i <> " Locals: " <> show ba.locals else ba{stack = lvToStackEntry (ba.locals !! fromIntegral i) : ba.stack} - analyseInstruction (AStore i) ba = ba{locals = replaceAtOrGrow (fromIntegral (i - 1)) (stackEntryToLV $ head ba.stack) ba.locals, stack = tail ba.stack} - analyseInstruction (IStore i) ba = ba{locals = replaceAtOrGrow (fromIntegral (i - 1)) (stackEntryToLV $ head ba.stack) ba.locals, stack = tail ba.stack} + analyseInstruction (AStore i) ba = ba{locals = replaceAtOrGrow (fromIntegral i) (stackEntryToLV $ head ba.stack) ba.locals, stack = tail ba.stack} + analyseInstruction (IStore i) ba = ba{locals = replaceAtOrGrow (fromIntegral i) (stackEntryToLV $ head ba.stack) ba.locals, stack = tail ba.stack} analyseInstruction AReturn ba = ba{stack = tail ba.stack} analyseInstruction Return ba = ba analyseInstruction (LDC (LDCInt _)) ba = ba{stack = StackEntry (PrimitiveFieldType Int) : ba.stack} diff --git a/test/Analyse.hs b/test/Analyse.hs index 69e6fa9..288202b 100644 --- a/test/Analyse.hs +++ b/test/Analyse.hs @@ -49,6 +49,29 @@ genFieldType = spec :: Spec spec = describe "Analysis checks" $ do describe "Does StackDiff concatenation correctly" $ do + it "Can identify incredibly simple blocks properly" $ do + let (_, code) = runCodeBuilder $ do + emit $ LDC (LDCInt 0) -- [0] + emit $ AStore 0 + emit $ ALoad 0 + emit AReturn + + hedgehog $ do + let blocks = splitIntoBasicBlocks code + + blocks + === [ BasicBlock 0 [LDC (LDCInt 0), AStore 0, ALoad 0, AReturn] Nothing + ] + + let top = topFrame (MethodDescriptor [] (TypeReturn (PrimitiveFieldType Int))) + let nextFrame = analyseBlockDiff top (head blocks) + + nextFrame + === Frame + { locals = [LocalVariable (PrimitiveFieldType Int)] + , stack = [] + } + it "Can identify sameframe blocks properly" $ do let (l, _, code) = runCodeBuilder' $ do label <- newLabel @@ -93,24 +116,24 @@ spec = describe "Analysis checks" $ do let (l, _, code) = runCodeBuilder' $ do label <- newLabel emit $ LDC (LDCInt 0) -- [0] - emit $ IStore 1 -- [] + emit $ IStore 0 -- [] emit $ LDC (LDCInt 0) -- [0] - emit $ IStore 2 -- [] - emit $ ILoad 1 -- [0] + emit $ IStore 1 -- [] + emit $ ILoad 0 -- [0] emit $ IfLe label -- [] emit $ LDC (LDCInt 0) -- [0] - emit $ IStore 3 -- [] + emit $ IStore 2 -- [] emit $ Label label -- [] emit $ LDC (LDCInt 0) -- [0] - emit $ IStore 3 -- [] + emit $ IStore 2 -- [] emit Return -- [] pure label hedgehog $ do let blocks = splitIntoBasicBlocks code blocks - === [ BasicBlock 0 [LDC (LDCInt 0), IStore 1, LDC (LDCInt 0), IStore 2, ILoad 1, IfLe l, LDC (LDCInt 0), IStore 3] (Just l) - , BasicBlock 1 [LDC (LDCInt 0), IStore 3, Return] Nothing + === [ BasicBlock 0 [LDC (LDCInt 0), IStore 0, LDC (LDCInt 0), IStore 1, ILoad 0, IfLe l, LDC (LDCInt 0), IStore 2] (Just l) + , BasicBlock 1 [LDC (LDCInt 0), IStore 2, Return] Nothing ] let top = topFrame (MethodDescriptor [] VoidReturn)