home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_324 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  22.2 KB  |  835 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import dis
  5. import types
  6. import sys
  7. from compiler import misc
  8. from compiler.consts import CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS
  9.  
  10. class FlowGraph:
  11.     
  12.     def __init__(self):
  13.         self.current = self.entry = Block()
  14.         self.exit = Block('exit')
  15.         self.blocks = misc.Set()
  16.         self.blocks.add(self.entry)
  17.         self.blocks.add(self.exit)
  18.  
  19.     
  20.     def startBlock(self, block):
  21.         if self._debug:
  22.             if self.current:
  23.                 print 'end', repr(self.current)
  24.                 print '    next', self.current.next
  25.                 print '   ', self.current.get_children()
  26.             
  27.             print repr(block)
  28.         
  29.         self.current = block
  30.  
  31.     
  32.     def nextBlock(self, block = None):
  33.         if block is None:
  34.             block = self.newBlock()
  35.         
  36.         self.current.addNext(block)
  37.         self.startBlock(block)
  38.  
  39.     
  40.     def newBlock(self):
  41.         b = Block()
  42.         self.blocks.add(b)
  43.         return b
  44.  
  45.     
  46.     def startExitBlock(self):
  47.         self.startBlock(self.exit)
  48.  
  49.     _debug = 0
  50.     
  51.     def _enable_debug(self):
  52.         self._debug = 1
  53.  
  54.     
  55.     def _disable_debug(self):
  56.         self._debug = 0
  57.  
  58.     
  59.     def emit(self, *inst):
  60.         if self._debug:
  61.             print '\t', inst
  62.         
  63.         if inst[0] in ('RETURN_VALUE', 'YIELD_VALUE'):
  64.             self.current.addOutEdge(self.exit)
  65.         
  66.         if len(inst) == 2 and isinstance(inst[1], Block):
  67.             self.current.addOutEdge(inst[1])
  68.         
  69.         self.current.emit(inst)
  70.  
  71.     
  72.     def getBlocksInOrder(self):
  73.         for b in self.blocks.elements():
  74.             if b is self.exit:
  75.                 continue
  76.             
  77.             if not b.next:
  78.                 b.addNext(self.exit)
  79.                 continue
  80.         
  81.         order = dfs_postorder(self.entry, { })
  82.         order.reverse()
  83.         self.fixupOrder(order, self.exit)
  84.         if self.exit not in order:
  85.             order.append(self.exit)
  86.         
  87.         return order
  88.  
  89.     
  90.     def fixupOrder(self, blocks, default_next):
  91.         self.fixupOrderHonorNext(blocks, default_next)
  92.         self.fixupOrderForward(blocks, default_next)
  93.  
  94.     
  95.     def fixupOrderHonorNext(self, blocks, default_next):
  96.         index = { }
  97.         for i in range(len(blocks)):
  98.             index[blocks[i]] = i
  99.         
  100.         for i in range(0, len(blocks) - 1):
  101.             b = blocks[i]
  102.             n = blocks[i + 1]
  103.             if not (b.next) and b.next[0] == default_next or b.next[0] == n:
  104.                 continue
  105.             
  106.             cur = b
  107.             chain = []
  108.             elt = cur
  109.             while elt.next and elt.next[0] != default_next:
  110.                 chain.append(elt.next[0])
  111.                 elt = elt.next[0]
  112.             l = []
  113.             for b in chain:
  114.                 l.append((index[b], b))
  115.             
  116.             l.sort()
  117.             l.reverse()
  118.             for j, b in l:
  119.                 del blocks[index[b]]
  120.             
  121.             blocks[i:i + 1] = [
  122.                 cur] + chain
  123.             for i in range(len(blocks)):
  124.                 index[blocks[i]] = i
  125.             
  126.         
  127.  
  128.     
  129.     def fixupOrderForward(self, blocks, default_next):
  130.         index = { }
  131.         chains = []
  132.         cur = []
  133.         for b in blocks:
  134.             index[b] = len(chains)
  135.             cur.append(b)
  136.             if b.next and b.next[0] == default_next:
  137.                 chains.append(cur)
  138.                 cur = []
  139.                 continue
  140.         
  141.         chains.append(cur)
  142.         while None:
  143.             constraints = []
  144.             for i in range(len(chains)):
  145.                 l = chains[i]
  146.                 for b in l:
  147.                     for c in b.get_children():
  148.                         if index[c] < i:
  149.                             forward_p = 0
  150.                             for inst in b.insts:
  151.                                 if inst[0] == 'JUMP_FORWARD':
  152.                                     if inst[1] == c:
  153.                                         forward_p = 1
  154.                                     
  155.                                 inst[1] == c
  156.                             
  157.                             if not forward_p:
  158.                                 continue
  159.                             
  160.                             constraints.append((index[c], i))
  161.                             continue
  162.                     
  163.                 
  164.             
  165.             if not constraints:
  166.                 break
  167.             
  168.             (goes_before, a_chain) = constraints[0]
  169.             c = chains[a_chain]
  170.             chains.insert(goes_before, c)
  171.             continue
  172.             del blocks[:]
  173.             for c in chains:
  174.                 for b in c:
  175.                     blocks.append(b)
  176.                 
  177.             
  178.  
  179.     
  180.     def getBlocks(self):
  181.         return self.blocks.elements()
  182.  
  183.     
  184.     def getRoot(self):
  185.         return self.entry
  186.  
  187.     
  188.     def getContainedGraphs(self):
  189.         l = []
  190.         for b in self.getBlocks():
  191.             l.extend(b.getContainedGraphs())
  192.         
  193.         return l
  194.  
  195.  
  196.  
  197. def dfs_postorder(b, seen):
  198.     order = []
  199.     seen[b] = b
  200.     for c in b.get_children():
  201.         if c in seen:
  202.             continue
  203.         
  204.         order = order + dfs_postorder(c, seen)
  205.     
  206.     order.append(b)
  207.     return order
  208.  
  209.  
  210. class Block:
  211.     _count = 0
  212.     
  213.     def __init__(self, label = ''):
  214.         self.insts = []
  215.         self.inEdges = misc.Set()
  216.         self.outEdges = misc.Set()
  217.         self.label = label
  218.         self.bid = Block._count
  219.         self.next = []
  220.         Block._count = Block._count + 1
  221.  
  222.     
  223.     def __repr__(self):
  224.         if self.label:
  225.             return '<block %s id=%d>' % (self.label, self.bid)
  226.         return '<block id=%d>' % self.bid
  227.  
  228.     
  229.     def __str__(self):
  230.         insts = map(str, self.insts)
  231.         return '<block %s %d:\n%s>' % (self.label, self.bid, '\n'.join(insts))
  232.  
  233.     
  234.     def emit(self, inst):
  235.         op = inst[0]
  236.         if op[:4] == 'JUMP':
  237.             self.outEdges.add(inst[1])
  238.         
  239.         self.insts.append(inst)
  240.  
  241.     
  242.     def getInstructions(self):
  243.         return self.insts
  244.  
  245.     
  246.     def addInEdge(self, block):
  247.         self.inEdges.add(block)
  248.  
  249.     
  250.     def addOutEdge(self, block):
  251.         self.outEdges.add(block)
  252.  
  253.     
  254.     def addNext(self, block):
  255.         self.next.append(block)
  256.  
  257.     _uncond_transfer = ('RETURN_VALUE', 'RAISE_VARARGS', 'YIELD_VALUE', 'JUMP_ABSOLUTE', 'JUMP_FORWARD', 'CONTINUE_LOOP')
  258.     
  259.     def pruneNext(self):
  260.         
  261.         try:
  262.             (op, arg) = self.insts[-1]
  263.         except (IndexError, ValueError):
  264.             return None
  265.  
  266.         if op in self._uncond_transfer:
  267.             self.next = []
  268.         
  269.  
  270.     
  271.     def get_children(self):
  272.         if self.next and self.next[0] in self.outEdges:
  273.             self.outEdges.remove(self.next[0])
  274.         
  275.         return self.outEdges.elements() + self.next
  276.  
  277.     
  278.     def getContainedGraphs(self):
  279.         contained = []
  280.         for inst in self.insts:
  281.             if len(inst) == 1:
  282.                 continue
  283.             
  284.             op = inst[1]
  285.             if hasattr(op, 'graph'):
  286.                 contained.append(op.graph)
  287.                 continue
  288.         
  289.         return contained
  290.  
  291.  
  292. RAW = 'RAW'
  293. FLAT = 'FLAT'
  294. CONV = 'CONV'
  295. DONE = 'DONE'
  296.  
  297. class PyFlowGraph(FlowGraph):
  298.     super_init = FlowGraph.__init__
  299.     
  300.     def __init__(self, name, filename, args = (), optimized = 0, klass = None):
  301.         self.super_init()
  302.         self.name = name
  303.         self.filename = filename
  304.         self.docstring = None
  305.         self.args = args
  306.         self.argcount = getArgCount(args)
  307.         self.klass = klass
  308.         if optimized:
  309.             self.flags = CO_OPTIMIZED | CO_NEWLOCALS
  310.         else:
  311.             self.flags = 0
  312.         self.consts = []
  313.         self.names = []
  314.         self.freevars = []
  315.         self.cellvars = []
  316.         self.closure = []
  317.         if not list(args):
  318.             pass
  319.         self.varnames = []
  320.         for i in range(len(self.varnames)):
  321.             var = self.varnames[i]
  322.             if isinstance(var, TupleArg):
  323.                 self.varnames[i] = var.getName()
  324.                 continue
  325.         
  326.         self.stage = RAW
  327.  
  328.     
  329.     def setDocstring(self, doc):
  330.         self.docstring = doc
  331.  
  332.     
  333.     def setFlag(self, flag):
  334.         self.flags = self.flags | flag
  335.         if flag == CO_VARARGS:
  336.             self.argcount = self.argcount - 1
  337.         
  338.  
  339.     
  340.     def checkFlag(self, flag):
  341.         if self.flags & flag:
  342.             return 1
  343.  
  344.     
  345.     def setFreeVars(self, names):
  346.         self.freevars = list(names)
  347.  
  348.     
  349.     def setCellVars(self, names):
  350.         self.cellvars = names
  351.  
  352.     
  353.     def getCode(self):
  354.         self.computeStackDepth()
  355.         self.flattenGraph()
  356.         self.convertArgs()
  357.         self.makeByteCode()
  358.         return self.newCodeObject()
  359.  
  360.     
  361.     def dump(self, io = None):
  362.         if io:
  363.             save = sys.stdout
  364.             sys.stdout = io
  365.         
  366.         pc = 0
  367.         for t in self.insts:
  368.             opname = t[0]
  369.             if opname == 'SET_LINENO':
  370.                 print 
  371.             
  372.             if len(t) == 1:
  373.                 print '\t', '%3d' % pc, opname
  374.                 pc = pc + 1
  375.                 continue
  376.             print '\t', '%3d' % pc, opname, t[1]
  377.             pc = pc + 3
  378.         
  379.         if io:
  380.             sys.stdout = save
  381.         
  382.  
  383.     
  384.     def computeStackDepth(self):
  385.         depth = { }
  386.         exit = None
  387.         for b in self.getBlocks():
  388.             depth[b] = findDepth(b.getInstructions())
  389.         
  390.         seen = { }
  391.         
  392.         def max_depth(b, d):
  393.             if b in seen:
  394.                 return d
  395.             seen[b] = 1
  396.             d = d + depth[b]
  397.             children = b.get_children()
  398.             if children:
  399.                 return []([ max_depth(c, d) for c in children ])
  400.             if not b.label == 'exit':
  401.                 return max_depth(self.exit, d)
  402.             return d
  403.  
  404.         self.stacksize = max_depth(self.entry, 0)
  405.  
  406.     
  407.     def flattenGraph(self):
  408.         self.insts = insts = []
  409.         pc = 0
  410.         begin = { }
  411.         end = { }
  412.         for b in self.getBlocksInOrder():
  413.             begin[b] = pc
  414.             for inst in b.getInstructions():
  415.                 insts.append(inst)
  416.                 if len(inst) == 1:
  417.                     pc = pc + 1
  418.                     continue
  419.                 if inst[0] != 'SET_LINENO':
  420.                     pc = pc + 3
  421.                     continue
  422.             
  423.             end[b] = pc
  424.         
  425.         pc = 0
  426.         for i in range(len(insts)):
  427.             inst = insts[i]
  428.             if len(inst) == 1:
  429.                 pc = pc + 1
  430.             elif inst[0] != 'SET_LINENO':
  431.                 pc = pc + 3
  432.             
  433.             opname = inst[0]
  434.             if self.hasjrel.has_elt(opname):
  435.                 oparg = inst[1]
  436.                 offset = begin[oparg] - pc
  437.                 insts[i] = (opname, offset)
  438.                 continue
  439.             if self.hasjabs.has_elt(opname):
  440.                 insts[i] = (opname, begin[inst[1]])
  441.                 continue
  442.         
  443.         self.stage = FLAT
  444.  
  445.     hasjrel = misc.Set()
  446.     for i in dis.hasjrel:
  447.         hasjrel.add(dis.opname[i])
  448.     
  449.     hasjabs = misc.Set()
  450.     for i in dis.hasjabs:
  451.         hasjabs.add(dis.opname[i])
  452.     
  453.     
  454.     def convertArgs(self):
  455.         self.consts.insert(0, self.docstring)
  456.         self.sort_cellvars()
  457.         for i in range(len(self.insts)):
  458.             t = self.insts[i]
  459.             if len(t) == 2:
  460.                 (opname, oparg) = t
  461.                 conv = self._converters.get(opname, None)
  462.                 if conv:
  463.                     self.insts[i] = (opname, conv(self, oparg))
  464.                 
  465.             conv
  466.         
  467.         self.stage = CONV
  468.  
  469.     
  470.     def sort_cellvars(self):
  471.         cells = { }
  472.         for name in self.cellvars:
  473.             cells[name] = 1
  474.         
  475.         self.cellvars = _[1]
  476.         for name in self.cellvars:
  477.             del cells[name]
  478.         
  479.         self.cellvars = self.cellvars + cells.keys()
  480.         self.closure = self.cellvars + self.freevars
  481.  
  482.     
  483.     def _lookupName(self, name, list):
  484.         t = type(name)
  485.         for i in range(len(list)):
  486.             if t == type(list[i]) and list[i] == name:
  487.                 return i
  488.         
  489.         end = len(list)
  490.         list.append(name)
  491.         return end
  492.  
  493.     _converters = { }
  494.     
  495.     def _convert_LOAD_CONST(self, arg):
  496.         if hasattr(arg, 'getCode'):
  497.             arg = arg.getCode()
  498.         
  499.         return self._lookupName(arg, self.consts)
  500.  
  501.     
  502.     def _convert_LOAD_FAST(self, arg):
  503.         self._lookupName(arg, self.names)
  504.         return self._lookupName(arg, self.varnames)
  505.  
  506.     _convert_STORE_FAST = _convert_LOAD_FAST
  507.     _convert_DELETE_FAST = _convert_LOAD_FAST
  508.     
  509.     def _convert_LOAD_NAME(self, arg):
  510.         if self.klass is None:
  511.             self._lookupName(arg, self.varnames)
  512.         
  513.         return self._lookupName(arg, self.names)
  514.  
  515.     
  516.     def _convert_NAME(self, arg):
  517.         if self.klass is None:
  518.             self._lookupName(arg, self.varnames)
  519.         
  520.         return self._lookupName(arg, self.names)
  521.  
  522.     _convert_STORE_NAME = _convert_NAME
  523.     _convert_DELETE_NAME = _convert_NAME
  524.     _convert_IMPORT_NAME = _convert_NAME
  525.     _convert_IMPORT_FROM = _convert_NAME
  526.     _convert_STORE_ATTR = _convert_NAME
  527.     _convert_LOAD_ATTR = _convert_NAME
  528.     _convert_DELETE_ATTR = _convert_NAME
  529.     _convert_LOAD_GLOBAL = _convert_NAME
  530.     _convert_STORE_GLOBAL = _convert_NAME
  531.     _convert_DELETE_GLOBAL = _convert_NAME
  532.     
  533.     def _convert_DEREF(self, arg):
  534.         self._lookupName(arg, self.names)
  535.         self._lookupName(arg, self.varnames)
  536.         return self._lookupName(arg, self.closure)
  537.  
  538.     _convert_LOAD_DEREF = _convert_DEREF
  539.     _convert_STORE_DEREF = _convert_DEREF
  540.     
  541.     def _convert_LOAD_CLOSURE(self, arg):
  542.         self._lookupName(arg, self.varnames)
  543.         return self._lookupName(arg, self.closure)
  544.  
  545.     _cmp = list(dis.cmp_op)
  546.     
  547.     def _convert_COMPARE_OP(self, arg):
  548.         return self._cmp.index(arg)
  549.  
  550.     for name, obj in locals().items():
  551.         if name[:9] == '_convert_':
  552.             opname = name[9:]
  553.             _converters[opname] = obj
  554.             continue
  555.     
  556.     del name
  557.     del obj
  558.     del opname
  559.     
  560.     def makeByteCode(self):
  561.         self.lnotab = lnotab = LineAddrTable()
  562.         for t in self.insts:
  563.             opname = t[0]
  564.             if len(t) == 1:
  565.                 lnotab.addCode(self.opnum[opname])
  566.                 continue
  567.             oparg = t[1]
  568.             if opname == 'SET_LINENO':
  569.                 lnotab.nextLine(oparg)
  570.                 continue
  571.             
  572.             (hi, lo) = twobyte(oparg)
  573.             
  574.             try:
  575.                 lnotab.addCode(self.opnum[opname], lo, hi)
  576.             continue
  577.             except ValueError:
  578.                 print opname, oparg
  579.                 print self.opnum[opname], lo, hi
  580.                 raise 
  581.                 continue
  582.             
  583.  
  584.         
  585.         self.stage = DONE
  586.  
  587.     opnum = { }
  588.     for num in range(len(dis.opname)):
  589.         opnum[dis.opname[num]] = num
  590.     
  591.     del num
  592.     
  593.     def newCodeObject(self):
  594.         if self.flags & CO_NEWLOCALS == 0:
  595.             nlocals = 0
  596.         else:
  597.             nlocals = len(self.varnames)
  598.         argcount = self.argcount
  599.         if self.flags & CO_VARKEYWORDS:
  600.             argcount = argcount - 1
  601.         
  602.         return types.CodeType(argcount, nlocals, self.stacksize, self.flags, self.lnotab.getCode(), self.getConsts(), tuple(self.names), tuple(self.varnames), self.filename, self.name, self.lnotab.firstline, self.lnotab.getTable(), tuple(self.freevars), tuple(self.cellvars))
  603.  
  604.     
  605.     def getConsts(self):
  606.         l = []
  607.         for elt in self.consts:
  608.             if isinstance(elt, PyFlowGraph):
  609.                 elt = elt.getCode()
  610.             
  611.             l.append(elt)
  612.         
  613.         return tuple(l)
  614.  
  615.  
  616.  
  617. def isJump(opname):
  618.     if opname[:4] == 'JUMP':
  619.         return 1
  620.  
  621.  
  622. class TupleArg:
  623.     
  624.     def __init__(self, count, names):
  625.         self.count = count
  626.         self.names = names
  627.  
  628.     
  629.     def __repr__(self):
  630.         return 'TupleArg(%s, %s)' % (self.count, self.names)
  631.  
  632.     
  633.     def getName(self):
  634.         return '.%d' % self.count
  635.  
  636.  
  637.  
  638. def getArgCount(args):
  639.     argcount = len(args)
  640.     if args:
  641.         for arg in args:
  642.             if isinstance(arg, TupleArg):
  643.                 numNames = len(misc.flatten(arg.names))
  644.                 argcount = argcount - numNames
  645.                 continue
  646.         
  647.     
  648.     return argcount
  649.  
  650.  
  651. def twobyte(val):
  652.     return divmod(val, 256)
  653.  
  654.  
  655. class LineAddrTable:
  656.     
  657.     def __init__(self):
  658.         self.code = []
  659.         self.codeOffset = 0
  660.         self.firstline = 0
  661.         self.lastline = 0
  662.         self.lastoff = 0
  663.         self.lnotab = []
  664.  
  665.     
  666.     def addCode(self, *args):
  667.         for arg in args:
  668.             self.code.append(chr(arg))
  669.         
  670.         self.codeOffset = self.codeOffset + len(args)
  671.  
  672.     
  673.     def nextLine(self, lineno):
  674.         if self.firstline == 0:
  675.             self.firstline = lineno
  676.             self.lastline = lineno
  677.         else:
  678.             addr = self.codeOffset - self.lastoff
  679.             line = lineno - self.lastline
  680.             if line >= 0:
  681.                 push = self.lnotab.append
  682.                 while addr > 255:
  683.                     push(255)
  684.                     push(0)
  685.                     addr -= 255
  686.                 while line > 255:
  687.                     push(addr)
  688.                     push(255)
  689.                     line -= 255
  690.                     addr = 0
  691.                 if addr > 0 or line > 0:
  692.                     push(addr)
  693.                     push(line)
  694.                 
  695.                 self.lastline = lineno
  696.                 self.lastoff = self.codeOffset
  697.             
  698.  
  699.     
  700.     def getCode(self):
  701.         return ''.join(self.code)
  702.  
  703.     
  704.     def getTable(self):
  705.         return ''.join(map(chr, self.lnotab))
  706.  
  707.  
  708.  
  709. class StackDepthTracker:
  710.     
  711.     def findDepth(self, insts, debug = 0):
  712.         depth = 0
  713.         maxDepth = 0
  714.         for i in insts:
  715.             opname = i[0]
  716.             if debug:
  717.                 print i,
  718.             
  719.             delta = self.effect.get(opname, None)
  720.             if delta is not None:
  721.                 depth = depth + delta
  722.             else:
  723.                 for pat, pat_delta in self.patterns:
  724.                     if opname[:len(pat)] == pat:
  725.                         delta = pat_delta
  726.                         depth = depth + delta
  727.                         break
  728.                         continue
  729.                 
  730.                 if delta is None:
  731.                     meth = getattr(self, opname, None)
  732.                     if meth is not None:
  733.                         depth = depth + meth(i[1])
  734.                     
  735.                 
  736.             if depth > maxDepth:
  737.                 maxDepth = depth
  738.             
  739.             if debug:
  740.                 print depth, maxDepth
  741.                 continue
  742.         
  743.         return maxDepth
  744.  
  745.     effect = {
  746.         'POP_TOP': -1,
  747.         'DUP_TOP': 1,
  748.         'LIST_APPEND': -2,
  749.         'SLICE+1': -1,
  750.         'SLICE+2': -1,
  751.         'SLICE+3': -2,
  752.         'STORE_SLICE+0': -1,
  753.         'STORE_SLICE+1': -2,
  754.         'STORE_SLICE+2': -2,
  755.         'STORE_SLICE+3': -3,
  756.         'DELETE_SLICE+0': -1,
  757.         'DELETE_SLICE+1': -2,
  758.         'DELETE_SLICE+2': -2,
  759.         'DELETE_SLICE+3': -3,
  760.         'STORE_SUBSCR': -3,
  761.         'DELETE_SUBSCR': -2,
  762.         'PRINT_ITEM': -1,
  763.         'RETURN_VALUE': -1,
  764.         'YIELD_VALUE': -1,
  765.         'EXEC_STMT': -3,
  766.         'BUILD_CLASS': -2,
  767.         'STORE_NAME': -1,
  768.         'STORE_ATTR': -2,
  769.         'DELETE_ATTR': -1,
  770.         'STORE_GLOBAL': -1,
  771.         'BUILD_MAP': 1,
  772.         'COMPARE_OP': -1,
  773.         'STORE_FAST': -1,
  774.         'IMPORT_STAR': -1,
  775.         'IMPORT_NAME': -1,
  776.         'IMPORT_FROM': 1,
  777.         'LOAD_ATTR': 0,
  778.         'SETUP_EXCEPT': 3,
  779.         'SETUP_FINALLY': 3,
  780.         'FOR_ITER': 1,
  781.         'WITH_CLEANUP': -1 }
  782.     patterns = [
  783.         ('BINARY_', -1),
  784.         ('LOAD_', 1)]
  785.     
  786.     def UNPACK_SEQUENCE(self, count):
  787.         return count - 1
  788.  
  789.     
  790.     def BUILD_TUPLE(self, count):
  791.         return -count + 1
  792.  
  793.     
  794.     def BUILD_LIST(self, count):
  795.         return -count + 1
  796.  
  797.     
  798.     def CALL_FUNCTION(self, argc):
  799.         (hi, lo) = divmod(argc, 256)
  800.         return -(lo + hi * 2)
  801.  
  802.     
  803.     def CALL_FUNCTION_VAR(self, argc):
  804.         return self.CALL_FUNCTION(argc) - 1
  805.  
  806.     
  807.     def CALL_FUNCTION_KW(self, argc):
  808.         return self.CALL_FUNCTION(argc) - 1
  809.  
  810.     
  811.     def CALL_FUNCTION_VAR_KW(self, argc):
  812.         return self.CALL_FUNCTION(argc) - 2
  813.  
  814.     
  815.     def MAKE_FUNCTION(self, argc):
  816.         return -argc
  817.  
  818.     
  819.     def MAKE_CLOSURE(self, argc):
  820.         return -argc
  821.  
  822.     
  823.     def BUILD_SLICE(self, argc):
  824.         if argc == 2:
  825.             return -1
  826.         if argc == 3:
  827.             return -2
  828.  
  829.     
  830.     def DUP_TOPX(self, argc):
  831.         return argc
  832.  
  833.  
  834. findDepth = StackDepthTracker().findDepth
  835.