• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CityOfZion / neo3-boa / 30ae3248-fada-4b8d-8735-31794b222593

17 Jan 2024 01:43PM UTC coverage: 92.103%. Remained the same
30ae3248-fada-4b8d-8735-31794b222593

push

circleci

web-flow
Merge pull request #1170 from CityOfZion/CU-86a1hepnw

CU-86a1hepnw - Fix tests using Python 3.12 (parsing manifest JSON)

1 of 1 new or added line in 1 file covered. (100.0%)

253 existing lines in 51 files now uncovered.

20773 of 22554 relevant lines covered (92.1%)

2.75 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.28
/boa3/internal/compiler/codegenerator/vmcodemap.py
1
from typing import List, Dict, Optional
3✔
2

3
from boa3.internal.neo.vm.VMCode import VMCode
3✔
4

5

6
class VMCodeMap:
3✔
7
    def __init__(self):
3✔
8
        self._vm_code_list: List[VMCode] = []
3✔
9
        self._vm_code_addresses: List[int] = []
3✔
10

11
        # optimization so it's not needed to iterate over everything in search of targets
12
        self._vm_code_with_target: List[VMCode] = []
3✔
13

14
    def __len__(self) -> int:
3✔
15
        return self._vm_code_list.__len__()
3✔
16

17
    def clear(self):
3✔
18
        self._vm_code_addresses.clear()
3✔
19
        self._vm_code_list.clear()
3✔
20

21
    def get_code_map(self) -> Dict[int, VMCode]:
3✔
22
        size = len(self)
3✔
23
        return {self._vm_code_addresses[index]: self._vm_code_list[index] for index in range(size)}
3✔
24

25
    def get_code_list(self) -> List[VMCode]:
3✔
26
        return self._vm_code_list
3✔
27

28
    def get_code_with_target_list(self) -> List[VMCode]:
3✔
29
        return self._vm_code_with_target
3✔
30

31
    def get_bytecode_size(self) -> int:
3✔
32
        if len(self) < 1:
3✔
33
            return 0
3✔
34

35
        return self._vm_code_addresses[-1] + self._vm_code_list[-1].size
3✔
36

37
    def insert_code(self, vm_code: VMCode, has_target: bool = False):
3✔
38
        if vm_code not in self._vm_code_list:
3✔
39
            self._vm_code_addresses.append(self.get_bytecode_size())
3✔
40
            self._vm_code_list.append(vm_code)
3✔
41

42
            if has_target:
3✔
43
                self._vm_code_with_target.append(vm_code)
3✔
44

45
    def get_code(self, address: int) -> Optional[VMCode]:
3✔
46
        try:
3✔
47
            index = self._vm_code_addresses.index(address)
3✔
48
        except ValueError:
3✔
49
            # the address is not int the list
50
            if address >= self.get_bytecode_size():
3✔
51
                # the address is not in the bytecode
52
                return None
3✔
53

54
            # if the address is not the start of a instruction, gets the last instruction before given address
UNCOV
55
            code_address = 0
2✔
UNCOV
56
            for addr in self._vm_code_addresses:
2✔
UNCOV
57
                if addr > address:
2✔
UNCOV
58
                    break
2✔
UNCOV
59
                code_address = addr
2✔
60

UNCOV
61
            index = self._vm_code_addresses.index(code_address)
2✔
62

63
        return self._vm_code_list[index]
3✔
64

65
    def get_start_address(self, vm_code: VMCode) -> int:
3✔
66
        try:
3✔
67
            index = self._vm_code_list.index(vm_code)
3✔
68
            return self._vm_code_addresses[index]
3✔
69
        except ValueError:
3✔
70
            return 0
3✔
71

72
    def get_end_address(self, vm_code: VMCode) -> int:
3✔
73
        try:
3✔
74
            index = self._vm_code_list.index(vm_code) + 1
3✔
75
            if index == len(self._vm_code_list):
3✔
76
                return self.get_bytecode_size()
3✔
77
            else:
78
                return self._vm_code_addresses[index] - 1
3✔
79
        except ValueError:
×
80
            return 0
×
81

82
    def get_addresses(self, start_address: int, end_address: int) -> List[int]:
3✔
83
        if start_address > end_address:
