mò &U²Ic@sdZdkZdkZdkZdkZdklZdklZl Z l Z l Z dfd„ƒYZ d„Z dfd„ƒYZd Zd Zd Zd Zd e fd„ƒYZd„Zdfd„ƒYZd„Zd„Zdfd„ƒYZdfd„ƒYZeƒiZdS(s/A flow graph representation for Python bytecodeN(smisc(s CO_OPTIMIZEDs CO_NEWLOCALSs CO_VARARGSsCO_VARKEYWORDSt FlowGraphcBs˜tZd„Zd„Zdd„Zd„Zd„ZdZd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„ZRS(NcCs[tƒ|_|_tdƒ|_tiƒ|_|ii|iƒ|ii|iƒdS(Ntexit( tBlocktselftcurrenttentryRtmisctSettblockstadd(R((t-/data/zmath/lib/python2.4/compiler/pyassem.pyt__init__ s cCsg|ioP|io7dGt|iƒGHdG|iiGHdG|iiƒGHnt|ƒGHn||_dS(Ntends nexts (Rt_debugRtreprtnextt get_childrentblock(RR((R t startBlocks  cCs>|djo|iƒ}n|ii|ƒ|i|ƒdS(N(RtNoneRtnewBlockRtaddNextR(RR((R t nextBlocks  cCstƒ}|ii|ƒ|S(N(RtbRRR (RR((R R6s cCs|i|iƒdS(N(RRR(R((R tstartExitBlock;sicCs d|_dS(Ni(RR (R((R t _enable_debug@scCs d|_dS(Ni(RR (R((R t_disable_debugCscGs˜|io dG|GHn|dddgjo|ii|iƒnt|ƒdjo,t|dtƒo|ii|dƒn|ii |ƒdS(Ns it RETURN_VALUEt YIELD_VALUEii( RR tinstRt addOutEdgeRtlent isinstanceRtemit(RR((R R!Fs  'cCs¦xL|iiƒD];}||ijoqn|ip|i|iƒqqWt|ihƒ}|i ƒ|i ||iƒ|i|jo|i |iƒn|S(slReturn the blocks in reverse postorder i.e. each node appears before all of its successors N( RRtelementsRRRRt dfs_postorderRtordertreverset fixupOrdertappend(RRR$((R tgetBlocksInOrderOs  cCs$|i||ƒ|i||ƒdS(s"Fixup bad order introduced by DFS.N(RtfixupOrderHonorNextRt default_nexttfixupOrderForward(RRR*((R R&dsc Cs«h}x(tt|ƒƒD]}|||||iƒD]0}|i|ƒoqn|t||ƒ}qW|i|ƒ|S(s;Depth-first search of tree rooted at b, return in postorderN(R$RtseenRR9thas_keyR#R'(RRFR9R$((R R#Ñs   RcBsztZdZdd„Zd„Zd„Zd„Zd„Zd„Zd „Z d „Z dZ d„Z d„Z d„ZRS(NitcCsYg|_tiƒ|_tiƒ|_||_ti|_ g|_ tidt_dS(Ni( RR;RRtinEdgestoutEdgestlabelRt_counttbidR(RRK((R R ßs    cCs1|iod|i|ifSn d|iSdS(Nss (RRKRM(R((R t__repr__ès cCs2tt|iƒ}d|i|idi|ƒfS(Nss (tmaptstrRR;RKRMtjoin(RR;((R t__str__îscCsG|d}|d djo|ii|dƒn|ii|ƒdS(NiitJUMPi(RtopRRJR R;R'(RRRT((R R!ós cCs|iS(N(RR;(R((R tgetInstructionsùscCs|ii|ƒdS(N(RRIR R(RR((R t addInEdgeüscCs|ii|ƒdS(N(RRJR R(RR((R RÿscCs|ii|ƒdS(N(RRR'R(RR((R RsRt RAISE_VARARGSRt JUMP_ABSOLUTER6t CONTINUE_LOOPcCsXy|id\}}Wnttfj o dSnX||ijo g|_ndS(sLRemove bogus edge for unconditional transfers Each block has a next edge that accounts for implicit control transfers, e.g. from a JUMP_IF_FALSE to the block that will be executed if the test is true. These edges must remain for the current assembler code to work. If they are removed, the dfs_postorder gets things in weird orders. However, they shouldn't be there for other purposes, e.g. conversion to SSA form. This method will remove the next edge when it follows an unconditional control transfer. iÿÿÿÿN(RR;RTtargt IndexErrort ValueErrort_uncond_transferR(RRZRT((R t pruneNext s  cCsP|io2|id|ijo|ii|idƒn|iiƒ|iS(Ni(RRRJR>R"(R((R Rs!cCsfg}xY|iD]N}t|ƒdjoqn|d}t|dƒo|i|iƒqqW|S(s¨Return all graphs contained within this block. For example, a MAKE_FUNCTION block will contain a reference to the graph for the function body. itgraphN( t containedRR;RRRTthasattrR'R_(RR`RRT((R RC#s  (s RETURN_VALUERWs YIELD_VALUERXs JUMP_FORWARDRY(RDRERLR RNRRR!RURVRRR]R^RRC(((R RÜs         tRAWtFLATtCONVtDONEt PyFlowGraphcBsItZeiZfddd„Zd„Zd„Zd„Zd„Z d„Z d„Z dd „Z d „Z d „ZeiƒZx%eiD]Zeieieƒq‹WeiƒZx%eiD]Zeieieƒq¿Wd „Zd „Zd„ZhZd„Zd„ZeZeZd„Zd„Z e Z!e Z"e Z#e Z$e Z%e Z&e Z'e Z(e Z)e Z*d„Z+e+Z,e+Z-d„Z.e/ei0ƒZ1d„Z2xFe3ƒi4ƒD]5\Z5Z6e5d djoe5dZe6ee|iD]3}t|tƒo|iƒ}n|i|ƒqWt|ƒS(s›Return a tuple for the const slot of the code object Must convert references to code (MAKE_FUNCTION) to code objects recursively. N( R3RRsR2R RfRŒR'RÂ(RR3R2((R RÁ_s (>RDRERR RgRRR‚RƒR„R…RŒR•R†R‡RRRŸtdisR.R R”R£RˆR¤R«R¥R¬R­t_convert_STORE_FASTt_convert_DELETE_FASTR®R¯t_convert_STORE_NAMEt_convert_DELETE_NAMEt_convert_IMPORT_NAMEt_convert_IMPORT_FROMt_convert_STORE_ATTRt_convert_LOAD_ATTRt_convert_DELETE_ATTRt_convert_LOAD_GLOBALt_convert_STORE_GLOBALt_convert_DELETE_GLOBALR°t_convert_LOAD_DEREFt_convert_STORE_DEREFR±Rxtcmp_opR²R³tlocalstitemsRhtobjR‰R¸R-RtnumRŠRÁ(((R Rf:sv         !                  cCs|d djodSndS(NiRSi(R”(R”((R tisJumplsR{cBs)tZdZd„Zd„Zd„ZRS(s:Helper for marking func defs with nested tuples in arglistcCs||_||_dS(N(tcountRRt(RRÚRt((R R rs cCsd|i|ifS(NsTupleArg(%s, %s)(RRÚRt(R((R RNuscCs d|iS(Ns.%d(RRÚ(R((R R|ws(RDREt__doc__R RNR|(((R R{ps   cCsbt|ƒ}|oKxH|D]<}t|tƒo&tti|iƒƒ}||}qqWn|S(N( RRkRmRZR R{RtflattenRttnumNames(RkRÝRmRZ((R Rlzs cCs t|dƒS(s/Convert an int argument into high and low bytesiN(tdivmodtval(Rß((R RºƒsRµcBs;tZdZd„Zd„Zd„Zd„Zd„ZRS(s(lnotab This class builds the lnotab, which is documented in compile.c. Here's a brief recap: For each SET_LINENO instruction after the first one, two bytes are added to lnotab. (In some cases, multiple two-byte entries are added.) The first byte is the distance in bytes between the instruction for the last SET_LINENO and the current SET_LINENO. The second byte is offset in line numbers. If either offset is greater than 255, multiple two-byte entries are added -- see compile.c for the delicate details. cCs:g|_d|_d|_d|_d|_g|_dS(Ni(RRÀt codeOffsetRÃtlastlinetlastoffR¶(R((R R —s      cGsAx$|D]}|iit|ƒƒqW|it|ƒ|_dS(N(RkRZRRÀR'tchrRàR(RRkRZ((R R·ŸscCs|idjo||_||_nî|i|i}||i}|djoÃ|ii }x0|djo"|dƒ|dƒ|d8}q_Wx6|djo(||ƒ|dƒ|d8}d}q’W|djp |djo||ƒ||ƒn||_|i|_ndS(Niiÿ( RRÃtlinenoRáRàRâtaddrtlineR¶R'tpush(RRäRçRæRå((R R¹¤s(         cCsdi|iƒS(NRH(RQRRÀ(R((R RŒÄscCsditt|iƒƒS(NRH(RQRORãRR¶(R((R RÄÇs(RDRERÛR R·R¹RŒRÄ(((R Rµˆs    tStackDepthTrackercBsÇtZdd„Zhdd<dd<dd<dd<d d <d d<d d <d d <dd<dd<dd <dd <dd<dd<dd <dd<dd<dd<dd<dd <dd<dd <dd<dd<dd<d d<d!d<d"d<d#d<d$d<d%d<d&d'<d(d'<d)d