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