PageRenderTime 54ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/interpreter/pyopcode.py

https://bitbucket.org/quangquach/pypy
Python | 1481 lines | 1211 code | 177 blank | 93 comment | 143 complexity | 19d97d3fcc6af646209a38b02bb3a31b MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. """
  2. Implementation of a part of the standard Python opcodes.
  3. The rest, dealing with variables in optimized ways, is in nestedscope.py.
  4. """
  5. import sys
  6. from pypy.interpreter.error import OperationError, operationerrfmt
  7. from pypy.interpreter.baseobjspace import Wrappable
  8. from pypy.interpreter import gateway, function, eval, pyframe, pytraceback
  9. from pypy.interpreter.pycode import PyCode, BytecodeCorruption
  10. from pypy.tool.sourcetools import func_with_new_name
  11. from pypy.rlib.objectmodel import we_are_translated
  12. from pypy.rlib import jit, rstackovf
  13. from pypy.rlib.rarithmetic import r_uint, intmask
  14. from pypy.rlib.unroll import unrolling_iterable
  15. from pypy.rlib.debug import check_nonneg
  16. from pypy.tool.stdlib_opcode import (bytecode_spec,
  17. unrolling_all_opcode_descs)
  18. def unaryoperation(operationname):
  19. """NOT_RPYTHON"""
  20. def opimpl(self, *ignored):
  21. operation = getattr(self.space, operationname)
  22. w_1 = self.popvalue()
  23. w_result = operation(w_1)
  24. self.pushvalue(w_result)
  25. opimpl.unaryop = operationname
  26. return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname)
  27. def binaryoperation(operationname):
  28. """NOT_RPYTHON"""
  29. def opimpl(self, *ignored):
  30. operation = getattr(self.space, operationname)
  31. w_2 = self.popvalue()
  32. w_1 = self.popvalue()
  33. w_result = operation(w_1, w_2)
  34. self.pushvalue(w_result)
  35. opimpl.binop = operationname
  36. return func_with_new_name(opimpl, "opcode_impl_for_%s" % operationname)
  37. compare_dispatch_table = [
  38. "cmp_lt", # "<"
  39. "cmp_le", # "<="
  40. "cmp_eq", # "=="
  41. "cmp_ne", # "!="
  42. "cmp_gt", # ">"
  43. "cmp_ge", # ">="
  44. "cmp_in",
  45. "cmp_not_in",
  46. "cmp_is",
  47. "cmp_is_not",
  48. "cmp_exc_match",
  49. ]
  50. unrolling_compare_dispatch_table = unrolling_iterable(
  51. enumerate(compare_dispatch_table))
  52. class __extend__(pyframe.PyFrame):
  53. """A PyFrame that knows about interpretation of standard Python opcodes
  54. minus the ones related to nested scopes."""
  55. bytecode_spec = bytecode_spec
  56. opcode_method_names = bytecode_spec.method_names
  57. opcodedesc = bytecode_spec.opcodedesc
  58. opdescmap = bytecode_spec.opdescmap
  59. HAVE_ARGUMENT = bytecode_spec.HAVE_ARGUMENT
  60. ### opcode dispatch ###
  61. def dispatch(self, pycode, next_instr, ec):
  62. # For the sequel, force 'next_instr' to be unsigned for performance
  63. next_instr = r_uint(next_instr)
  64. co_code = pycode.co_code
  65. try:
  66. while True:
  67. next_instr = self.handle_bytecode(co_code, next_instr, ec)
  68. except ExitFrame:
  69. return self.popvalue()
  70. def handle_bytecode(self, co_code, next_instr, ec):
  71. try:
  72. next_instr = self.dispatch_bytecode(co_code, next_instr, ec)
  73. except OperationError, operr:
  74. next_instr = self.handle_operation_error(ec, operr)
  75. except RaiseWithExplicitTraceback, e:
  76. next_instr = self.handle_operation_error(ec, e.operr,
  77. attach_tb=False)
  78. except KeyboardInterrupt:
  79. next_instr = self.handle_asynchronous_error(ec,
  80. self.space.w_KeyboardInterrupt)
  81. except MemoryError:
  82. next_instr = self.handle_asynchronous_error(ec,
  83. self.space.w_MemoryError)
  84. except rstackovf.StackOverflow, e:
  85. # Note that this case catches AttributeError!
  86. rstackovf.check_stack_overflow()
  87. next_instr = self.handle_asynchronous_error(ec,
  88. self.space.w_RuntimeError,
  89. self.space.wrap("maximum recursion depth exceeded"))
  90. return next_instr
  91. def handle_asynchronous_error(self, ec, w_type, w_value=None):
  92. # catch asynchronous exceptions and turn them
  93. # into OperationErrors
  94. if w_value is None:
  95. w_value = self.space.w_None
  96. operr = OperationError(w_type, w_value)
  97. return self.handle_operation_error(ec, operr)
  98. def handle_operation_error(self, ec, operr, attach_tb=True):
  99. if attach_tb:
  100. if 1:
  101. # xxx this is a hack. It allows bytecode_trace() to
  102. # call a signal handler which raises, and catch the
  103. # raised exception immediately. See test_alarm_raise in
  104. # pypy/module/signal/test/test_signal.py. Without the
  105. # next four lines, if an external call (like
  106. # socket.accept()) is interrupted by a signal, it raises
  107. # an exception carrying EINTR which arrives here,
  108. # entering the next "except" block -- but the signal
  109. # handler is then called on the next call to
  110. # dispatch_bytecode(), causing the real exception to be
  111. # raised after the exception handler block was popped.
  112. try:
  113. trace = self.w_f_trace
  114. if trace is not None:
  115. self.w_f_trace = None
  116. try:
  117. ec.bytecode_trace_after_exception(self)
  118. finally:
  119. if trace is not None:
  120. self.w_f_trace = trace
  121. except OperationError, e:
  122. operr = e
  123. pytraceback.record_application_traceback(
  124. self.space, operr, self, self.last_instr)
  125. ec.exception_trace(self, operr)
  126. block = self.unrollstack(SApplicationException.kind)
  127. if block is None:
  128. # no handler found for the OperationError
  129. if we_are_translated():
  130. raise operr
  131. else:
  132. # try to preserve the CPython-level traceback
  133. import sys
  134. tb = sys.exc_info()[2]
  135. raise OperationError, operr, tb
  136. else:
  137. unroller = SApplicationException(operr)
  138. next_instr = block.handle(self, unroller)
  139. return next_instr
  140. def call_contextmanager_exit_function(self, w_func, w_typ, w_val, w_tb):
  141. return self.space.call_function(w_func, w_typ, w_val, w_tb)
  142. @jit.unroll_safe
  143. def dispatch_bytecode(self, co_code, next_instr, ec):
  144. space = self.space
  145. while True:
  146. self.last_instr = intmask(next_instr)
  147. if not jit.we_are_jitted():
  148. ec.bytecode_trace(self)
  149. next_instr = r_uint(self.last_instr)
  150. opcode = ord(co_code[next_instr])
  151. next_instr += 1
  152. if opcode >= self.HAVE_ARGUMENT:
  153. lo = ord(co_code[next_instr])
  154. hi = ord(co_code[next_instr+1])
  155. next_instr += 2
  156. oparg = (hi * 256) | lo
  157. else:
  158. oparg = 0
  159. while opcode == self.opcodedesc.EXTENDED_ARG.index:
  160. opcode = ord(co_code[next_instr])
  161. if opcode < self.HAVE_ARGUMENT:
  162. raise BytecodeCorruption
  163. lo = ord(co_code[next_instr+1])
  164. hi = ord(co_code[next_instr+2])
  165. next_instr += 3
  166. oparg = (oparg * 65536) | (hi * 256) | lo
  167. if opcode == self.opcodedesc.RETURN_VALUE.index:
  168. w_returnvalue = self.popvalue()
  169. block = self.unrollstack(SReturnValue.kind)
  170. if block is None:
  171. self.pushvalue(w_returnvalue) # XXX ping pong
  172. raise Return
  173. else:
  174. unroller = SReturnValue(w_returnvalue)
  175. next_instr = block.handle(self, unroller)
  176. return next_instr # now inside a 'finally' block
  177. if opcode == self.opcodedesc.END_FINALLY.index:
  178. unroller = self.end_finally()
  179. if isinstance(unroller, SuspendedUnroller):
  180. # go on unrolling the stack
  181. block = self.unrollstack(unroller.kind)
  182. if block is None:
  183. w_result = unroller.nomoreblocks()
  184. self.pushvalue(w_result)
  185. raise Return
  186. else:
  187. next_instr = block.handle(self, unroller)
  188. return next_instr
  189. if opcode == self.opcodedesc.JUMP_ABSOLUTE.index:
  190. return self.jump_absolute(oparg, ec)
  191. if we_are_translated():
  192. for opdesc in unrolling_all_opcode_descs:
  193. # static checks to skip this whole case if necessary
  194. if opdesc.bytecode_spec is not self.bytecode_spec:
  195. continue
  196. if not opdesc.is_enabled(space):
  197. continue
  198. if opdesc.methodname in (
  199. 'EXTENDED_ARG', 'RETURN_VALUE',
  200. 'END_FINALLY', 'JUMP_ABSOLUTE'):
  201. continue # opcodes implemented above
  202. if opcode == opdesc.index:
  203. # dispatch to the opcode method
  204. meth = getattr(self, opdesc.methodname)
  205. res = meth(oparg, next_instr)
  206. # !! warning, for the annotator the next line is not
  207. # comparing an int and None - you can't do that.
  208. # Instead, it's constant-folded to either True or False
  209. if res is not None:
  210. next_instr = res
  211. break
  212. else:
  213. self.MISSING_OPCODE(oparg, next_instr)
  214. else: # when we are not translated, a list lookup is much faster
  215. methodname = self.opcode_method_names[opcode]
  216. try:
  217. meth = getattr(self, methodname)
  218. except AttributeError:
  219. raise BytecodeCorruption("unimplemented opcode, ofs=%d, "
  220. "code=%d, name=%s" %
  221. (self.last_instr, opcode,
  222. methodname))
  223. try:
  224. res = meth(oparg, next_instr)
  225. except Exception:
  226. if 0:
  227. import dis, sys
  228. print "*** %s at offset %d (%s)" % (sys.exc_info()[0],
  229. self.last_instr,
  230. methodname)
  231. try:
  232. dis.dis(co_code)
  233. except:
  234. pass
  235. raise
  236. if res is not None:
  237. next_instr = res
  238. if jit.we_are_jitted():
  239. return next_instr
  240. @jit.unroll_safe
  241. def unrollstack(self, unroller_kind):
  242. while self.blockstack_non_empty():
  243. block = self.pop_block()
  244. if (block.handling_mask & unroller_kind) != 0:
  245. return block
  246. block.cleanupstack(self)
  247. self.frame_finished_execution = True # for generators
  248. return None
  249. def unrollstack_and_jump(self, unroller):
  250. block = self.unrollstack(unroller.kind)
  251. if block is None:
  252. raise BytecodeCorruption("misplaced bytecode - should not return")
  253. return block.handle(self, unroller)
  254. ### accessor functions ###
  255. def getlocalvarname(self, index):
  256. return self.getcode().co_varnames[index]
  257. def getconstant_w(self, index):
  258. return self.getcode().co_consts_w[index]
  259. def getname_u(self, index):
  260. return self.space.str_w(self.getcode().co_names_w[index])
  261. def getname_w(self, index):
  262. return self.getcode().co_names_w[index]
  263. ################################################################
  264. ## Implementation of the "operational" opcodes
  265. ## See also nestedscope.py for the rest.
  266. ##
  267. def NOP(self, oparg, next_instr):
  268. # annotation-time check: if it fails, it means that the decoding
  269. # of oparg failed to produce an integer which is annotated as non-neg
  270. check_nonneg(oparg)
  271. def LOAD_FAST(self, varindex, next_instr):
  272. # access a local variable directly
  273. w_value = self.locals_stack_w[varindex]
  274. if w_value is None:
  275. self._load_fast_failed(varindex)
  276. self.pushvalue(w_value)
  277. LOAD_FAST._always_inline_ = True
  278. def _load_fast_failed(self, varindex):
  279. varname = self.getlocalvarname(varindex)
  280. message = "local variable '%s' referenced before assignment"
  281. raise operationerrfmt(self.space.w_UnboundLocalError, message, varname)
  282. _load_fast_failed._dont_inline_ = True
  283. def LOAD_CONST(self, constindex, next_instr):
  284. w_const = self.getconstant_w(constindex)
  285. self.pushvalue(w_const)
  286. def STORE_FAST(self, varindex, next_instr):
  287. w_newvalue = self.popvalue()
  288. assert w_newvalue is not None
  289. self.locals_stack_w[varindex] = w_newvalue
  290. def POP_TOP(self, oparg, next_instr):
  291. self.popvalue()
  292. def ROT_TWO(self, oparg, next_instr):
  293. w_1 = self.popvalue()
  294. w_2 = self.popvalue()
  295. self.pushvalue(w_1)
  296. self.pushvalue(w_2)
  297. def ROT_THREE(self, oparg, next_instr):
  298. w_1 = self.popvalue()
  299. w_2 = self.popvalue()
  300. w_3 = self.popvalue()
  301. self.pushvalue(w_1)
  302. self.pushvalue(w_3)
  303. self.pushvalue(w_2)
  304. def ROT_FOUR(self, oparg, next_instr):
  305. w_1 = self.popvalue()
  306. w_2 = self.popvalue()
  307. w_3 = self.popvalue()
  308. w_4 = self.popvalue()
  309. self.pushvalue(w_1)
  310. self.pushvalue(w_4)
  311. self.pushvalue(w_3)
  312. self.pushvalue(w_2)
  313. def DUP_TOP(self, oparg, next_instr):
  314. w_1 = self.peekvalue()
  315. self.pushvalue(w_1)
  316. def DUP_TOPX(self, itemcount, next_instr):
  317. assert 1 <= itemcount <= 5, "limitation of the current interpreter"
  318. self.dupvalues(itemcount)
  319. UNARY_POSITIVE = unaryoperation("pos")
  320. UNARY_NEGATIVE = unaryoperation("neg")
  321. UNARY_NOT = unaryoperation("not_")
  322. UNARY_CONVERT = unaryoperation("repr")
  323. UNARY_INVERT = unaryoperation("invert")
  324. def BINARY_POWER(self, oparg, next_instr):
  325. w_2 = self.popvalue()
  326. w_1 = self.popvalue()
  327. w_result = self.space.pow(w_1, w_2, self.space.w_None)
  328. self.pushvalue(w_result)
  329. BINARY_MULTIPLY = binaryoperation("mul")
  330. BINARY_TRUE_DIVIDE = binaryoperation("truediv")
  331. BINARY_FLOOR_DIVIDE = binaryoperation("floordiv")
  332. BINARY_DIVIDE = binaryoperation("div")
  333. # XXX BINARY_DIVIDE must fall back to BINARY_TRUE_DIVIDE with -Qnew
  334. BINARY_MODULO = binaryoperation("mod")
  335. BINARY_ADD = binaryoperation("add")
  336. BINARY_SUBTRACT = binaryoperation("sub")
  337. BINARY_SUBSCR = binaryoperation("getitem")
  338. BINARY_LSHIFT = binaryoperation("lshift")
  339. BINARY_RSHIFT = binaryoperation("rshift")
  340. BINARY_AND = binaryoperation("and_")
  341. BINARY_XOR = binaryoperation("xor")
  342. BINARY_OR = binaryoperation("or_")
  343. def INPLACE_POWER(self, oparg, next_instr):
  344. w_2 = self.popvalue()
  345. w_1 = self.popvalue()
  346. w_result = self.space.inplace_pow(w_1, w_2)
  347. self.pushvalue(w_result)
  348. INPLACE_MULTIPLY = binaryoperation("inplace_mul")
  349. INPLACE_TRUE_DIVIDE = binaryoperation("inplace_truediv")
  350. INPLACE_FLOOR_DIVIDE = binaryoperation("inplace_floordiv")
  351. INPLACE_DIVIDE = binaryoperation("inplace_div")
  352. # XXX INPLACE_DIVIDE must fall back to INPLACE_TRUE_DIVIDE with -Qnew
  353. INPLACE_MODULO = binaryoperation("inplace_mod")
  354. INPLACE_ADD = binaryoperation("inplace_add")
  355. INPLACE_SUBTRACT = binaryoperation("inplace_sub")
  356. INPLACE_LSHIFT = binaryoperation("inplace_lshift")
  357. INPLACE_RSHIFT = binaryoperation("inplace_rshift")
  358. INPLACE_AND = binaryoperation("inplace_and")
  359. INPLACE_XOR = binaryoperation("inplace_xor")
  360. INPLACE_OR = binaryoperation("inplace_or")
  361. def slice(self, w_start, w_end):
  362. w_obj = self.popvalue()
  363. w_result = self.space.getslice(w_obj, w_start, w_end)
  364. self.pushvalue(w_result)
  365. def SLICE_0(self, oparg, next_instr):
  366. self.slice(self.space.w_None, self.space.w_None)
  367. def SLICE_1(self, oparg, next_instr):
  368. w_start = self.popvalue()
  369. self.slice(w_start, self.space.w_None)
  370. def SLICE_2(self, oparg, next_instr):
  371. w_end = self.popvalue()
  372. self.slice(self.space.w_None, w_end)
  373. def SLICE_3(self, oparg, next_instr):
  374. w_end = self.popvalue()
  375. w_start = self.popvalue()
  376. self.slice(w_start, w_end)
  377. def storeslice(self, w_start, w_end):
  378. w_obj = self.popvalue()
  379. w_newvalue = self.popvalue()
  380. self.space.setslice(w_obj, w_start, w_end, w_newvalue)
  381. def STORE_SLICE_0(self, oparg, next_instr):
  382. self.storeslice(self.space.w_None, self.space.w_None)
  383. def STORE_SLICE_1(self, oparg, next_instr):
  384. w_start = self.popvalue()
  385. self.storeslice(w_start, self.space.w_None)
  386. def STORE_SLICE_2(self, oparg, next_instr):
  387. w_end = self.popvalue()
  388. self.storeslice(self.space.w_None, w_end)
  389. def STORE_SLICE_3(self, oparg, next_instr):
  390. w_end = self.popvalue()
  391. w_start = self.popvalue()
  392. self.storeslice(w_start, w_end)
  393. def deleteslice(self, w_start, w_end):
  394. w_obj = self.popvalue()
  395. self.space.delslice(w_obj, w_start, w_end)
  396. def DELETE_SLICE_0(self, oparg, next_instr):
  397. self.deleteslice(self.space.w_None, self.space.w_None)
  398. def DELETE_SLICE_1(self, oparg, next_instr):
  399. w_start = self.popvalue()
  400. self.deleteslice(w_start, self.space.w_None)
  401. def DELETE_SLICE_2(self, oparg, next_instr):
  402. w_end = self.popvalue()
  403. self.deleteslice(self.space.w_None, w_end)
  404. def DELETE_SLICE_3(self, oparg, next_instr):
  405. w_end = self.popvalue()
  406. w_start = self.popvalue()
  407. self.deleteslice(w_start, w_end)
  408. def STORE_SUBSCR(self, oparg, next_instr):
  409. "obj[subscr] = newvalue"
  410. w_subscr = self.popvalue()
  411. w_obj = self.popvalue()
  412. w_newvalue = self.popvalue()
  413. self.space.setitem(w_obj, w_subscr, w_newvalue)
  414. def DELETE_SUBSCR(self, oparg, next_instr):
  415. "del obj[subscr]"
  416. w_subscr = self.popvalue()
  417. w_obj = self.popvalue()
  418. self.space.delitem(w_obj, w_subscr)
  419. def PRINT_EXPR(self, oparg, next_instr):
  420. w_expr = self.popvalue()
  421. print_expr(self.space, w_expr)
  422. def PRINT_ITEM_TO(self, oparg, next_instr):
  423. w_stream = self.popvalue()
  424. w_item = self.popvalue()
  425. if self.space.is_w(w_stream, self.space.w_None):
  426. w_stream = sys_stdout(self.space) # grumble grumble special cases
  427. print_item_to(self.space, w_item, w_stream)
  428. def PRINT_ITEM(self, oparg, next_instr):
  429. w_item = self.popvalue()
  430. print_item(self.space, w_item)
  431. def PRINT_NEWLINE_TO(self, oparg, next_instr):
  432. w_stream = self.popvalue()
  433. if self.space.is_w(w_stream, self.space.w_None):
  434. w_stream = sys_stdout(self.space) # grumble grumble special cases
  435. print_newline_to(self.space, w_stream)
  436. def PRINT_NEWLINE(self, oparg, next_instr):
  437. print_newline(self.space)
  438. def BREAK_LOOP(self, oparg, next_instr):
  439. return self.unrollstack_and_jump(SBreakLoop.singleton)
  440. def CONTINUE_LOOP(self, startofloop, next_instr):
  441. unroller = SContinueLoop(startofloop)
  442. return self.unrollstack_and_jump(unroller)
  443. @jit.unroll_safe
  444. def RAISE_VARARGS(self, nbargs, next_instr):
  445. space = self.space
  446. if nbargs == 0:
  447. frame = self
  448. ec = self.space.getexecutioncontext()
  449. while frame:
  450. if frame.last_exception is not None:
  451. operror = frame.last_exception
  452. break
  453. frame = frame.f_backref()
  454. else:
  455. raise OperationError(space.w_TypeError,
  456. space.wrap("raise: no active exception to re-raise"))
  457. # re-raise, no new traceback obj will be attached
  458. self.last_exception = operror
  459. raise RaiseWithExplicitTraceback(operror)
  460. w_value = w_traceback = space.w_None
  461. if nbargs >= 3:
  462. w_traceback = self.popvalue()
  463. if nbargs >= 2:
  464. w_value = self.popvalue()
  465. if 1:
  466. w_type = self.popvalue()
  467. operror = OperationError(w_type, w_value)
  468. operror.normalize_exception(space)
  469. if space.is_w(w_traceback, space.w_None):
  470. # common case
  471. raise operror
  472. else:
  473. msg = "raise: arg 3 must be a traceback or None"
  474. tb = pytraceback.check_traceback(space, w_traceback, msg)
  475. operror.set_traceback(tb)
  476. # special 3-arguments raise, no new traceback obj will be attached
  477. raise RaiseWithExplicitTraceback(operror)
  478. def LOAD_LOCALS(self, oparg, next_instr):
  479. self.pushvalue(self.w_locals)
  480. def EXEC_STMT(self, oparg, next_instr):
  481. w_locals = self.popvalue()
  482. w_globals = self.popvalue()
  483. w_prog = self.popvalue()
  484. ec = self.space.getexecutioncontext()
  485. flags = ec.compiler.getcodeflags(self.pycode)
  486. w_compile_flags = self.space.wrap(flags)
  487. w_resulttuple = prepare_exec(self.space, self.space.wrap(self), w_prog,
  488. w_globals, w_locals,
  489. w_compile_flags,
  490. self.space.wrap(self.get_builtin()),
  491. self.space.gettypeobject(PyCode.typedef))
  492. w_prog, w_globals, w_locals = self.space.fixedview(w_resulttuple, 3)
  493. plain = (self.w_locals is not None and
  494. self.space.is_w(w_locals, self.w_locals))
  495. if plain:
  496. w_locals = self.getdictscope()
  497. co = self.space.interp_w(eval.Code, w_prog)
  498. co.exec_code(self.space, w_globals, w_locals)
  499. if plain:
  500. self.setdictscope(w_locals)
  501. def POP_BLOCK(self, oparg, next_instr):
  502. block = self.pop_block()
  503. block.cleanup(self) # the block knows how to clean up the value stack
  504. def end_finally(self):
  505. # unlike CPython, there are two statically distinct cases: the
  506. # END_FINALLY might be closing an 'except' block or a 'finally'
  507. # block. In the first case, the stack contains three items:
  508. # [exception type we are now handling]
  509. # [exception value we are now handling]
  510. # [wrapped SApplicationException]
  511. # In the case of a finally: block, the stack contains only one
  512. # item (unlike CPython which can have 1, 2 or 3 items):
  513. # [wrapped subclass of SuspendedUnroller]
  514. w_top = self.popvalue()
  515. # the following logic is a mess for the flow objspace,
  516. # so we hide it specially in the space :-/
  517. if self.space._check_constant_interp_w_or_w_None(SuspendedUnroller, w_top):
  518. # case of a finally: block
  519. unroller = self.space.interpclass_w(w_top)
  520. return unroller
  521. else:
  522. # case of an except: block. We popped the exception type
  523. self.popvalue() # Now we pop the exception value
  524. unroller = self.space.interpclass_w(self.popvalue())
  525. assert unroller is not None
  526. return unroller
  527. def BUILD_CLASS(self, oparg, next_instr):
  528. w_methodsdict = self.popvalue()
  529. w_bases = self.popvalue()
  530. w_name = self.popvalue()
  531. w_metaclass = find_metaclass(self.space, w_bases,
  532. w_methodsdict, self.w_globals,
  533. self.space.wrap(self.get_builtin()))
  534. w_newclass = self.space.call_function(w_metaclass, w_name,
  535. w_bases, w_methodsdict)
  536. self.pushvalue(w_newclass)
  537. def STORE_NAME(self, varindex, next_instr):
  538. varname = self.getname_u(varindex)
  539. w_newvalue = self.popvalue()
  540. self.space.setitem_str(self.w_locals, varname, w_newvalue)
  541. def DELETE_NAME(self, varindex, next_instr):
  542. w_varname = self.getname_w(varindex)
  543. try:
  544. self.space.delitem(self.w_locals, w_varname)
  545. except OperationError, e:
  546. # catch KeyErrors and turn them into NameErrors
  547. if not e.match(self.space, self.space.w_KeyError):
  548. raise
  549. message = "name '%s' is not defined"
  550. raise operationerrfmt(self.space.w_NameError, message,
  551. self.space.str_w(w_varname))
  552. def UNPACK_SEQUENCE(self, itemcount, next_instr):
  553. w_iterable = self.popvalue()
  554. items = self.space.fixedview_unroll(w_iterable, itemcount)
  555. self.pushrevvalues(itemcount, items)
  556. def STORE_ATTR(self, nameindex, next_instr):
  557. "obj.attributename = newvalue"
  558. w_attributename = self.getname_w(nameindex)
  559. w_obj = self.popvalue()
  560. w_newvalue = self.popvalue()
  561. self.space.setattr(w_obj, w_attributename, w_newvalue)
  562. def DELETE_ATTR(self, nameindex, next_instr):
  563. "del obj.attributename"
  564. w_attributename = self.getname_w(nameindex)
  565. w_obj = self.popvalue()
  566. self.space.delattr(w_obj, w_attributename)
  567. def STORE_GLOBAL(self, nameindex, next_instr):
  568. varname = self.getname_u(nameindex)
  569. w_newvalue = self.popvalue()
  570. self.space.setitem_str(self.w_globals, varname, w_newvalue)
  571. def DELETE_GLOBAL(self, nameindex, next_instr):
  572. w_varname = self.getname_w(nameindex)
  573. self.space.delitem(self.w_globals, w_varname)
  574. def LOAD_NAME(self, nameindex, next_instr):
  575. if self.w_locals is not self.w_globals:
  576. w_varname = self.getname_w(nameindex)
  577. w_value = self.space.finditem(self.w_locals, w_varname)
  578. if w_value is not None:
  579. self.pushvalue(w_value)
  580. return
  581. self.LOAD_GLOBAL(nameindex, next_instr) # fall-back
  582. def _load_global(self, varname):
  583. w_value = self.space.finditem_str(self.w_globals, varname)
  584. if w_value is None:
  585. # not in the globals, now look in the built-ins
  586. w_value = self.get_builtin().getdictvalue(self.space, varname)
  587. if w_value is None:
  588. self._load_global_failed(varname)
  589. return w_value
  590. _load_global._always_inline_ = True
  591. def _load_global_failed(self, varname):
  592. message = "global name '%s' is not defined"
  593. raise operationerrfmt(self.space.w_NameError, message, varname)
  594. _load_global_failed._dont_inline_ = True
  595. def LOAD_GLOBAL(self, nameindex, next_instr):
  596. self.pushvalue(self._load_global(self.getname_u(nameindex)))
  597. LOAD_GLOBAL._always_inline_ = True
  598. def DELETE_FAST(self, varindex, next_instr):
  599. if self.locals_stack_w[varindex] is None:
  600. varname = self.getlocalvarname(varindex)
  601. message = "local variable '%s' referenced before assignment"
  602. raise operationerrfmt(self.space.w_UnboundLocalError, message,
  603. varname)
  604. self.locals_stack_w[varindex] = None
  605. def BUILD_TUPLE(self, itemcount, next_instr):
  606. items = self.popvalues(itemcount)
  607. w_tuple = self.space.newtuple(items)
  608. self.pushvalue(w_tuple)
  609. def BUILD_LIST(self, itemcount, next_instr):
  610. items = self.popvalues_mutable(itemcount)
  611. w_list = self.space.newlist(items)
  612. self.pushvalue(w_list)
  613. def BUILD_LIST_FROM_ARG(self, _, next_instr):
  614. # this is a little dance, because list has to be before the
  615. # value
  616. last_val = self.popvalue()
  617. try:
  618. lgt = self.space.len_w(last_val)
  619. except OperationError, e:
  620. if e.async(self.space):
  621. raise
  622. lgt = 0 # oh well
  623. self.pushvalue(self.space.newlist([], sizehint=lgt))
  624. self.pushvalue(last_val)
  625. def LOAD_ATTR(self, nameindex, next_instr):
  626. "obj.attributename"
  627. w_obj = self.popvalue()
  628. if (self.space.config.objspace.std.withmapdict
  629. and not jit.we_are_jitted()):
  630. from pypy.objspace.std.mapdict import LOAD_ATTR_caching
  631. w_value = LOAD_ATTR_caching(self.getcode(), w_obj, nameindex)
  632. else:
  633. w_attributename = self.getname_w(nameindex)
  634. w_value = self.space.getattr(w_obj, w_attributename)
  635. self.pushvalue(w_value)
  636. LOAD_ATTR._always_inline_ = True
  637. def cmp_lt(self, w_1, w_2):
  638. return self.space.lt(w_1, w_2)
  639. def cmp_le(self, w_1, w_2):
  640. return self.space.le(w_1, w_2)
  641. def cmp_eq(self, w_1, w_2):
  642. return self.space.eq(w_1, w_2)
  643. def cmp_ne(self, w_1, w_2):
  644. return self.space.ne(w_1, w_2)
  645. def cmp_gt(self, w_1, w_2):
  646. return self.space.gt(w_1, w_2)
  647. def cmp_ge(self, w_1, w_2):
  648. return self.space.ge(w_1, w_2)
  649. def cmp_in(self, w_1, w_2):
  650. return self.space.contains(w_2, w_1)
  651. def cmp_not_in(self, w_1, w_2):
  652. return self.space.not_(self.space.contains(w_2, w_1))
  653. def cmp_is(self, w_1, w_2):
  654. return self.space.is_(w_1, w_2)
  655. def cmp_is_not(self, w_1, w_2):
  656. return self.space.not_(self.space.is_(w_1, w_2))
  657. @jit.unroll_safe
  658. def cmp_exc_match(self, w_1, w_2):
  659. if self.space.is_true(self.space.isinstance(w_2, self.space.w_tuple)):
  660. for w_t in self.space.fixedview(w_2):
  661. if self.space.is_true(self.space.isinstance(w_t,
  662. self.space.w_str)):
  663. self.space.warn("catching of string exceptions is "
  664. "deprecated",
  665. self.space.w_DeprecationWarning)
  666. elif self.space.is_true(self.space.isinstance(w_2, self.space.w_str)):
  667. self.space.warn("catching of string exceptions is deprecated",
  668. self.space.w_DeprecationWarning)
  669. return self.space.newbool(self.space.exception_match(w_1, w_2))
  670. def COMPARE_OP(self, testnum, next_instr):
  671. w_2 = self.popvalue()
  672. w_1 = self.popvalue()
  673. w_result = None
  674. for i, attr in unrolling_compare_dispatch_table:
  675. if i == testnum:
  676. w_result = getattr(self, attr)(w_1, w_2)
  677. break
  678. else:
  679. raise BytecodeCorruption, "bad COMPARE_OP oparg"
  680. self.pushvalue(w_result)
  681. def IMPORT_NAME(self, nameindex, next_instr):
  682. space = self.space
  683. w_modulename = self.getname_w(nameindex)
  684. modulename = self.space.str_w(w_modulename)
  685. w_fromlist = self.popvalue()
  686. w_flag = self.popvalue()
  687. try:
  688. if space.int_w(w_flag) == -1:
  689. w_flag = None
  690. except OperationError, e:
  691. if e.async(space):
  692. raise
  693. w_import = self.get_builtin().getdictvalue(space, '__import__')
  694. if w_import is None:
  695. raise OperationError(space.w_ImportError,
  696. space.wrap("__import__ not found"))
  697. w_locals = self.w_locals
  698. if w_locals is None: # CPython does this
  699. w_locals = space.w_None
  700. w_modulename = space.wrap(modulename)
  701. w_globals = self.w_globals
  702. if w_flag is None:
  703. w_obj = space.call_function(w_import, w_modulename, w_globals,
  704. w_locals, w_fromlist)
  705. else:
  706. w_obj = space.call_function(w_import, w_modulename, w_globals,
  707. w_locals, w_fromlist, w_flag)
  708. self.pushvalue(w_obj)
  709. def IMPORT_STAR(self, oparg, next_instr):
  710. w_module = self.popvalue()
  711. w_locals = self.getdictscope()
  712. import_all_from(self.space, w_module, w_locals)
  713. self.setdictscope(w_locals)
  714. def IMPORT_FROM(self, nameindex, next_instr):
  715. w_name = self.getname_w(nameindex)
  716. w_module = self.peekvalue()
  717. try:
  718. w_obj = self.space.getattr(w_module, w_name)
  719. except OperationError, e:
  720. if not e.match(self.space, self.space.w_AttributeError):
  721. raise
  722. raise operationerrfmt(self.space.w_ImportError,
  723. "cannot import name '%s'",
  724. self.space.str_w(w_name))
  725. self.pushvalue(w_obj)
  726. def YIELD_VALUE(self, oparg, next_instr):
  727. raise Yield
  728. def jump_absolute(self, jumpto, ec):
  729. # this function is overridden by pypy.module.pypyjit.interp_jit
  730. check_nonneg(jumpto)
  731. return jumpto
  732. def JUMP_FORWARD(self, jumpby, next_instr):
  733. next_instr += jumpby
  734. return next_instr
  735. def POP_JUMP_IF_FALSE(self, target, next_instr):
  736. w_value = self.popvalue()
  737. if not self.space.is_true(w_value):
  738. return target
  739. return next_instr
  740. def POP_JUMP_IF_TRUE(self, target, next_instr):
  741. w_value = self.popvalue()
  742. if self.space.is_true(w_value):
  743. return target
  744. return next_instr
  745. def JUMP_IF_FALSE_OR_POP(self, target, next_instr):
  746. w_value = self.peekvalue()
  747. if not self.space.is_true(w_value):
  748. return target
  749. self.popvalue()
  750. return next_instr
  751. def JUMP_IF_TRUE_OR_POP(self, target, next_instr):
  752. w_value = self.peekvalue()
  753. if self.space.is_true(w_value):
  754. return target
  755. self.popvalue()
  756. return next_instr
  757. def GET_ITER(self, oparg, next_instr):
  758. w_iterable = self.popvalue()
  759. w_iterator = self.space.iter(w_iterable)
  760. self.pushvalue(w_iterator)
  761. def FOR_ITER(self, jumpby, next_instr):
  762. w_iterator = self.peekvalue()
  763. try:
  764. w_nextitem = self.space.next(w_iterator)
  765. except OperationError, e:
  766. if not e.match(self.space, self.space.w_StopIteration):
  767. raise
  768. # iterator exhausted
  769. self.popvalue()
  770. next_instr += jumpby
  771. else:
  772. self.pushvalue(w_nextitem)
  773. return next_instr
  774. def FOR_LOOP(self, oparg, next_instr):
  775. raise BytecodeCorruption, "old opcode, no longer in use"
  776. def SETUP_LOOP(self, offsettoend, next_instr):
  777. block = LoopBlock(self, next_instr + offsettoend, self.lastblock)
  778. self.lastblock = block
  779. def SETUP_EXCEPT(self, offsettoend, next_instr):
  780. block = ExceptBlock(self, next_instr + offsettoend, self.lastblock)
  781. self.lastblock = block
  782. def SETUP_FINALLY(self, offsettoend, next_instr):
  783. block = FinallyBlock(self, next_instr + offsettoend, self.lastblock)
  784. self.lastblock = block
  785. def SETUP_WITH(self, offsettoend, next_instr):
  786. w_manager = self.peekvalue()
  787. w_enter = self.space.lookup(w_manager, "__enter__")
  788. w_descr = self.space.lookup(w_manager, "__exit__")
  789. if w_enter is None or w_descr is None:
  790. typename = self.space.type(w_manager).getname(self.space)
  791. raise operationerrfmt(self.space.w_AttributeError,
  792. "'%s' object is not a context manager"
  793. " (no __enter__/__exit__ method)", typename)
  794. w_exit = self.space.get(w_descr, w_manager)
  795. self.settopvalue(w_exit)
  796. w_result = self.space.get_and_call_function(w_enter, w_manager)
  797. block = WithBlock(self, next_instr + offsettoend, self.lastblock)
  798. self.lastblock = block
  799. self.pushvalue(w_result)
  800. def WITH_CLEANUP(self, oparg, next_instr):
  801. # see comment in END_FINALLY for stack state
  802. w_unroller = self.popvalue()
  803. w_exitfunc = self.popvalue()
  804. self.pushvalue(w_unroller)
  805. unroller = self.space.interpclass_w(w_unroller)
  806. is_app_exc = (unroller is not None and
  807. isinstance(unroller, SApplicationException))
  808. if is_app_exc:
  809. operr = unroller.operr
  810. self.last_exception = operr
  811. w_traceback = self.space.wrap(operr.get_traceback())
  812. w_suppress = self.call_contextmanager_exit_function(
  813. w_exitfunc,
  814. operr.w_type,
  815. operr.get_w_value(self.space),
  816. w_traceback)
  817. if self.space.is_true(w_suppress):
  818. # __exit__() returned True -> Swallow the exception.
  819. self.settopvalue(self.space.w_None)
  820. else:
  821. self.call_contextmanager_exit_function(
  822. w_exitfunc,
  823. self.space.w_None,
  824. self.space.w_None,
  825. self.space.w_None)
  826. @jit.unroll_safe
  827. def call_function(self, oparg, w_star=None, w_starstar=None):
  828. n_arguments = oparg & 0xff
  829. n_keywords = (oparg>>8) & 0xff
  830. if n_keywords:
  831. keywords = [None] * n_keywords
  832. keywords_w = [None] * n_keywords
  833. while True:
  834. n_keywords -= 1
  835. if n_keywords < 0:
  836. break
  837. w_value = self.popvalue()
  838. w_key = self.popvalue()
  839. key = self.space.str_w(w_key)
  840. keywords[n_keywords] = key
  841. keywords_w[n_keywords] = w_value
  842. else:
  843. keywords = None
  844. keywords_w = None
  845. arguments = self.popvalues(n_arguments)
  846. args = self.argument_factory(arguments, keywords, keywords_w, w_star,
  847. w_starstar)
  848. w_function = self.popvalue()
  849. if self.is_being_profiled and function.is_builtin_code(w_function):
  850. w_result = self.space.call_args_and_c_profile(self, w_function,
  851. args)
  852. else:
  853. w_result = self.space.call_args(w_function, args)
  854. self.pushvalue(w_result)
  855. def CALL_FUNCTION(self, oparg, next_instr):
  856. # XXX start of hack for performance
  857. if (oparg >> 8) & 0xff == 0:
  858. # Only positional arguments
  859. nargs = oparg & 0xff
  860. w_function = self.peekvalue(nargs)
  861. try:
  862. w_result = self.space.call_valuestack(w_function, nargs, self)
  863. finally:
  864. self.dropvalues(nargs + 1)
  865. self.pushvalue(w_result)
  866. # XXX end of hack for performance
  867. else:
  868. # general case
  869. self.call_function(oparg)
  870. def CALL_FUNCTION_VAR(self, oparg, next_instr):
  871. w_varargs = self.popvalue()
  872. self.call_function(oparg, w_varargs)
  873. def CALL_FUNCTION_KW(self, oparg, next_instr):
  874. w_varkw = self.popvalue()
  875. self.call_function(oparg, None, w_varkw)
  876. def CALL_FUNCTION_VAR_KW(self, oparg, next_instr):
  877. w_varkw = self.popvalue()
  878. w_varargs = self.popvalue()
  879. self.call_function(oparg, w_varargs, w_varkw)
  880. def MAKE_FUNCTION(self, numdefaults, next_instr):
  881. w_codeobj = self.popvalue()
  882. codeobj = self.space.interp_w(PyCode, w_codeobj)
  883. defaultarguments = self.popvalues(numdefaults)
  884. fn = function.Function(self.space, codeobj, self.w_globals,
  885. defaultarguments)
  886. self.pushvalue(self.space.wrap(fn))
  887. def BUILD_SLICE(self, numargs, next_instr):
  888. if numargs == 3:
  889. w_step = self.popvalue()
  890. elif numargs == 2:
  891. w_step = self.space.w_None
  892. else:
  893. raise BytecodeCorruption
  894. w_end = self.popvalue()
  895. w_start = self.popvalue()
  896. w_slice = self.space.newslice(w_start, w_end, w_step)
  897. self.pushvalue(w_slice)
  898. def LIST_APPEND(self, oparg, next_instr):
  899. w = self.popvalue()
  900. v = self.peekvalue(oparg - 1)
  901. self.space.call_method(v, 'append', w)
  902. def SET_ADD(self, oparg, next_instr):
  903. w_value = self.popvalue()
  904. w_set = self.peekvalue(oparg - 1)
  905. self.space.call_method(w_set, 'add', w_value)
  906. def MAP_ADD(self, oparg, next_instr):
  907. w_key = self.popvalue()
  908. w_value = self.popvalue()
  909. w_dict = self.peekvalue(oparg - 1)
  910. self.space.setitem(w_dict, w_key, w_value)
  911. def SET_LINENO(self, lineno, next_instr):
  912. pass
  913. # overridden by faster version in the standard object space.
  914. LOOKUP_METHOD = LOAD_ATTR
  915. CALL_METHOD = CALL_FUNCTION
  916. def MISSING_OPCODE(self, oparg, next_instr):
  917. ofs = self.last_instr
  918. c = self.pycode.co_code[ofs]
  919. name = self.pycode.co_name
  920. raise BytecodeCorruption("unknown opcode, ofs=%d, code=%d, name=%s" %
  921. (ofs, ord(c), name) )
  922. STOP_CODE = MISSING_OPCODE
  923. def BUILD_MAP(self, itemcount, next_instr):
  924. w_dict = self.space.newdict()
  925. self.pushvalue(w_dict)
  926. @jit.unroll_safe
  927. def BUILD_SET(self, itemcount, next_instr):
  928. w_set = self.space.newset()
  929. for i in range(itemcount):
  930. w_item = self.popvalue()
  931. self.space.call_method(w_set, 'add', w_item)
  932. self.pushvalue(w_set)
  933. def STORE_MAP(self, oparg, next_instr):
  934. w_key = self.popvalue()
  935. w_value = self.popvalue()
  936. w_dict = self.peekvalue()
  937. self.space.setitem(w_dict, w_key, w_value)
  938. class __extend__(pyframe.CPythonFrame):
  939. def JUMP_IF_FALSE(self, stepby, next_instr):
  940. w_cond = self.peekvalue()
  941. if not self.space.is_true(w_cond):
  942. next_instr += stepby
  943. return next_instr
  944. def JUMP_IF_TRUE(self, stepby, next_instr):
  945. w_cond = self.peekvalue()
  946. if self.space.is_true(w_cond):
  947. next_instr += stepby
  948. return next_instr
  949. def BUILD_MAP(self, itemcount, next_instr):
  950. if sys.version_info >= (2, 6):
  951. # We could pre-allocate a dict here
  952. # but for the moment this code is not translated.
  953. pass
  954. else:
  955. if itemcount != 0:
  956. raise BytecodeCorruption
  957. w_dict = self.space.newdict()
  958. self.pushvalue(w_dict)
  959. def STORE_MAP(self, zero, next_instr):
  960. if sys.version_info >= (2, 6):
  961. w_key = self.popvalue()
  962. w_value = self.popvalue()
  963. w_dict = self.peekvalue()
  964. self.space.setitem(w_dict, w_key, w_value)
  965. else:
  966. raise BytecodeCorruption
  967. def LIST_APPEND(self, oparg, next_instr):
  968. w = self.popvalue()
  969. if sys.version_info < (2, 7):
  970. v = self.popvalue()
  971. else:
  972. v = self.peekvalue(oparg - 1)
  973. self.space.call_method(v, 'append', w)
  974. ### ____________________________________________________________ ###
  975. class ExitFrame(Exception):
  976. pass
  977. class Return(ExitFrame):
  978. """Raised when exiting a frame via a 'return' statement."""
  979. class Yield(ExitFrame):
  980. """Raised when exiting a frame via a 'yield' statement."""
  981. class RaiseWithExplicitTraceback(Exception):
  982. """Raised at interp-level by a 0- or 3-arguments 'raise' statement."""
  983. def __init__(self, operr):
  984. self.operr = operr
  985. ### Frame Blocks ###
  986. class SuspendedUnroller(Wrappable):
  987. """Abstract base class for interpreter-level objects that
  988. instruct the interpreter to change the control flow and the
  989. block stack.
  990. The concrete subclasses correspond to the various values WHY_XXX
  991. values of the why_code enumeration in ceval.c:
  992. WHY_NOT, OK, not this one :-)
  993. WHY_EXCEPTION, SApplicationException
  994. WHY_RERAISE, implemented differently, see Reraise
  995. WHY_RETURN, SReturnValue
  996. WHY_BREAK, SBreakLoop
  997. WHY_CONTINUE, SContinueLoop
  998. WHY_YIELD not needed
  999. """
  1000. _immutable_ = True
  1001. def nomoreblocks(self):
  1002. raise BytecodeCorruption("misplaced bytecode - should not return")
  1003. class SReturnValue(SuspendedUnroller):
  1004. """Signals a 'return' statement.
  1005. Argument is the wrapped object to return."""
  1006. _immutable_ = True
  1007. kind = 0x01
  1008. def __init__(self, w_returnvalue):
  1009. self.w_returnvalue = w_returnvalue
  1010. def nomoreblocks(self):
  1011. return self.w_returnvalue
  1012. class SApplicationException(SuspendedUnroller):
  1013. """Signals an application-level exception
  1014. (i.e. an OperationException)."""
  1015. _immutable_ = True
  1016. kind = 0x02
  1017. def __init__(self, operr):
  1018. self.operr = operr
  1019. def nomoreblocks(self):
  1020. raise RaiseWithExplicitTraceback(self.operr)
  1021. class SBreakLoop(SuspendedUnroller):
  1022. """Signals a 'break' statement."""
  1023. _immutable_ = True
  1024. kind = 0x04
  1025. SBreakLoop.singleton = SBreakLoop()
  1026. class SContinueLoop(SuspendedUnroller):
  1027. """Signals a 'continue' statement.
  1028. Argument is the bytecode position of the beginning of the loop."""
  1029. _immutable_ = True
  1030. kind = 0x08
  1031. def __init__(self, jump_to):
  1032. self.jump_to = jump_to
  1033. class FrameBlock(object):
  1034. """Abstract base class for frame blocks from the blockstack,
  1035. used by the SETUP_XXX and POP_BLOCK opcodes."""
  1036. _immutable_ = True
  1037. def __init__(self, frame, handlerposition, previous):
  1038. self.handlerposition = handlerposition
  1039. self.valuestackdepth = frame.valuestackdepth
  1040. self.previous = previous # this makes a linked list of blocks
  1041. def __eq__(self, other):
  1042. return (self.__class__ is other.__class__ and
  1043. self.handlerposition == other.handlerposition and
  1044. self.valuestackdepth == other.valuestackdepth)
  1045. def __ne__(self, other):
  1046. return not (self == other)
  1047. def __hash__(self):
  1048. return hash((self.handlerposition, self.valuestackdepth))
  1049. def cleanupstack(self, frame):
  1050. frame.dropvaluesuntil(self.valuestackdepth)
  1051. def cleanup(self, frame):
  1052. "Clean up a frame when we normally exit the block."
  1053. self.cleanupstack(frame)
  1054. # internal pickling interface, not using the standard protocol
  1055. def _get_state_(self, space):
  1056. w = space.wrap
  1057. return space.newtuple([w(self._opname), w(self.handlerposition),
  1058. w(self.valuestackdepth)])
  1059. def handle(self, frame, unroller):
  1060. """ Purely abstract method
  1061. """
  1062. raise NotImplementedError
  1063. class LoopBlock(FrameBlock):
  1064. """A loop block. Stores the end-of-loop pointer in case of 'break'."""
  1065. _immutable_ = True
  1066. _opname = 'SETUP_LOOP'
  1067. handling_mask = SBreakLoop.kind | SContinueLoop.kind
  1068. def handle(self, frame, unroller):
  1069. if isinstance(unroller, SContinueLoop):
  1070. # re-push the loop block without cleaning up the value stack,
  1071. # and jump to the beginning of the loop, stored in the
  1072. # exception's argument
  1073. frame.append_block(self)
  1074. jumpto = unroller.jump_to
  1075. ec = frame.space.getexecutioncontext()
  1076. return r_uint(frame.jump_absolute(jumpto, ec))
  1077. else:
  1078. # jump to the end of the loop
  1079. self.cleanupstack(frame)
  1080. return r_uint(self.handlerposition)
  1081. class ExceptBlock(FrameBlock):
  1082. """An try:except: block. Stores the position of the exception handler."""
  1083. _immutable_ = True
  1084. _opname = 'SETUP_EXCEPT'
  1085. handling_mask = SApplicationException.kind
  1086. def handle(self, frame, unroller):
  1087. # push the exception to the value stack for inspection by the
  1088. # exception handler (the code after the except:)
  1089. self.cleanupstack(frame)
  1090. assert isinstance(unroller, SApplicationException)
  1091. operationerr = unroller.operr
  1092. operationerr.normalize_exception(frame.space)
  1093. # the stack setup is slightly different than in CPython:
  1094. # instead of the traceback, we store the unroller object,
  1095. # wrapped.
  1096. frame.pushvalue(frame.space.wrap(unroller))
  1097. frame.pushvalue(operationerr.get_w_value(frame.space))
  1098. frame.pushvalue(operationerr.w_type)
  1099. frame.last_exception = operationerr
  1100. return r_uint(self.handlerposition) # jump to the handler
  1101. class FinallyBlock(FrameBlock):
  1102. """A try:finally: block. Stores the position of the exception handler."""
  1103. _immutable_ = True
  1104. _opname = 'SETUP_FINALLY'
  1105. handling_mask = -1 # handles every kind of SuspendedUnroller
  1106. def handle(self, frame, unroller):
  1107. # any abnormal reason for unrolling a finally: triggers the end of
  1108. # the block unrolling and the entering the finally: handler.
  1109. # see comments in cleanup().
  1110. self.cleanupstack(frame)
  1111. frame.pushvalue(frame.space.wrap(unroller))
  1112. return r_uint(self.handlerposition) # jump to the handler
  1113. class WithBlock(FinallyBlock):
  1114. _immutable_ = True
  1115. def handle(self, frame, unroller):
  1116. if isinstance(unroller, SApplicationException):
  1117. unroller.operr.normalize_exception(frame.space)
  1118. return FinallyBlock.handle(self, frame, unroller)
  1119. block_classes = {'SETUP_LOOP': LoopBlock,
  1120. 'SETUP_EXCEPT': ExceptBlock,
  1121. 'SETUP_FINALLY': FinallyBlock,
  1122. 'SETUP_WITH': WithBlock,
  1123. }
  1124. ### helpers written at the application-level ###
  1125. # Some of these functions are expected to be generally useful if other
  1126. # parts of the code need to do the same thing as a non-trivial opcode,
  1127. # like finding out which metaclass a new class should have.
  1128. # This is why they are not methods of PyFrame.
  1129. # There are also a couple of helpers that are methods, defined in the
  1130. # class above.
  1131. app = gateway.applevel(r'''
  1132. """ applevel imp…

Large files files are truncated, but you can click here to view the full file