@@ -49,6 +49,8 @@ import qualified Data.BitCode.LLVM.Flags as Flags
4949import Data.BitCode.LLVM.Opcodes.Binary as BinOp
5050import qualified Data.BitCode.LLVM.Opcodes.Cast as CastOp
5151
52+ import GHC.Stack (HasCallStack )
53+ 5254
5355-- Conceptuall we take bitcode and interpret it as LLVM IR.
5456-- This should result in a single module.
@@ -194,7 +196,7 @@ toSigned v | testBit v 0 = complement (shift v (-1))
194196 | otherwise = shift v (- 1 )
195197
196198-- | Parse constants.
197- parseConstants :: [NBitCode ] -> LLVMReader ()
199+ parseConstants :: HasCallStack => [NBitCode ] -> LLVMReader ()
198200parseConstants = foldM_ parseConstant undefined . records
199201 where parseConstant :: Ty -> (Constant ,[BC. Val ]) -> LLVMReader Ty
200202 parseConstant ty = \ case
@@ -299,16 +301,16 @@ parseMetadata = mapM_ parseMetadata . records
299301
300302-- * module codes
301303
302- parseVersion :: [BC. Val ] -> Word64
304+ parseVersion :: HasCallStack => [BC. Val ] -> Word64
303305parseVersion [v] = v
304306
305- parseTriple :: [BC. Val ] -> String
307+ parseTriple :: HasCallStack => [BC. Val ] -> String
306308parseTriple = map toEnum'
307309
308- parseDataLayout :: [BC. Val ] -> String
310+ parseDataLayout :: HasCallStack => [BC. Val ] -> String
309311parseDataLayout = map toEnum'
310312
311- parseGlobalVar :: [BC. Val ] -> LLVMReader ()
313+ parseGlobalVar :: HasCallStack => [BC. Val ] -> LLVMReader ()
312314parseGlobalVar vals
313315 | length vals < 6 = error $ " Invalid record: Global Var must have at least six operands. " ++ show vals ++ " given."
314316 | [ ptrTyId, isConst, initId, linkage, paramAttrId, section ] <- vals = do
@@ -342,12 +344,12 @@ parseGlobalVar vals
342344-- if type can not be reconstructed, invalid record.
343345-- if ty can not be cast to function type. -> invalid value
344346
345- parseFunctionDecl :: [BC. Val ] -> LLVMReader ()
347+ parseFunctionDecl :: HasCallStack => [BC. Val ] -> LLVMReader ()
346348parseFunctionDecl vals = askVersion >>= \ case
347349 1 -> parseFunctionDecl' vals
348350 2 -> parseFunctionDecl' (drop 2 vals)
349351
350- parseFunctionDecl' :: [BC. Val ] -> LLVMReader ()
352+ parseFunctionDecl' :: HasCallStack => [BC. Val ] -> LLVMReader ()
351353parseFunctionDecl'
352354 [ tyId, cconv, isProto, linkage -- 4
353355 , paramAttrId, alignment, section, visibility, gc -- 9
@@ -370,7 +372,8 @@ upgradeDLLImportExportLinkage = \case
370372 Linkage. Appending -> DLLStorageClass. DLLExport
371373 _ -> DLLStorageClass. Default
372374
373- parseAlias :: Bool -- ^ New Alias
375+ parseAlias :: HasCallStack
376+ => Bool -- ^ New Alias
374377 -> [BC. Val ] -- Values
375378 -> LLVMReader ()
376379
@@ -404,10 +407,10 @@ parseAlias True [ tyId, addrSpace, valId, linkage ]
404407 = parseAlias True [ tyId, addrSpace, valId, linkage, (fromIntegral (fromEnum Visibility. Default )) ]
405408
406409-- helper
407- toEnum' :: (Integral a , Enum e ) => a -> e
410+ toEnum' :: (HasCallStack , Integral a , Enum e ) => a -> e
408411toEnum' = toEnum . fromIntegral
409412
410- parseTopLevel :: [NBitCode ] -> LLVMReader (Maybe Ident , Module )
413+ parseTopLevel :: HasCallStack => [NBitCode ] -> LLVMReader (Maybe Ident , Module )
411414parseTopLevel bs = do
412415 ident <- case lookupBlock IDENTIFICATION bs of
413416 Just b -> Just <$> parseIdent b
@@ -417,7 +420,7 @@ parseTopLevel bs = do
417420 mod <- parseModule moduleBlock
418421 return (ident, mod )
419422
420- resolveFwdRefs :: [Symbol ] -> [Symbol ]
423+ resolveFwdRefs :: HasCallStack => [Symbol ] -> [Symbol ]
421424resolveFwdRefs ss = map (fmap' resolveFwdRef') ss
422425 where
423426 -- TODO: Maybe Symbol should be more generic? Symbol a,
@@ -433,7 +436,7 @@ resolveFwdRefs ss = map (fmap' resolveFwdRef') ss
433436 resolveFwdRef' x = x
434437
435438-- | Parse a module from a set of blocks (the body of the module)
436- parseModule :: [NBitCode ] -> LLVMReader Module
439+ parseModule :: HasCallStack => [NBitCode ] -> LLVMReader Module
437440parseModule bs = do
438441 let Just version = parseVersion <$> lookupRecord VERSION bs
439442 triple = parseTriple <$> lookupRecord TRIPLE bs
@@ -482,7 +485,7 @@ parseModule bs = do
482485 ) . zip [0 .. ]
483486
484487-- | Parse value symbol table
485- parseSymbolValueTable :: [NBitCode ] -> ValueSymbolTable
488+ parseSymbolValueTable :: HasCallStack => [NBitCode ] -> ValueSymbolTable
486489parseSymbolValueTable = foldl (\ l x -> parseSymbolValue x: l) [] . filter f . records
487490 where parseSymbolValue :: (ValueSymtabCodes , [BC. Val ]) -> (Int , ValueSymbolEntry )
488491 parseSymbolValue (VST_CODE_ENTRY , (idx: vs)) = (fromIntegral idx, Entry $ map toEnum' vs)
@@ -493,7 +496,7 @@ parseSymbolValueTable = foldl (\l x -> parseSymbolValue x:l) [] . filter f . rec
493496 f _ = False
494497
495498-- block ids
496- parseModuleBlock :: (ModuleBlockID , [NBitCode ]) -> LLVMReader ()
499+ parseModuleBlock :: HasCallStack => (ModuleBlockID , [NBitCode ]) -> LLVMReader ()
497500parseModuleBlock (id ,bs) = trace (" parseModuleBlock " ++ show id ) >> case (id ,bs) of
498501 ({- 9 -} PARAMATTR , bs) -> parseAttr bs
499502 ({- 10 -} PARAMATTR_GROUP , bs) -> parseAttrGroup bs
@@ -515,7 +518,7 @@ parseModuleBlock (id,bs) = trace ("parseModuleBlock " ++ show id) >> case (id,bs
515518 ({- 26 -} SYNC_SCOPE_NAMES , bs) -> return () -- TODO
516519 c -> fail $ " Encountered unhandled block: " ++ show c
517520
518- parseModuleRecord :: (ModuleCode , [BC. Val ]) -> LLVMReader ()
521+ parseModuleRecord :: HasCallStack => (ModuleCode , [BC. Val ]) -> LLVMReader ()
519522parseModuleRecord (id ,bs) = trace (" parseModuleRecord " ++ show id ) >> case (id ,bs) of
520523 ({- 1 -} VERSION , _) -> pure () -- ignore, it's being picked apart somewhere else.
521524 ({- 2 -} TRIPLE , _) -> pure () -- ignore
@@ -564,7 +567,7 @@ parseModuleRecord (id,bs) = trace ("parseModuleRecord " ++ show id) >> case (id,
564567-- Function bodies should come in sequence of their declaration in the GV.
565568-- prototype functions are external.
566569--
567- parseFunction :: (Symbol , [NBitCode ]) -> LLVMReader F. Function
570+ parseFunction :: HasCallStack => (Symbol , [NBitCode ]) -> LLVMReader F. Function
568571parseFunction (f@ (Named _ V. Function {.. }), b) = do
569572 -- remember the size of the value list. We need to trim it back down after
570573 -- parsing; and might want to attach the new values to the constants of the Function.
@@ -599,18 +602,22 @@ parseFunction ((Unnamed f), b) = parseFunction ((Named "dummy" f), b)
599602parseFunction _ = fail " Invalid arguments"
600603
601604
602- parseFunctionBlock :: (ModuleBlockID , [NBitCode ]) -> LLVMReader ()
605+ parseFunctionBlock :: HasCallStack => (ModuleBlockID , [NBitCode ]) -> LLVMReader ()
603606parseFunctionBlock = \ case
604607 (CONSTANTS , b) -> parseConstants b
605608 (B. METADATA , b) -> parseMetadata b
606609 (B. METADATA_ATTACHMENT_ID , b) -> trace (" Ignoring Metadata attachment: " ++ show b)
607610 (B. USELIST , b) -> trace (" Cannot parse uselist yet (" ++ show b ++ " )" ) >> return ()
608611 _ -> pure ()
609612
610- getRelativeVal :: (Integral a ) => [Symbol ] -> a -> LLVMReader Symbol
613+ getRelativeVal :: (HasCallStack , Integral a ) => [Symbol ] -> a -> LLVMReader Symbol
611614getRelativeVal refs n = do
612615 valueList <- askValueList
613- pure $ reverse (valueList ++ refs) !! (fromIntegral n - 1 )
616+ let lst = reverse (valueList ++ refs)
617+ idx = fromIntegral n - 1
618+ if idx < 0 || idx > length lst
619+ then fail $ " index " ++ (show idx) ++ " out of range [0, " ++ show (length lst) ++ " ) of avaliable relative values."
620+ else pure (lst !! idx)
614621
615622
616623-- TODO: filter out the `FUNC_CODE_DECLAREBLOCKS` in
@@ -630,7 +637,7 @@ foldHelper s@((BasicBlock insts):bbs,vs) instr = do
630637 True -> return ((BasicBlock [] ): bbs', vs')
631638 False -> return (bbs', vs')
632639
633- parseInst :: [Symbol ] -> (Instruction , [BC. Val ]) -> LLVMReader (Maybe Inst )
640+ parseInst :: HasCallStack => [Symbol ] -> (Instruction , [BC. Val ]) -> LLVMReader (Maybe Inst )
634641parseInst rs = \ case
635642 -- 1
636643 (DECLAREBLOCKS , x) | length x == 0 -> error " Invalid record: DECLAREBLOCKS must not be empty!"
@@ -728,7 +735,9 @@ parseInst rs = \case
728735 -- (INST_STORE_OLD [ ptrty, ptr, val, align, vol])
729736 -- 25 - Unused
730737 -- 26
731- -- (INST_EXTRACTVAL, ops)
738+ (INST_EXTRACTVAL , (op: idxs)) -> do
739+ val <- getRelativeVal rs op
740+ return . Just $ ExtractValue val idxs
732741 -- 27
733742 -- (INST_INSERTVAL, ops)
734743 -- 28
0 commit comments