{-# LANGUAGE CPP, ScopedTypeVariables, DoAndIfThenElse, NondecreasingIndentation, DeriveFunctor, DeriveFoldable, DeriveTraversable #-}-- | A disassembler for ByteCode objects as used by GHCi.moduleGHC.Disassembler(toBytes,disassemble,BCI(..))whereimportqualifiedData.ByteString.LazyasBSimportData.ByteString.Lazy(ByteString)importData.ByteString.Lazy.BuilderimportData.ByteString.Lazy.Builder.ExtrasimportData.Binary.GetimportData.WordimportData.IntimportData.MonoidimportData.BitsimportData.FunctorimportData.Foldable(Foldable)importData.Traversable(Traversable)#include "ghcautoconf.h"#include "rts/Bytecodes.h"-- | Converts the first @n@ bytes of this list of Words to a ByteString.toBytes::Word->[Word]->ByteStringtoBytesn=BS.take(fromIntegraln).toLazyByteString.mconcat.map(wordHost.fromIntegral)-- | Given a list of pointers, a list of literals and a ByteString containing-- byte code instructions, disassembles them into a list of byte code instructions.disassemble::forallbox.[box]->[Word]->ByteString->[BCIbox]disassembleptrslits=runGet$do-- Ignore length tag. Needs to be skipped with GHC versions with-- http://hackage.haskell.org/trac/ghc/ticket/7518 included_<-getWord16host#if SIZEOF_VOID_P == 8_<-getWord16host_<-getWord16host#endif_n<-getWord16hostnextInstwheregetLiteral::GetWordgetLiteral=((!!)lits).fromIntegral<$>getWord16hostgetLiterals=dop<-fromIntegral<$>getWord16hostn<-fromIntegral<$>getWord16hostreturn$taken(dropplits)getAddr::Int->boxgetAddrp=ptrs!!pgetPtr::GetboxgetPtr=getAddr.fromIntegral<$>getWord16hostnextInst::Get[BCIbox]nextInst=doe<-isEmptyifethenreturn[]elsedow<-getWord16hostletlarge=0/=w.&.0x8000letgetLarge=iflargethengetWordhostelsefromIntegral`fmap`getWord16hostletgetLargeInt=iflargethengetInthostelsefromIntegral`fmap`getInt16hosti<-casew.&.0xffofbci_STKCHECK->don<-getLargereturn$BCISTKCHECK(n+1)bci_PUSH_L->doo1<-getWord16hostreturn$BCIPUSH_Lo1bci_PUSH_LL->doo1<-getWord16hosto2<-getWord16hostreturn$BCIPUSH_LLo1o2bci_PUSH_LLL->doo1<-getWord16hosto2<-getWord16hosto3<-getWord16hostreturn$BCIPUSH_LLLo1o2o3bci_PUSH_G->dop<-getPtrreturn$BCIPUSH_Gpbci_PUSH_ALTS->dop<-getPtrreturn$BCIPUSH_ALTSpbci_PUSH_ALTS_P->dop<-getPtrreturn$BCIPUSH_ALTS_Ppbci_PUSH_ALTS_N->dop<-getPtrreturn$BCIPUSH_ALTS_Npbci_PUSH_ALTS_F->dop<-getPtrreturn$BCIPUSH_ALTS_Fpbci_PUSH_ALTS_D->dop<-getPtrreturn$BCIPUSH_ALTS_Dpbci_PUSH_ALTS_L->dop<-getPtrreturn$BCIPUSH_ALTS_Lpbci_PUSH_ALTS_V->dop<-getPtrreturn$BCIPUSH_ALTS_Vpbci_PUSH_UBX->doubx_lits<-getLiteralsreturn$BCIPUSH_UBXubx_litsbci_PUSH_APPLY_N->doreturnBCIPUSH_APPLY_Nbci_PUSH_APPLY_F->doreturnBCIPUSH_APPLY_Fbci_PUSH_APPLY_D->doreturnBCIPUSH_APPLY_Dbci_PUSH_APPLY_L->doreturnBCIPUSH_APPLY_Lbci_PUSH_APPLY_V->doreturnBCIPUSH_APPLY_Vbci_PUSH_APPLY_P->doreturnBCIPUSH_APPLY_Pbci_PUSH_APPLY_PP->doreturnBCIPUSH_APPLY_PPbci_PUSH_APPLY_PPP->doreturnBCIPUSH_APPLY_PPPbci_PUSH_APPLY_PPPP->doreturnBCIPUSH_APPLY_PPPPbci_PUSH_APPLY_PPPPP->doreturnBCIPUSH_APPLY_PPPPPbci_PUSH_APPLY_PPPPPP->doreturnBCIPUSH_APPLY_PPPPPPbci_SLIDE->dop<-getWord16hostn<-getWord16hostreturn$BCISLIDEpnbci_ALLOC_AP->don<-getWord16hostreturn$BCIALLOC_APnbci_ALLOC_AP_NOUPD->don<-getWord16hostreturn$BCIALLOC_AP_NOUPDnbci_ALLOC_PAP->doa<-getWord16hostn<-getWord16hostreturn$BCIALLOC_PAPanbci_MKAP->don<-getWord16hosts<-getWord16hostreturn$BCIMKAPnsbci_MKPAP->don<-getWord16hosts<-getWord16hostreturn$BCIMKPAPnsbci_UNPACK->don<-getWord16hostreturn$BCIUNPACKnbci_PACK->dop<-getLiteraln<-getWord16hostreturn$BCIPACKpnbci_TESTLT_I->dod<-getLargeIntt<-getLargeIntreturn$BCITESTLT_Idtbci_TESTEQ_I->dod<-getLargeIntt<-getLargeIntreturn$BCITESTEQ_Idtbci_TESTLT_W->dod<-getLarget<-getLargeIntreturn$BCITESTLT_Wdtbci_TESTEQ_W->dod<-getLarget<-getLargeIntreturn$BCITESTEQ_Wdtbci_TESTLT_F->dod<-getLarget<-getLargeIntreturn$BCITESTLT_Fdtbci_TESTEQ_F->dod<-getLarget<-getLargeIntreturn$BCITESTEQ_Fdtbci_TESTLT_D->dod<-getLarget<-getLargeIntreturn$BCITESTLT_Ddtbci_TESTEQ_D->dod<-getLarget<-getLargeIntreturn$BCITESTEQ_Ddtbci_TESTLT_P->dod<-getWord16hostt<-getLargeIntreturn$BCITESTLT_Pdtbci_TESTEQ_P->dod<-getWord16hostt<-getLargeIntreturn$BCITESTEQ_Pdtbci_CASEFAIL->doreturnBCICASEFAILbci_JMP->doreturnBCIJMPbci_CCALL->dop<-getLiteralreturn$BCICCALLpbci_SWIZZLE->dop<-getWord16hostn<-getInt16hostreturn$BCISWIZZLEpnbci_ENTER->doreturnBCIENTERbci_RETURN->doreturnBCIRETURNbci_RETURN_P->doreturnBCIRETURN_Pbci_RETURN_N->doreturnBCIRETURN_Nbci_RETURN_F->doreturnBCIRETURN_Fbci_RETURN_D->doreturnBCIRETURN_Dbci_RETURN_L->doreturnBCIRETURN_Lbci_RETURN_V->doreturnBCIRETURN_Vbci_BRK_FUN->do_<-getWord16host_<-getWord16host_<-getWord16hostreturnBCIBRK_FUNx->error$"Unknown opcode "++showx(i:)`fmap`nextInst-- | The various byte code instructions that GHCi supports.dataBCIbox=BCISTKCHECKWord|BCIPUSH_LWord16|BCIPUSH_LLWord16Word16|BCIPUSH_LLLWord16Word16Word16|BCIPUSH_Gbox|BCIPUSH_ALTSbox|BCIPUSH_ALTS_Pbox|BCIPUSH_ALTS_Nbox|BCIPUSH_ALTS_Fbox|BCIPUSH_ALTS_Dbox|BCIPUSH_ALTS_Lbox|BCIPUSH_ALTS_Vbox|BCIPUSH_UBX[Word]|BCIPUSH_APPLY_N|BCIPUSH_APPLY_F|BCIPUSH_APPLY_D|BCIPUSH_APPLY_L|BCIPUSH_APPLY_V|BCIPUSH_APPLY_P|BCIPUSH_APPLY_PP|BCIPUSH_APPLY_PPP|BCIPUSH_APPLY_PPPP|BCIPUSH_APPLY_PPPPP|BCIPUSH_APPLY_PPPPPP/*|BCIPUSH_APPLY_PPPPPPP*/|BCISLIDEWord16Word16|BCIALLOC_APWord16|BCIALLOC_AP_NOUPDWord16|BCIALLOC_PAPWord16Word16|BCIMKAPWord16Word16|BCIMKPAPWord16Word16|BCIUNPACKWord16|BCIPACKWordWord16|BCITESTLT_IIntInt|BCITESTEQ_IIntInt|BCITESTLT_FWordInt|BCITESTEQ_FWordInt|BCITESTLT_DWordInt|BCITESTEQ_DWordInt|BCITESTLT_PWord16Int|BCITESTEQ_PWord16Int|BCICASEFAIL|BCIJMP|BCICCALLWord|BCISWIZZLEWord16Int16|BCIENTER|BCIRETURN|BCIRETURN_P|BCIRETURN_N|BCIRETURN_F|BCIRETURN_D|BCIRETURN_L|BCIRETURN_V|BCIBRK_FUN-- ^ We do not parse this opcode's arguments|BCITESTLT_WWordInt|BCITESTEQ_WWordIntderiving(Show,Functor,Traversable,Foldable)getInthost::GetIntgetInthost=fromIntegral<$>getWordhostgetInt16host::GetInt16getInt16host=fromIntegral<$>getWord16host