PageRenderTime 43ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/jit/metainterp/optimizeopt/test/test_util.py

https://bitbucket.org/pypy/pypy/
Python | 498 lines | 494 code | 4 blank | 0 comment | 2 complexity | 596a444a2d082f4551d64a45e935178f MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py, random
  2. from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr
  3. from pypy.rpython.ootypesystem import ootype
  4. from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
  5. from pypy.rpython.rclass import FieldListAccessor, IR_QUASIIMMUTABLE
  6. from pypy.jit.backend.llgraph import runner
  7. from pypy.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstPtr,
  8. Const, TreeLoop, BoxObj,
  9. ConstObj, AbstractDescr,
  10. JitCellToken, TargetToken)
  11. from pypy.jit.metainterp.optimizeopt.util import sort_descrs, equaloplists
  12. from pypy.jit.metainterp.optimize import InvalidLoop
  13. from pypy.jit.codewriter.effectinfo import EffectInfo
  14. from pypy.jit.codewriter.heaptracker import register_known_gctype, adr2int
  15. from pypy.jit.tool.oparser import parse, pure_parse
  16. from pypy.jit.metainterp.quasiimmut import QuasiImmutDescr
  17. from pypy.jit.metainterp import compile, resume, history
  18. from pypy.jit.metainterp.jitprof import EmptyProfiler
  19. from pypy.config.pypyoption import get_pypy_config
  20. from pypy.jit.metainterp.resoperation import rop, opname, ResOperation
  21. from pypy.jit.metainterp.optimizeopt.unroll import Inliner
  22. def test_sort_descrs():
  23. class PseudoDescr(AbstractDescr):
  24. def __init__(self, n):
  25. self.n = n
  26. def sort_key(self):
  27. return self.n
  28. for i in range(17):
  29. lst = [PseudoDescr(j) for j in range(i)]
  30. lst2 = lst[:]
  31. random.shuffle(lst2)
  32. sort_descrs(lst2)
  33. assert lst2 == lst
  34. def test_equaloplists():
  35. ops = """
  36. [i0]
  37. i1 = int_add(i0, 1)
  38. i2 = int_add(i1, 1)
  39. guard_true(i1) [i2]
  40. jump(i1)
  41. """
  42. namespace = {}
  43. loop1 = pure_parse(ops, namespace=namespace)
  44. loop2 = pure_parse(ops, namespace=namespace)
  45. loop3 = pure_parse(ops.replace("i2 = int_add", "i2 = int_sub"),
  46. namespace=namespace)
  47. assert equaloplists(loop1.operations, loop2.operations)
  48. py.test.raises(AssertionError,
  49. "equaloplists(loop1.operations, loop3.operations)")
  50. def test_equaloplists_fail_args():
  51. ops = """
  52. [i0]
  53. i1 = int_add(i0, 1)
  54. i2 = int_add(i1, 1)
  55. guard_true(i1) [i2, i1]
  56. jump(i1)
  57. """
  58. namespace = {}
  59. loop1 = pure_parse(ops, namespace=namespace)
  60. loop2 = pure_parse(ops.replace("[i2, i1]", "[i1, i2]"),
  61. namespace=namespace)
  62. py.test.raises(AssertionError,
  63. "equaloplists(loop1.operations, loop2.operations)")
  64. assert equaloplists(loop1.operations, loop2.operations,
  65. strict_fail_args=False)
  66. loop3 = pure_parse(ops.replace("[i2, i1]", "[i2, i0]"),
  67. namespace=namespace)
  68. py.test.raises(AssertionError,
  69. "equaloplists(loop1.operations, loop3.operations)")
  70. # ____________________________________________________________
  71. class LLtypeMixin(object):
  72. type_system = 'lltype'
  73. def get_class_of_box(self, box):
  74. return box.getref(rclass.OBJECTPTR).typeptr
  75. node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  76. node_vtable.name = rclass.alloc_array_name('node')
  77. node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
  78. node_vtable2 = lltype.malloc(OBJECT_VTABLE, immortal=True)
  79. node_vtable2.name = rclass.alloc_array_name('node2')
  80. node_vtable_adr2 = llmemory.cast_ptr_to_adr(node_vtable2)
  81. cpu = runner.LLtypeCPU(None)
  82. NODE = lltype.GcForwardReference()
  83. NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT),
  84. ('value', lltype.Signed),
  85. ('floatval', lltype.Float),
  86. ('next', lltype.Ptr(NODE))))
  87. NODE2 = lltype.GcStruct('NODE2', ('parent', NODE),
  88. ('other', lltype.Ptr(NODE)))
  89. node = lltype.malloc(NODE)
  90. node.parent.typeptr = node_vtable
  91. node2 = lltype.malloc(NODE2)
  92. node2.parent.parent.typeptr = node_vtable2
  93. nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
  94. myptr = nodebox.value
  95. myptr2 = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(NODE))
  96. nullptr = lltype.nullptr(llmemory.GCREF.TO)
  97. nodebox2 = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node2))
  98. nodesize = cpu.sizeof(NODE)
  99. nodesize2 = cpu.sizeof(NODE2)
  100. valuedescr = cpu.fielddescrof(NODE, 'value')
  101. floatdescr = cpu.fielddescrof(NODE, 'floatval')
  102. nextdescr = cpu.fielddescrof(NODE, 'next')
  103. otherdescr = cpu.fielddescrof(NODE2, 'other')
  104. accessor = FieldListAccessor()
  105. accessor.initialize(None, {'inst_field': IR_QUASIIMMUTABLE})
  106. QUASI = lltype.GcStruct('QUASIIMMUT', ('inst_field', lltype.Signed),
  107. ('mutate_field', rclass.OBJECTPTR),
  108. hints={'immutable_fields': accessor})
  109. quasisize = cpu.sizeof(QUASI)
  110. quasi = lltype.malloc(QUASI, immortal=True)
  111. quasi.inst_field = -4247
  112. quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field')
  113. quasibox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, quasi))
  114. quasiimmutdescr = QuasiImmutDescr(cpu, quasibox,
  115. quasifielddescr,
  116. cpu.fielddescrof(QUASI, 'mutate_field'))
  117. NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT),
  118. ('ref', lltype.Ptr(OBJECT)))
  119. nodeobj = lltype.malloc(NODEOBJ)
  120. nodeobjvalue = lltype.cast_opaque_ptr(llmemory.GCREF, nodeobj)
  121. refdescr = cpu.fielddescrof(NODEOBJ, 'ref')
  122. INTOBJ_NOIMMUT = lltype.GcStruct('INTOBJ_NOIMMUT', ('parent', OBJECT),
  123. ('intval', lltype.Signed))
  124. INTOBJ_IMMUT = lltype.GcStruct('INTOBJ_IMMUT', ('parent', OBJECT),
  125. ('intval', lltype.Signed),
  126. hints={'immutable': True})
  127. intobj_noimmut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  128. intobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  129. noimmut_intval = cpu.fielddescrof(INTOBJ_NOIMMUT, 'intval')
  130. immut_intval = cpu.fielddescrof(INTOBJ_IMMUT, 'intval')
  131. PTROBJ_IMMUT = lltype.GcStruct('PTROBJ_IMMUT', ('parent', OBJECT),
  132. ('ptrval', lltype.Ptr(OBJECT)),
  133. hints={'immutable': True})
  134. ptrobj_immut_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  135. immut_ptrval = cpu.fielddescrof(PTROBJ_IMMUT, 'ptrval')
  136. arraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Signed))
  137. floatarraydescr = cpu.arraydescrof(lltype.GcArray(lltype.Float))
  138. # a GcStruct not inheriting from OBJECT
  139. S = lltype.GcStruct('TUPLE', ('a', lltype.Signed), ('b', lltype.Ptr(NODE)))
  140. ssize = cpu.sizeof(S)
  141. adescr = cpu.fielddescrof(S, 'a')
  142. bdescr = cpu.fielddescrof(S, 'b')
  143. sbox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, lltype.malloc(S)))
  144. arraydescr2 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(S)))
  145. T = lltype.GcStruct('TUPLE',
  146. ('c', lltype.Signed),
  147. ('d', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
  148. tsize = cpu.sizeof(T)
  149. cdescr = cpu.fielddescrof(T, 'c')
  150. ddescr = cpu.fielddescrof(T, 'd')
  151. arraydescr3 = cpu.arraydescrof(lltype.GcArray(lltype.Ptr(NODE)))
  152. U = lltype.GcStruct('U',
  153. ('parent', OBJECT),
  154. ('one', lltype.Ptr(lltype.GcArray(lltype.Ptr(NODE)))))
  155. u_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
  156. u_vtable_adr = llmemory.cast_ptr_to_adr(u_vtable)
  157. usize = cpu.sizeof(U)
  158. onedescr = cpu.fielddescrof(U, 'one')
  159. FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
  160. plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  161. EffectInfo.MOST_GENERAL)
  162. nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  163. EffectInfo([], [], [], []))
  164. writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  165. EffectInfo([], [], [adescr], []))
  166. writearraydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  167. EffectInfo([], [], [adescr], [arraydescr]))
  168. readadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  169. EffectInfo([adescr], [], [], []))
  170. mayforcevirtdescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  171. EffectInfo([nextdescr], [], [], [],
  172. EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE,
  173. can_invalidate=True))
  174. arraycopydescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  175. EffectInfo([], [arraydescr], [], [arraydescr],
  176. EffectInfo.EF_CANNOT_RAISE,
  177. oopspecindex=EffectInfo.OS_ARRAYCOPY))
  178. # array of structs (complex data)
  179. complexarray = lltype.GcArray(
  180. lltype.Struct("complex",
  181. ("real", lltype.Float),
  182. ("imag", lltype.Float),
  183. )
  184. )
  185. complexarraydescr = cpu.arraydescrof(complexarray)
  186. complexrealdescr = cpu.interiorfielddescrof(complexarray, "real")
  187. compleximagdescr = cpu.interiorfielddescrof(complexarray, "imag")
  188. for _name, _os in [
  189. ('strconcatdescr', 'OS_STR_CONCAT'),
  190. ('strslicedescr', 'OS_STR_SLICE'),
  191. ('strequaldescr', 'OS_STR_EQUAL'),
  192. ('streq_slice_checknull_descr', 'OS_STREQ_SLICE_CHECKNULL'),
  193. ('streq_slice_nonnull_descr', 'OS_STREQ_SLICE_NONNULL'),
  194. ('streq_slice_char_descr', 'OS_STREQ_SLICE_CHAR'),
  195. ('streq_nonnull_descr', 'OS_STREQ_NONNULL'),
  196. ('streq_nonnull_char_descr', 'OS_STREQ_NONNULL_CHAR'),
  197. ('streq_checknull_char_descr', 'OS_STREQ_CHECKNULL_CHAR'),
  198. ('streq_lengthok_descr', 'OS_STREQ_LENGTHOK'),
  199. ]:
  200. _oopspecindex = getattr(EffectInfo, _os)
  201. locals()[_name] = \
  202. cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  203. EffectInfo([], [], [], [], EffectInfo.EF_CANNOT_RAISE,
  204. oopspecindex=_oopspecindex))
  205. #
  206. _oopspecindex = getattr(EffectInfo, _os.replace('STR', 'UNI'))
  207. locals()[_name.replace('str', 'unicode')] = \
  208. cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  209. EffectInfo([], [], [], [], EffectInfo.EF_CANNOT_RAISE,
  210. oopspecindex=_oopspecindex))
  211. s2u_descr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
  212. EffectInfo([], [], [], [], oopspecindex=EffectInfo.OS_STR2UNICODE))
  213. #
  214. class LoopToken(AbstractDescr):
  215. pass
  216. asmdescr = LoopToken() # it can be whatever, it's not a descr though
  217. from pypy.jit.metainterp.virtualref import VirtualRefInfo
  218. class FakeWarmRunnerDesc:
  219. pass
  220. FakeWarmRunnerDesc.cpu = cpu
  221. vrefinfo = VirtualRefInfo(FakeWarmRunnerDesc)
  222. virtualtokendescr = vrefinfo.descr_virtual_token
  223. virtualforceddescr = vrefinfo.descr_forced
  224. jit_virtual_ref_vtable = vrefinfo.jit_virtual_ref_vtable
  225. jvr_vtable_adr = llmemory.cast_ptr_to_adr(jit_virtual_ref_vtable)
  226. register_known_gctype(cpu, node_vtable, NODE)
  227. register_known_gctype(cpu, node_vtable2, NODE2)
  228. register_known_gctype(cpu, u_vtable, U)
  229. register_known_gctype(cpu, jit_virtual_ref_vtable,vrefinfo.JIT_VIRTUAL_REF)
  230. register_known_gctype(cpu, intobj_noimmut_vtable, INTOBJ_NOIMMUT)
  231. register_known_gctype(cpu, intobj_immut_vtable, INTOBJ_IMMUT)
  232. register_known_gctype(cpu, ptrobj_immut_vtable, PTROBJ_IMMUT)
  233. namespace = locals()
  234. class OOtypeMixin_xxx_disabled(object):
  235. type_system = 'ootype'
  236. ## def get_class_of_box(self, box):
  237. ## root = box.getref(ootype.ROOT)
  238. ## return ootype.classof(root)
  239. ## cpu = runner.OOtypeCPU(None)
  240. ## NODE = ootype.Instance('NODE', ootype.ROOT, {})
  241. ## NODE._add_fields({'value': ootype.Signed,
  242. ## 'floatval' : ootype.Float,
  243. ## 'next': NODE})
  244. ## NODE2 = ootype.Instance('NODE2', NODE, {'other': NODE})
  245. ## node_vtable = ootype.runtimeClass(NODE)
  246. ## node_vtable_adr = ootype.cast_to_object(node_vtable)
  247. ## node_vtable2 = ootype.runtimeClass(NODE2)
  248. ## node_vtable_adr2 = ootype.cast_to_object(node_vtable2)
  249. ## node = ootype.new(NODE)
  250. ## nodebox = BoxObj(ootype.cast_to_object(node))
  251. ## myptr = nodebox.value
  252. ## myptr2 = ootype.cast_to_object(ootype.new(NODE))
  253. ## nodebox2 = BoxObj(ootype.cast_to_object(node))
  254. ## valuedescr = cpu.fielddescrof(NODE, 'value')
  255. ## floatdescr = cpu.fielddescrof(NODE, 'floatval')
  256. ## nextdescr = cpu.fielddescrof(NODE, 'next')
  257. ## otherdescr = cpu.fielddescrof(NODE2, 'other')
  258. ## nodesize = cpu.typedescrof(NODE)
  259. ## nodesize2 = cpu.typedescrof(NODE2)
  260. ## arraydescr = cpu.arraydescrof(ootype.Array(ootype.Signed))
  261. ## floatarraydescr = cpu.arraydescrof(ootype.Array(ootype.Float))
  262. ## # a plain Record
  263. ## S = ootype.Record({'a': ootype.Signed, 'b': NODE})
  264. ## ssize = cpu.typedescrof(S)
  265. ## adescr = cpu.fielddescrof(S, 'a')
  266. ## bdescr = cpu.fielddescrof(S, 'b')
  267. ## sbox = BoxObj(ootype.cast_to_object(ootype.new(S)))
  268. ## arraydescr2 = cpu.arraydescrof(ootype.Array(S))
  269. ## T = ootype.Record({'c': ootype.Signed,
  270. ## 'd': ootype.Array(NODE)})
  271. ## tsize = cpu.typedescrof(T)
  272. ## cdescr = cpu.fielddescrof(T, 'c')
  273. ## ddescr = cpu.fielddescrof(T, 'd')
  274. ## arraydescr3 = cpu.arraydescrof(ootype.Array(NODE))
  275. ## U = ootype.Instance('U', ootype.ROOT, {'one': ootype.Array(NODE)})
  276. ## usize = cpu.typedescrof(U)
  277. ## onedescr = cpu.fielddescrof(U, 'one')
  278. ## u_vtable = ootype.runtimeClass(U)
  279. ## u_vtable_adr = ootype.cast_to_object(u_vtable)
  280. ## # force a consistent order
  281. ## valuedescr.sort_key()
  282. ## nextdescr.sort_key()
  283. ## adescr.sort_key()
  284. ## bdescr.sort_key()
  285. ## FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
  286. ## nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT) # XXX fix ootype
  287. ## cpu.class_sizes = {node_vtable_adr: cpu.typedescrof(NODE),
  288. ## node_vtable_adr2: cpu.typedescrof(NODE2),
  289. ## u_vtable_adr: cpu.typedescrof(U)}
  290. ## namespace = locals()
  291. # ____________________________________________________________
  292. class Fake(object):
  293. failargs_limit = 1000
  294. storedebug = None
  295. class FakeMetaInterpStaticData(object):
  296. def __init__(self, cpu):
  297. self.cpu = cpu
  298. self.profiler = EmptyProfiler()
  299. self.options = Fake()
  300. self.globaldata = Fake()
  301. self.config = get_pypy_config(translating=True)
  302. self.config.translation.jit_ffi = True
  303. class logger_noopt:
  304. @classmethod
  305. def log_loop(*args):
  306. pass
  307. class warmrunnerdesc:
  308. class memory_manager:
  309. retrace_limit = 5
  310. max_retrace_guards = 15
  311. class Storage(compile.ResumeGuardDescr):
  312. "for tests."
  313. def __init__(self, metainterp_sd=None, original_greenkey=None):
  314. self.metainterp_sd = metainterp_sd
  315. self.original_greenkey = original_greenkey
  316. def store_final_boxes(self, op, boxes):
  317. op.setfailargs(boxes)
  318. def __eq__(self, other):
  319. return type(self) is type(other) # xxx obscure
  320. def clone_if_mutable(self):
  321. res = Storage(self.metainterp_sd, self.original_greenkey)
  322. self.copy_all_attributes_into(res)
  323. return res
  324. def _sortboxes(boxes):
  325. _kind2count = {history.INT: 1, history.REF: 2, history.FLOAT: 3}
  326. return sorted(boxes, key=lambda box: _kind2count[box.type])
  327. class BaseTest(object):
  328. def parse(self, s, boxkinds=None):
  329. return parse(s, self.cpu, self.namespace,
  330. type_system=self.type_system,
  331. boxkinds=boxkinds,
  332. invent_fail_descr=self.invent_fail_descr)
  333. def invent_fail_descr(self, model, fail_args):
  334. if fail_args is None:
  335. return None
  336. descr = Storage()
  337. descr.rd_frame_info_list = resume.FrameInfo(None, "code", 11)
  338. descr.rd_snapshot = resume.Snapshot(None, _sortboxes(fail_args))
  339. return descr
  340. def assert_equal(self, optimized, expected, text_right=None):
  341. from pypy.jit.metainterp.optimizeopt.util import equaloplists
  342. assert len(optimized.inputargs) == len(expected.inputargs)
  343. remap = {}
  344. for box1, box2 in zip(optimized.inputargs, expected.inputargs):
  345. assert box1.__class__ == box2.__class__
  346. remap[box2] = box1
  347. assert equaloplists(optimized.operations,
  348. expected.operations, False, remap, text_right)
  349. def _do_optimize_loop(self, loop, call_pure_results):
  350. from pypy.jit.metainterp.optimizeopt import optimize_trace
  351. from pypy.jit.metainterp.optimizeopt.util import args_dict
  352. self.loop = loop
  353. loop.call_pure_results = args_dict()
  354. if call_pure_results is not None:
  355. for k, v in call_pure_results.items():
  356. loop.call_pure_results[list(k)] = v
  357. metainterp_sd = FakeMetaInterpStaticData(self.cpu)
  358. if hasattr(self, 'vrefinfo'):
  359. metainterp_sd.virtualref_info = self.vrefinfo
  360. if hasattr(self, 'callinfocollection'):
  361. metainterp_sd.callinfocollection = self.callinfocollection
  362. #
  363. optimize_trace(metainterp_sd, loop, self.enable_opts)
  364. def unroll_and_optimize(self, loop, call_pure_results=None):
  365. operations = loop.operations
  366. jumpop = operations[-1]
  367. assert jumpop.getopnum() == rop.JUMP
  368. inputargs = loop.inputargs
  369. jump_args = jumpop.getarglist()[:]
  370. operations = operations[:-1]
  371. cloned_operations = [op.clone() for op in operations]
  372. preamble = TreeLoop('preamble')
  373. preamble.inputargs = inputargs
  374. preamble.resume_at_jump_descr = FakeDescrWithSnapshot()
  375. token = JitCellToken()
  376. preamble.operations = [ResOperation(rop.LABEL, inputargs, None, descr=TargetToken(token))] + \
  377. operations + \
  378. [ResOperation(rop.LABEL, jump_args, None, descr=token)]
  379. self._do_optimize_loop(preamble, call_pure_results)
  380. assert preamble.operations[-1].getopnum() == rop.LABEL
  381. inliner = Inliner(inputargs, jump_args)
  382. loop.resume_at_jump_descr = preamble.resume_at_jump_descr
  383. loop.operations = [preamble.operations[-1]] + \
  384. [inliner.inline_op(op, clone=False) for op in cloned_operations] + \
  385. [ResOperation(rop.JUMP, [inliner.inline_arg(a) for a in jump_args],
  386. None, descr=token)]
  387. #[inliner.inline_op(jumpop)]
  388. assert loop.operations[-1].getopnum() == rop.JUMP
  389. assert loop.operations[0].getopnum() == rop.LABEL
  390. loop.inputargs = loop.operations[0].getarglist()
  391. self._do_optimize_loop(loop, call_pure_results)
  392. extra_same_as = []
  393. while loop.operations[0].getopnum() != rop.LABEL:
  394. extra_same_as.append(loop.operations[0])
  395. del loop.operations[0]
  396. # Hack to prevent random order of same_as ops
  397. extra_same_as.sort(key=lambda op: str(preamble.operations).find(str(op.getarg(0))))
  398. for op in extra_same_as:
  399. preamble.operations.insert(-1, op)
  400. return preamble
  401. class FakeDescr(compile.ResumeGuardDescr):
  402. def clone_if_mutable(self):
  403. return FakeDescr()
  404. def __eq__(self, other):
  405. return isinstance(other, FakeDescr)
  406. class FakeDescrWithSnapshot(compile.ResumeGuardDescr):
  407. class rd_snapshot:
  408. class prev:
  409. prev = None
  410. boxes = []
  411. boxes = []
  412. def clone_if_mutable(self):
  413. return FakeDescrWithSnapshot()
  414. def __eq__(self, other):
  415. return isinstance(other, Storage) or isinstance(other, FakeDescrWithSnapshot)
  416. def convert_old_style_to_targets(loop, jump):
  417. newloop = TreeLoop(loop.name)
  418. newloop.inputargs = loop.inputargs
  419. newloop.operations = [ResOperation(rop.LABEL, loop.inputargs, None, descr=FakeDescr())] + \
  420. loop.operations
  421. if not jump:
  422. assert newloop.operations[-1].getopnum() == rop.JUMP
  423. newloop.operations[-1] = ResOperation(rop.LABEL, newloop.operations[-1].getarglist(), None, descr=FakeDescr())
  424. return newloop
  425. # ____________________________________________________________