| 62 | self.fail(msg) |
| 63 | |
| 64 | class CompilationStepTestCase(unittest.TestCase): |
| 65 | |
| 66 | HAS_ARG = set(dis.hasarg) |
| 67 | HAS_TARGET = set(dis.hasjrel + dis.hasjabs + dis.hasexc) |
| 68 | HAS_ARG_OR_TARGET = HAS_ARG.union(HAS_TARGET) |
| 69 | |
| 70 | class Label: |
| 71 | pass |
| 72 | |
| 73 | def assertInstructionsMatch(self, actual_seq, expected): |
| 74 | # get an InstructionSequence and an expected list, where each |
| 75 | # entry is a label or an instruction tuple. Construct an expected |
| 76 | # instruction sequence and compare with the one given. |
| 77 | |
| 78 | self.assertIsInstance(expected, list) |
| 79 | actual = actual_seq.get_instructions() |
| 80 | expected = self.seq_from_insts(expected).get_instructions() |
| 81 | self.assertEqual(len(actual), len(expected)) |
| 82 | |
| 83 | # compare instructions |
| 84 | for act, exp in zip(actual, expected): |
| 85 | if isinstance(act, int): |
| 86 | self.assertEqual(exp, act) |
| 87 | continue |
| 88 | self.assertIsInstance(exp, tuple) |
| 89 | self.assertIsInstance(act, tuple) |
| 90 | idx = max([p[0] for p in enumerate(exp) if p[1] != -1]) |
| 91 | self.assertEqual(exp[:idx], act[:idx]) |
| 92 | |
| 93 | def resolveAndRemoveLabels(self, insts): |
| 94 | idx = 0 |
| 95 | res = [] |
| 96 | for item in insts: |
| 97 | assert isinstance(item, (self.Label, tuple)) |
| 98 | if isinstance(item, self.Label): |
| 99 | item.value = idx |
| 100 | else: |
| 101 | idx += 1 |
| 102 | res.append(item) |
| 103 | |
| 104 | return res |
| 105 | |
| 106 | def seq_from_insts(self, insts): |
| 107 | labels = {item for item in insts if isinstance(item, self.Label)} |
| 108 | for i, lbl in enumerate(labels): |
| 109 | lbl.value = i |
| 110 | |
| 111 | seq = _testinternalcapi.new_instruction_sequence() |
| 112 | for item in insts: |
| 113 | if isinstance(item, self.Label): |
| 114 | seq.use_label(item.value) |
| 115 | else: |
| 116 | op = item[0] |
| 117 | if isinstance(op, str): |
| 118 | op = opcode.opmap[op] |
| 119 | arg, *loc = item[1:] |
| 120 | if isinstance(arg, self.Label): |
| 121 | arg = arg.value |