3✔
84
            start_address, end_address = end_address, start_address
×
85

86
        addresses = []
3✔
87
        for address in range(start_address, end_address + 1):
3✔
88
            if address in self._vm_code_addresses:
3✔
89
                addresses.append(address)
3✔
90
        return addresses
3✔
91

92
    def get_addresses_from_codes(self, codes: List[VMCode]) -> List[int]:
3✔
93
        if len(codes) < 1:
3✔
94
            return []
3✔
95

96
        addresses = []
3✔
97
        for vm_code in codes:
3✔
98
            try:
3✔
99
                index = self._vm_code_list.index(vm_code)
3✔
100
                addresses.append(self._vm_code_addresses[index])
3✔
101
            except ValueError:
×
102
                continue
×
103

104
        return addresses
3✔
105

106
    def get_opcodes(self, addresses: List[int]) -> List[VMCode]:
3✔
107
        codes = []
3✔
108

109
        for address in sorted(addresses):
3✔
110
            try:
3✔
111
                index = self._vm_code_addresses.index(address)
3✔
112
                codes.append(self._vm_code_list[index])
3✔
113
            except ValueError:
×
114
                # address not in list
115
                continue
×
116

117
        return codes
3✔
118

119
    def update_addresses(self, start_address: int = 0):
3✔
120
        next_address = -1
3✔
121
        final_size = len(self._vm_code_list)
3✔
122

123
        if len(self._vm_code_addresses) > final_size:
3✔
124
            self._vm_code_addresses = self._vm_code_addresses[:final_size]
3✔
125

126
        for index in range(final_size):
3✔
127
            address = self._vm_code_addresses[index]
3✔
128

129
            if address >= start_address:
3✔
130
                if next_address < 0:
3✔
131
                    if index > 0:
3✔
132
                        new_address = self._vm_code_addresses[index - 1]
3✔
133
                        next_address = new_address + self._vm_code_list[index - 1].size
3✔
134
                    else:
135
                        next_address = 0
3✔
136

137
                if next_address != address:
3✔
138
                    if index < len(self._vm_code_addresses):
3✔
139
                        self._vm_code_addresses[index] = next_address
3✔
140
                    else:
141
                        self._vm_code_addresses.append(next_address)
×
142

143
                next_address += self._vm_code_list[index].size
3✔
144

145
    def move_to_end(self, first_code_address: int, last_code_address: int) -> Optional[int]:
3✔
146
        if last_code_address < first_code_address:
3✔
147
            return
3✔
148

149
        if (len(self._vm_code_addresses) > 0 and
3✔
150
                last_code_address == self._vm_code_addresses[-1]):
151
            # there's nothing to change if it's moving the all the codes
152
            return
3✔
153

154
        first_index = -1
3✔
155
        last_index = 0
3✔
156
        for index, address in enumerate(self._vm_code_addresses):
3✔
157
            if first_code_address <= address and first_index < 0:
3✔
158
                first_index = index
3✔
159
            elif address > last_code_address:
3✔
160
                last_index = index
3✔
161
                break
3✔
162

163
        if first_index >= 0:
3✔
164
            # if the first index was not set, there's nothing to move
165
            if last_index < first_index:
3✔
166
                last_index = len(self._vm_code_addresses)
×
167

168
            self._vm_code_list[first_index:] = (self._vm_code_list[last_index:] +
3✔
169
                                                self._vm_code_list[first_index:last_index])
170
            self.update_addresses(first_code_address)
3✔
171

172
        index = self.get_bytecode_size()
3✔
173
        return index
3✔
174

175
    def remove_opcodes_by_addresses(self, addresses: List[int]):
3✔
176
        was_changed = False
3✔
177
        # reversed so we only need to update addresses once after all are removed
178
        for code_address in sorted(addresses, reverse=True):
3✔
179
            try:
3✔
180
                index = self._vm_code_addresses.index(code_address)
3✔
181
                code = self._vm_code_list.pop(index)
3✔
182

183
                was_changed = True
3✔
184
                self._vm_code_with_target.remove(code)
3✔
185
            except ValueError:
3✔
186
                # don't stop the loop if an address is not found
187
                continue
3✔
188

189
        if was_changed:
3✔
190
            self.update_addresses(min(addresses))
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc