PageRenderTime 55ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/interpreter/pyframe.py

https://bitbucket.org/pypy/pypy/
Python | 903 lines | 867 code | 3 blank | 33 comment | 2 complexity | 2a18aea926391cfbf8044364e978f28a MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. """ PyFrame class implementation with the interpreter main loop.
  2. """
  3. from rpython.rlib import jit
  4. from rpython.rlib.debug import make_sure_not_resized, check_nonneg
  5. from rpython.rlib.jit import hint
  6. from rpython.rlib.objectmodel import instantiate, specialize, we_are_translated
  7. from rpython.rlib.rarithmetic import intmask, r_uint
  8. from rpython.tool.pairtype import extendabletype
  9. from pypy.interpreter import pycode, pytraceback
  10. from pypy.interpreter.argument import Arguments
  11. from pypy.interpreter.astcompiler import consts
  12. from pypy.interpreter.baseobjspace import W_Root
  13. from pypy.interpreter.error import (
  14. OperationError, get_cleared_operation_error, oefmt)
  15. from pypy.interpreter.executioncontext import ExecutionContext
  16. from pypy.interpreter.nestedscope import Cell
  17. from pypy.tool import stdlib_opcode
  18. # Define some opcodes used
  19. for op in '''DUP_TOP POP_TOP SETUP_LOOP SETUP_EXCEPT SETUP_FINALLY SETUP_WITH
  20. POP_BLOCK END_FINALLY'''.split():
  21. globals()[op] = stdlib_opcode.opmap[op]
  22. HAVE_ARGUMENT = stdlib_opcode.HAVE_ARGUMENT
  23. class FrameDebugData(object):
  24. """ A small object that holds debug data for tracing
  25. """
  26. w_f_trace = None
  27. instr_lb = 0
  28. instr_ub = 0
  29. instr_prev_plus_one = 0
  30. f_lineno = 0 # current lineno for tracing
  31. is_being_profiled = False
  32. w_locals = None
  33. def __init__(self, pycode):
  34. self.f_lineno = pycode.co_firstlineno
  35. self.w_globals = pycode.w_globals
  36. class PyFrame(W_Root):
  37. """Represents a frame for a regular Python function
  38. that needs to be interpreted.
  39. Public fields:
  40. * 'space' is the object space this frame is running in
  41. * 'code' is the PyCode object this frame runs
  42. * 'w_locals' is the locals dictionary to use, if needed, stored on a
  43. debug object
  44. * 'w_globals' is the attached globals dictionary
  45. * 'builtin' is the attached built-in module
  46. * 'valuestack_w', 'blockstack', control the interpretation
  47. Cell Vars:
  48. my local variables that are exposed to my inner functions
  49. Free Vars:
  50. variables coming from a parent function in which i'm nested
  51. 'closure' is a list of Cell instances: the received free vars.
  52. """
  53. __metaclass__ = extendabletype
  54. frame_finished_execution = False
  55. last_instr = -1
  56. last_exception = None
  57. f_backref = jit.vref_None
  58. escaped = False # see mark_as_escaped()
  59. debugdata = None
  60. pycode = None # code object executed by that frame
  61. locals_cells_stack_w = None # the list of all locals, cells and the valuestack
  62. valuestackdepth = 0 # number of items on valuestack
  63. lastblock = None
  64. # other fields:
  65. # builtin - builtin cache, only if honor__builtins__ is True
  66. # defaults to False
  67. # there is also self.space which is removed by the annotator
  68. # additionally JIT uses vable_token field that is representing
  69. # frame current virtualizable state as seen by the JIT
  70. def __init__(self, space, code, w_globals, outer_func):
  71. if not we_are_translated():
  72. assert type(self) == space.FrameClass, (
  73. "use space.FrameClass(), not directly PyFrame()")
  74. self = hint(self, access_directly=True, fresh_virtualizable=True)
  75. assert isinstance(code, pycode.PyCode)
  76. self.space = space
  77. self.pycode = code
  78. if code.frame_stores_global(w_globals):
  79. self.getorcreatedebug().w_globals = w_globals
  80. ncellvars = len(code.co_cellvars)
  81. nfreevars = len(code.co_freevars)
  82. size = code.co_nlocals + ncellvars + nfreevars + code.co_stacksize
  83. # the layout of this list is as follows:
  84. # | local vars | cells | stack |
  85. self.locals_cells_stack_w = [None] * size
  86. self.valuestackdepth = code.co_nlocals + ncellvars + nfreevars
  87. make_sure_not_resized(self.locals_cells_stack_w)
  88. check_nonneg(self.valuestackdepth)
  89. #
  90. if space.config.objspace.honor__builtins__:
  91. self.builtin = space.builtin.pick_builtin(w_globals)
  92. # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
  93. # class bodies only have CO_NEWLOCALS.
  94. self.initialize_frame_scopes(outer_func, code)
  95. def getdebug(self):
  96. return self.debugdata
  97. def getorcreatedebug(self):
  98. if self.debugdata is None:
  99. self.debugdata = FrameDebugData(self.pycode)
  100. return self.debugdata
  101. def get_w_globals(self):
  102. debugdata = self.getdebug()
  103. if debugdata is not None:
  104. return debugdata.w_globals
  105. return jit.promote(self.pycode).w_globals
  106. def get_w_f_trace(self):
  107. d = self.getdebug()
  108. if d is None:
  109. return None
  110. return d.w_f_trace
  111. def get_is_being_profiled(self):
  112. d = self.getdebug()
  113. if d is None:
  114. return False
  115. return d.is_being_profiled
  116. def get_w_locals(self):
  117. d = self.getdebug()
  118. if d is None:
  119. return None
  120. return d.w_locals
  121. def __repr__(self):
  122. # NOT_RPYTHON: useful in tracebacks
  123. return "<%s.%s executing %s at line %s" % (
  124. self.__class__.__module__, self.__class__.__name__,
  125. self.pycode, self.get_last_lineno())
  126. def _getcell(self, varindex):
  127. cell = self.locals_cells_stack_w[varindex + self.pycode.co_nlocals]
  128. assert isinstance(cell, Cell)
  129. return cell
  130. def mark_as_escaped(self):
  131. """
  132. Must be called on frames that are exposed to applevel, e.g. by
  133. sys._getframe(). This ensures that the virtualref holding the frame
  134. is properly forced by ec.leave(), and thus the frame will be still
  135. accessible even after the corresponding C stack died.
  136. """
  137. self.escaped = True
  138. def append_block(self, block):
  139. assert block.previous is self.lastblock
  140. self.lastblock = block
  141. def pop_block(self):
  142. block = self.lastblock
  143. self.lastblock = block.previous
  144. return block
  145. def blockstack_non_empty(self):
  146. return self.lastblock is not None
  147. def get_blocklist(self):
  148. """Returns a list containing all the blocks in the frame"""
  149. lst = []
  150. block = self.lastblock
  151. while block is not None:
  152. lst.append(block)
  153. block = block.previous
  154. return lst
  155. def set_blocklist(self, lst):
  156. self.lastblock = None
  157. i = len(lst) - 1
  158. while i >= 0:
  159. block = lst[i]
  160. i -= 1
  161. block.previous = self.lastblock
  162. self.lastblock = block
  163. def get_builtin(self):
  164. if self.space.config.objspace.honor__builtins__:
  165. return self.builtin
  166. else:
  167. return self.space.builtin
  168. @jit.unroll_safe
  169. def initialize_frame_scopes(self, outer_func, code):
  170. # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
  171. # class bodies only have CO_NEWLOCALS.
  172. # CO_NEWLOCALS: make a locals dict unless optimized is also set
  173. # CO_OPTIMIZED: no locals dict needed at all
  174. flags = code.co_flags
  175. if not (flags & pycode.CO_OPTIMIZED):
  176. if flags & pycode.CO_NEWLOCALS:
  177. self.getorcreatedebug().w_locals = self.space.newdict(module=True)
  178. else:
  179. w_globals = self.get_w_globals()
  180. assert w_globals is not None
  181. self.getorcreatedebug().w_locals = w_globals
  182. ncellvars = len(code.co_cellvars)
  183. nfreevars = len(code.co_freevars)
  184. if not nfreevars:
  185. if not ncellvars:
  186. return # no cells needed - fast path
  187. elif outer_func is None:
  188. space = self.space
  189. raise oefmt(space.w_TypeError,
  190. "directly executed code object may not contain free "
  191. "variables")
  192. if outer_func and outer_func.closure:
  193. closure_size = len(outer_func.closure)
  194. else:
  195. closure_size = 0
  196. if closure_size != nfreevars:
  197. raise ValueError("code object received a closure with "
  198. "an unexpected number of free variables")
  199. index = code.co_nlocals
  200. for i in range(ncellvars):
  201. self.locals_cells_stack_w[index] = Cell()
  202. index += 1
  203. for i in range(nfreevars):
  204. self.locals_cells_stack_w[index] = outer_func.closure[i]
  205. index += 1
  206. def run(self):
  207. """Start this frame's execution."""
  208. if self.getcode().co_flags & pycode.CO_GENERATOR:
  209. from pypy.interpreter.generator import GeneratorIterator
  210. return self.space.wrap(GeneratorIterator(self))
  211. else:
  212. return self.execute_frame()
  213. def execute_frame(self, w_inputvalue=None, operr=None):
  214. """Execute this frame. Main entry point to the interpreter.
  215. The optional arguments are there to handle a generator's frame:
  216. w_inputvalue is for generator.send() and operr is for
  217. generator.throw().
  218. """
  219. # the following 'assert' is an annotation hint: it hides from
  220. # the annotator all methods that are defined in PyFrame but
  221. # overridden in the {,Host}FrameClass subclasses of PyFrame.
  222. assert (isinstance(self, self.space.FrameClass) or
  223. not self.space.config.translating)
  224. executioncontext = self.space.getexecutioncontext()
  225. executioncontext.enter(self)
  226. got_exception = True
  227. w_exitvalue = self.space.w_None
  228. try:
  229. executioncontext.call_trace(self)
  230. #
  231. if operr is not None:
  232. ec = self.space.getexecutioncontext()
  233. next_instr = self.handle_operation_error(ec, operr)
  234. self.last_instr = intmask(next_instr - 1)
  235. else:
  236. # Execution starts just after the last_instr. Initially,
  237. # last_instr is -1. After a generator suspends it points to
  238. # the YIELD_VALUE instruction.
  239. next_instr = r_uint(self.last_instr + 1)
  240. if next_instr != 0:
  241. self.pushvalue(w_inputvalue)
  242. #
  243. try:
  244. w_exitvalue = self.dispatch(self.pycode, next_instr,
  245. executioncontext)
  246. except Exception:
  247. executioncontext.return_trace(self, self.space.w_None)
  248. raise
  249. executioncontext.return_trace(self, w_exitvalue)
  250. # it used to say self.last_exception = None
  251. # this is now done by the code in pypyjit module
  252. # since we don't want to invalidate the virtualizable
  253. # for no good reason
  254. got_exception = False
  255. finally:
  256. executioncontext.leave(self, w_exitvalue, got_exception)
  257. return w_exitvalue
  258. execute_frame.insert_stack_check_here = True
  259. # stack manipulation helpers
  260. def pushvalue(self, w_object):
  261. depth = self.valuestackdepth
  262. self.locals_cells_stack_w[depth] = w_object
  263. self.valuestackdepth = depth + 1
  264. def _check_stack_index(self, index):
  265. # will be completely removed by the optimizer if only used in an assert
  266. # and if asserts are disabled
  267. code = self.pycode
  268. ncellvars = len(code.co_cellvars)
  269. nfreevars = len(code.co_freevars)
  270. stackstart = code.co_nlocals + ncellvars + nfreevars
  271. return index >= stackstart
  272. def popvalue(self):
  273. depth = self.valuestackdepth - 1
  274. assert self._check_stack_index(depth)
  275. assert depth >= 0
  276. w_object = self.locals_cells_stack_w[depth]
  277. self.locals_cells_stack_w[depth] = None
  278. self.valuestackdepth = depth
  279. return w_object
  280. # we need two popvalues that return different data types:
  281. # one in case we want list another in case of tuple
  282. def _new_popvalues():
  283. @jit.unroll_safe
  284. def popvalues(self, n):
  285. values_w = [None] * n
  286. while True:
  287. n -= 1
  288. if n < 0:
  289. break
  290. values_w[n] = self.popvalue()
  291. return values_w
  292. return popvalues
  293. popvalues = _new_popvalues()
  294. popvalues_mutable = _new_popvalues()
  295. del _new_popvalues
  296. @jit.unroll_safe
  297. def peekvalues(self, n):
  298. values_w = [None] * n
  299. base = self.valuestackdepth - n
  300. assert self._check_stack_index(base)
  301. assert base >= 0
  302. while True:
  303. n -= 1
  304. if n < 0:
  305. break
  306. values_w[n] = self.locals_cells_stack_w[base+n]
  307. return values_w
  308. @jit.unroll_safe
  309. def dropvalues(self, n):
  310. n = hint(n, promote=True)
  311. finaldepth = self.valuestackdepth - n
  312. assert self._check_stack_index(finaldepth)
  313. assert finaldepth >= 0
  314. while True:
  315. n -= 1
  316. if n < 0:
  317. break
  318. self.locals_cells_stack_w[finaldepth+n] = None
  319. self.valuestackdepth = finaldepth
  320. @jit.unroll_safe
  321. def pushrevvalues(self, n, values_w): # n should be len(values_w)
  322. make_sure_not_resized(values_w)
  323. while True:
  324. n -= 1
  325. if n < 0:
  326. break
  327. self.pushvalue(values_w[n])
  328. @jit.unroll_safe
  329. def dupvalues(self, n):
  330. delta = n-1
  331. while True:
  332. n -= 1
  333. if n < 0:
  334. break
  335. w_value = self.peekvalue(delta)
  336. self.pushvalue(w_value)
  337. def peekvalue(self, index_from_top=0):
  338. # NOTE: top of the stack is peekvalue(0).
  339. # Contrast this with CPython where it's PEEK(-1).
  340. index_from_top = hint(index_from_top, promote=True)
  341. index = self.valuestackdepth + ~index_from_top
  342. assert self._check_stack_index(index)
  343. assert index >= 0
  344. return self.locals_cells_stack_w[index]
  345. def settopvalue(self, w_object, index_from_top=0):
  346. index_from_top = hint(index_from_top, promote=True)
  347. index = self.valuestackdepth + ~index_from_top
  348. assert self._check_stack_index(index)
  349. assert index >= 0
  350. self.locals_cells_stack_w[index] = w_object
  351. @jit.unroll_safe
  352. def dropvaluesuntil(self, finaldepth):
  353. depth = self.valuestackdepth - 1
  354. finaldepth = hint(finaldepth, promote=True)
  355. assert finaldepth >= 0
  356. while depth >= finaldepth:
  357. self.locals_cells_stack_w[depth] = None
  358. depth -= 1
  359. self.valuestackdepth = finaldepth
  360. def make_arguments(self, nargs):
  361. return Arguments(self.space, self.peekvalues(nargs))
  362. def argument_factory(self, arguments, keywords, keywords_w, w_star, w_starstar):
  363. return Arguments(self.space, arguments, keywords, keywords_w, w_star, w_starstar)
  364. @jit.dont_look_inside
  365. def descr__reduce__(self, space):
  366. from pypy.interpreter.mixedmodule import MixedModule
  367. w_mod = space.getbuiltinmodule('_pickle_support')
  368. mod = space.interp_w(MixedModule, w_mod)
  369. new_inst = mod.get('frame_new')
  370. w_tup_state = self._reduce_state(space)
  371. nt = space.newtuple
  372. return nt([new_inst, nt([]), w_tup_state])
  373. @jit.dont_look_inside
  374. def _reduce_state(self, space):
  375. from pypy.module._pickle_support import maker # helper fns
  376. w = space.wrap
  377. nt = space.newtuple
  378. if self.get_w_f_trace() is None:
  379. f_lineno = self.get_last_lineno()
  380. else:
  381. f_lineno = self.getorcreatedebug().f_lineno
  382. nlocals = self.pycode.co_nlocals
  383. values_w = self.locals_cells_stack_w
  384. w_locals_cells_stack = maker.slp_into_tuple_with_nulls(space, values_w)
  385. w_blockstack = nt([block._get_state_(space) for block in self.get_blocklist()])
  386. if self.last_exception is None:
  387. w_exc_value = space.w_None
  388. w_tb = space.w_None
  389. else:
  390. w_exc_value = self.last_exception.get_w_value(space)
  391. w_tb = w(self.last_exception.get_traceback())
  392. d = self.getorcreatedebug()
  393. tup_state = [
  394. w(self.f_backref()),
  395. w(self.get_builtin()),
  396. w(self.pycode),
  397. w_locals_cells_stack,
  398. w_blockstack,
  399. w_exc_value, # last_exception
  400. w_tb, #
  401. self.get_w_globals(),
  402. w(self.last_instr),
  403. w(self.frame_finished_execution),
  404. w(f_lineno),
  405. space.w_None, #XXX placeholder for f_locals
  406. #f_restricted requires no additional data!
  407. space.w_None,
  408. w(d.instr_lb),
  409. w(d.instr_ub),
  410. w(d.instr_prev_plus_one),
  411. w(self.valuestackdepth),
  412. ]
  413. return nt(tup_state)
  414. @jit.dont_look_inside
  415. def descr__setstate__(self, space, w_args):
  416. from pypy.module._pickle_support import maker # helper fns
  417. from pypy.interpreter.pycode import PyCode
  418. from pypy.interpreter.module import Module
  419. args_w = space.unpackiterable(w_args, 17)
  420. w_f_back, w_builtin, w_pycode, w_locals_cells_stack, w_blockstack, w_exc_value, w_tb,\
  421. w_globals, w_last_instr, w_finished, w_f_lineno, w_f_locals, \
  422. w_f_trace, w_instr_lb, w_instr_ub, w_instr_prev_plus_one, w_stackdepth = args_w
  423. new_frame = self
  424. pycode = space.interp_w(PyCode, w_pycode)
  425. values_w = maker.slp_from_tuple_with_nulls(space, w_locals_cells_stack)
  426. nfreevars = len(pycode.co_freevars)
  427. closure = None
  428. if nfreevars:
  429. base = pycode.co_nlocals + len(pycode.co_cellvars)
  430. closure = values_w[base: base + nfreevars]
  431. # do not use the instance's __init__ but the base's, because we set
  432. # everything like cells from here
  433. # XXX hack
  434. from pypy.interpreter.function import Function
  435. outer_func = Function(space, None, closure=closure,
  436. forcename="fake")
  437. PyFrame.__init__(self, space, pycode, w_globals, outer_func)
  438. f_back = space.interp_w(PyFrame, w_f_back, can_be_None=True)
  439. new_frame.f_backref = jit.non_virtual_ref(f_back)
  440. if space.config.objspace.honor__builtins__:
  441. new_frame.builtin = space.interp_w(Module, w_builtin)
  442. else:
  443. assert space.interp_w(Module, w_builtin) is space.builtin
  444. new_frame.set_blocklist([unpickle_block(space, w_blk)
  445. for w_blk in space.unpackiterable(w_blockstack)])
  446. self.locals_cells_stack_w = values_w[:]
  447. valuestackdepth = space.int_w(w_stackdepth)
  448. if not self._check_stack_index(valuestackdepth):
  449. raise oefmt(space.w_ValueError, "invalid stackdepth")
  450. assert valuestackdepth >= 0
  451. self.valuestackdepth = valuestackdepth
  452. if space.is_w(w_exc_value, space.w_None):
  453. new_frame.last_exception = None
  454. else:
  455. from pypy.interpreter.pytraceback import PyTraceback
  456. tb = space.interp_w(PyTraceback, w_tb)
  457. new_frame.last_exception = OperationError(space.type(w_exc_value),
  458. w_exc_value, tb
  459. )
  460. new_frame.last_instr = space.int_w(w_last_instr)
  461. new_frame.frame_finished_execution = space.is_true(w_finished)
  462. d = new_frame.getorcreatedebug()
  463. d.f_lineno = space.int_w(w_f_lineno)
  464. if space.is_w(w_f_trace, space.w_None):
  465. d.w_f_trace = None
  466. else:
  467. d.w_f_trace = w_f_trace
  468. d.instr_lb = space.int_w(w_instr_lb) #the three for tracing
  469. d.instr_ub = space.int_w(w_instr_ub)
  470. d.instr_prev_plus_one = space.int_w(w_instr_prev_plus_one)
  471. def hide(self):
  472. return self.pycode.hidden_applevel
  473. def getcode(self):
  474. return hint(self.pycode, promote=True)
  475. @jit.look_inside_iff(lambda self, scope_w: jit.isvirtual(scope_w))
  476. def setfastscope(self, scope_w):
  477. """Initialize the fast locals from a list of values,
  478. where the order is according to self.pycode.signature()."""
  479. scope_len = len(scope_w)
  480. if scope_len > self.pycode.co_nlocals:
  481. raise ValueError("new fastscope is longer than the allocated area")
  482. # don't assign directly to 'locals_cells_stack_w[:scope_len]' to be
  483. # virtualizable-friendly
  484. for i in range(scope_len):
  485. self.locals_cells_stack_w[i] = scope_w[i]
  486. self.init_cells()
  487. def getdictscope(self):
  488. """
  489. Get the locals as a dictionary
  490. """
  491. self.fast2locals()
  492. return self.debugdata.w_locals
  493. def setdictscope(self, w_locals):
  494. """
  495. Initialize the locals from a dictionary.
  496. """
  497. self.getorcreatedebug().w_locals = w_locals
  498. self.locals2fast()
  499. @jit.unroll_safe
  500. def fast2locals(self):
  501. # Copy values from the fastlocals to self.w_locals
  502. d = self.getorcreatedebug()
  503. if d.w_locals is None:
  504. d.w_locals = self.space.newdict()
  505. varnames = self.getcode().getvarnames()
  506. for i in range(min(len(varnames), self.getcode().co_nlocals)):
  507. name = varnames[i]
  508. w_value = self.locals_cells_stack_w[i]
  509. if w_value is not None:
  510. self.space.setitem_str(d.w_locals, name, w_value)
  511. else:
  512. w_name = self.space.wrap(name)
  513. try:
  514. self.space.delitem(d.w_locals, w_name)
  515. except OperationError as e:
  516. if not e.match(self.space, self.space.w_KeyError):
  517. raise
  518. # cellvars are values exported to inner scopes
  519. # freevars are values coming from outer scopes
  520. # (see locals2fast for why CO_OPTIMIZED)
  521. freevarnames = self.pycode.co_cellvars
  522. if self.pycode.co_flags & consts.CO_OPTIMIZED:
  523. freevarnames = freevarnames + self.pycode.co_freevars
  524. for i in range(len(freevarnames)):
  525. name = freevarnames[i]
  526. cell = self._getcell(i)
  527. try:
  528. w_value = cell.get()
  529. except ValueError:
  530. pass
  531. else:
  532. self.space.setitem_str(d.w_locals, name, w_value)
  533. @jit.unroll_safe
  534. def locals2fast(self):
  535. # Copy values from self.w_locals to the fastlocals
  536. w_locals = self.getorcreatedebug().w_locals
  537. assert w_locals is not None
  538. varnames = self.getcode().getvarnames()
  539. numlocals = self.getcode().co_nlocals
  540. new_fastlocals_w = [None] * numlocals
  541. for i in range(min(len(varnames), numlocals)):
  542. name = varnames[i]
  543. w_value = self.space.finditem_str(w_locals, name)
  544. if w_value is not None:
  545. new_fastlocals_w[i] = w_value
  546. self.setfastscope(new_fastlocals_w)
  547. freevarnames = self.pycode.co_cellvars
  548. if self.pycode.co_flags & consts.CO_OPTIMIZED:
  549. freevarnames = freevarnames + self.pycode.co_freevars
  550. # If the namespace is unoptimized, then one of the
  551. # following cases applies:
  552. # 1. It does not contain free variables, because it
  553. # uses import * or is a top-level namespace.
  554. # 2. It is a class namespace.
  555. # We don't want to accidentally copy free variables
  556. # into the locals dict used by the class.
  557. for i in range(len(freevarnames)):
  558. name = freevarnames[i]
  559. cell = self._getcell(i)
  560. w_value = self.space.finditem_str(w_locals, name)
  561. if w_value is not None:
  562. cell.set(w_value)
  563. @jit.unroll_safe
  564. def init_cells(self):
  565. """
  566. Initialize cellvars from self.locals_cells_stack_w.
  567. """
  568. args_to_copy = self.pycode._args_as_cellvars
  569. index = self.pycode.co_nlocals
  570. for i in range(len(args_to_copy)):
  571. argnum = args_to_copy[i]
  572. if argnum >= 0:
  573. cell = self.locals_cells_stack_w[index]
  574. assert isinstance(cell, Cell)
  575. cell.set(self.locals_cells_stack_w[argnum])
  576. index += 1
  577. def getclosure(self):
  578. return None
  579. def fget_code(self, space):
  580. return space.wrap(self.getcode())
  581. def fget_getdictscope(self, space):
  582. return self.getdictscope()
  583. def fget_w_globals(self, space):
  584. # bit silly, but GetSetProperty passes a space
  585. return self.get_w_globals()
  586. ### line numbers ###
  587. def fget_f_lineno(self, space):
  588. "Returns the line number of the instruction currently being executed."
  589. if self.get_w_f_trace() is None:
  590. return space.wrap(self.get_last_lineno())
  591. else:
  592. return space.wrap(self.getorcreatedebug().f_lineno)
  593. def fset_f_lineno(self, space, w_new_lineno):
  594. "Returns the line number of the instruction currently being executed."
  595. try:
  596. new_lineno = space.int_w(w_new_lineno)
  597. except OperationError:
  598. raise oefmt(space.w_ValueError, "lineno must be an integer")
  599. if self.get_w_f_trace() is None:
  600. raise oefmt(space.w_ValueError,
  601. "f_lineno can only be set by a trace function.")
  602. line = self.pycode.co_firstlineno
  603. if new_lineno < line:
  604. raise oefmt(space.w_ValueError,
  605. "line %d comes before the current code.", new_lineno)
  606. elif new_lineno == line:
  607. new_lasti = 0
  608. else:
  609. new_lasti = -1
  610. addr = 0
  611. lnotab = self.pycode.co_lnotab
  612. for offset in xrange(0, len(lnotab), 2):
  613. addr += ord(lnotab[offset])
  614. line += ord(lnotab[offset + 1])
  615. if line >= new_lineno:
  616. new_lasti = addr
  617. new_lineno = line
  618. break
  619. if new_lasti == -1:
  620. raise oefmt(space.w_ValueError,
  621. "line %d comes after the current code.", new_lineno)
  622. # Don't jump to a line with an except in it.
  623. code = self.pycode.co_code
  624. if ord(code[new_lasti]) in (DUP_TOP, POP_TOP):
  625. raise oefmt(space.w_ValueError,
  626. "can't jump to 'except' line as there's no exception")
  627. # Don't jump into or out of a finally block.
  628. f_lasti_setup_addr = -1
  629. new_lasti_setup_addr = -1
  630. blockstack = []
  631. addr = 0
  632. while addr < len(code):
  633. op = ord(code[addr])
  634. if op in (SETUP_LOOP, SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH):
  635. blockstack.append([addr, False])
  636. elif op == POP_BLOCK:
  637. setup_op = ord(code[blockstack[-1][0]])
  638. if setup_op == SETUP_FINALLY or setup_op == SETUP_WITH:
  639. blockstack[-1][1] = True
  640. else:
  641. blockstack.pop()
  642. elif op == END_FINALLY:
  643. if len(blockstack) > 0:
  644. setup_op = ord(code[blockstack[-1][0]])
  645. if setup_op == SETUP_FINALLY or setup_op == SETUP_WITH:
  646. blockstack.pop()
  647. if addr == new_lasti or addr == self.last_instr:
  648. for ii in range(len(blockstack)):
  649. setup_addr, in_finally = blockstack[~ii]
  650. if in_finally:
  651. if addr == new_lasti:
  652. new_lasti_setup_addr = setup_addr
  653. if addr == self.last_instr:
  654. f_lasti_setup_addr = setup_addr
  655. break
  656. if op >= HAVE_ARGUMENT:
  657. addr += 3
  658. else:
  659. addr += 1
  660. assert len(blockstack) == 0
  661. if new_lasti_setup_addr != f_lasti_setup_addr:
  662. raise oefmt(space.w_ValueError,
  663. "can't jump into or out of a 'finally' block %d -> %d",
  664. f_lasti_setup_addr, new_lasti_setup_addr)
  665. if new_lasti < self.last_instr:
  666. min_addr = new_lasti
  667. max_addr = self.last_instr
  668. else:
  669. min_addr = self.last_instr
  670. max_addr = new_lasti
  671. delta_iblock = min_delta_iblock = 0
  672. addr = min_addr
  673. while addr < max_addr:
  674. op = ord(code[addr])
  675. if op in (SETUP_LOOP, SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH):
  676. delta_iblock += 1
  677. elif op == POP_BLOCK:
  678. delta_iblock -= 1
  679. if delta_iblock < min_delta_iblock:
  680. min_delta_iblock = delta_iblock
  681. if op >= stdlib_opcode.HAVE_ARGUMENT:
  682. addr += 3
  683. else:
  684. addr += 1
  685. f_iblock = 0
  686. block = self.lastblock
  687. while block:
  688. f_iblock += 1
  689. block = block.previous
  690. min_iblock = f_iblock + min_delta_iblock
  691. if new_lasti > self.last_instr:
  692. new_iblock = f_iblock + delta_iblock
  693. else:
  694. new_iblock = f_iblock - delta_iblock
  695. if new_iblock > min_iblock:
  696. raise oefmt(space.w_ValueError,
  697. "can't jump into the middle of a block")
  698. while f_iblock > new_iblock:
  699. block = self.pop_block()
  700. block.cleanup(self)
  701. f_iblock -= 1
  702. self.getorcreatedebug().f_lineno = new_lineno
  703. self.last_instr = new_lasti
  704. def get_last_lineno(self):
  705. "Returns the line number of the instruction currently being executed."
  706. return pytraceback.offset2lineno(self.pycode, self.last_instr)
  707. def fget_f_builtins(self, space):
  708. return self.get_builtin().getdict(space)
  709. def fget_f_back(self, space):
  710. f_back = ExecutionContext.getnextframe_nohidden(self)
  711. return self.space.wrap(f_back)
  712. def fget_f_lasti(self, space):
  713. return self.space.wrap(self.last_instr)
  714. def fget_f_trace(self, space):
  715. return self.get_w_f_trace()
  716. def fset_f_trace(self, space, w_trace):
  717. if space.is_w(w_trace, space.w_None):
  718. self.getorcreatedebug().w_f_trace = None
  719. else:
  720. d = self.getorcreatedebug()
  721. d.w_f_trace = w_trace
  722. d.f_lineno = self.get_last_lineno()
  723. def fdel_f_trace(self, space):
  724. self.getorcreatedebug().w_f_trace = None
  725. def fget_f_exc_type(self, space):
  726. if self.last_exception is not None:
  727. f = self.f_backref()
  728. while f is not None and f.last_exception is None:
  729. f = f.f_backref()
  730. if f is not None:
  731. return f.last_exception.w_type
  732. return space.w_None
  733. def fget_f_exc_value(self, space):
  734. if self.last_exception is not None:
  735. f = self.f_backref()
  736. while f is not None and f.last_exception is None:
  737. f = f.f_backref()
  738. if f is not None:
  739. return f.last_exception.get_w_value(space)
  740. return space.w_None
  741. def fget_f_exc_traceback(self, space):
  742. if self.last_exception is not None:
  743. f = self.f_backref()
  744. while f is not None and f.last_exception is None:
  745. f = f.f_backref()
  746. if f is not None:
  747. return space.wrap(f.last_exception.get_traceback())
  748. return space.w_None
  749. def fget_f_restricted(self, space):
  750. if space.config.objspace.honor__builtins__:
  751. return space.wrap(self.builtin is not space.builtin)
  752. return space.w_False
  753. @jit.unroll_safe
  754. @specialize.arg(2)
  755. def _exc_info_unroll(self, space, for_hidden=False):
  756. """Return the most recent OperationError being handled in the
  757. call stack
  758. """
  759. frame = self
  760. while frame:
  761. last = frame.last_exception
  762. if last is not None:
  763. if last is get_cleared_operation_error(self.space):
  764. break
  765. if for_hidden or not frame.hide():
  766. return last
  767. frame = frame.f_backref()
  768. return None
  769. # ____________________________________________________________
  770. def get_block_class(opname):
  771. # select the appropriate kind of block
  772. from pypy.interpreter.pyopcode import block_classes
  773. return block_classes[opname]
  774. def unpickle_block(space, w_tup):
  775. w_opname, w_handlerposition, w_valuestackdepth = space.unpackiterable(w_tup)
  776. opname = space.str_w(w_opname)
  777. handlerposition = space.int_w(w_handlerposition)
  778. valuestackdepth = space.int_w(w_valuestackdepth)
  779. assert valuestackdepth >= 0
  780. assert handlerposition >= 0
  781. blk = instantiate(get_block_class(opname))
  782. blk.handlerposition = handlerposition
  783. blk.valuestackdepth = valuestackdepth
  784. return blk