-
Notifications
You must be signed in to change notification settings - Fork 278
/
Copy pathtrace_entry.py
69 lines (55 loc) · 1.73 KB
/
trace_entry.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import dataclasses
import struct
from typing import Dict, Generic, List, TypeVar
from starkware.cairo.lang.vm.relocatable import MaybeRelocatable, relocate_value
T = TypeVar("T", int, MaybeRelocatable)
@dataclasses.dataclass
class TraceEntry(Generic[T]):
"""
A trace entry for every instruction that was executed.
Holds the register values before the instruction was executed.
"""
pc: T
ap: T
fp: T
def serialize(self) -> bytes:
"""
Serializes the trace entry to binary format:
[ 8 bytes | 8 bytes | 8 bytes ]
[ ap | fp | pc ]
"""
values = [self.ap, self.fp, self.pc]
for x in values:
assert isinstance(x, int)
assert 0 <= x < 2**64
return struct.pack("<3Q", *values)
@classmethod
def deserialize(cls, serialized: bytes) -> "TraceEntry":
assert len(serialized) == cls.serialization_size(), "Unexpected input length."
ap, fp, pc = struct.unpack("<3Q", serialized)
return cls(
pc=pc,
ap=ap,
fp=fp,
)
@staticmethod
def serialization_size():
return 3 * 8
def relocate_trace(
trace: List[TraceEntry[MaybeRelocatable]],
segment_offsets: Dict[int, T],
prime: int,
allow_missing_segments: bool = False,
) -> List[TraceEntry[T]]:
new_trace: List[TraceEntry[T]] = []
def relocate_val(x):
return relocate_value(x, segment_offsets, prime, allow_missing_segments)
for entry in trace:
new_trace.append(
TraceEntry(
pc=relocate_val(entry.pc),
ap=relocate_val(entry.ap),
fp=relocate_val(entry.fp),
)
)
return new_trace