15
15
class CodeStream (object ):
16
16
stream = None
17
17
depth_processed = None
18
+ _length_cache = None
19
+ _raw_code_bytes = None
18
20
19
21
logger = logging .getLogger ('eth.vm.CodeStream' )
20
22
21
23
def __init__ (self , code_bytes : bytes ) -> None :
22
24
validate_is_bytes (code_bytes , title = "CodeStream bytes" )
23
25
self .stream = io .BytesIO (code_bytes )
26
+ self ._raw_code_bytes = code_bytes
27
+ self ._length_cache = len (code_bytes )
24
28
self .invalid_positions = set () # type: Set[int]
25
29
self .depth_processed = 0
26
30
27
31
def read (self , size : int ) -> bytes :
28
32
return self .stream .read (size )
29
33
30
34
def __len__ (self ) -> int :
31
- return len ( self .stream . getvalue ())
35
+ return self ._length_cache
32
36
33
37
def __iter__ (self ) -> 'CodeStream' :
34
38
return self
@@ -37,7 +41,7 @@ def __next__(self) -> int:
37
41
return self .next ()
38
42
39
43
def __getitem__ (self , i : int ) -> int :
40
- return self .stream . getvalue () [i ]
44
+ return self ._raw_code_bytes [i ]
41
45
42
46
def next (self ) -> int :
43
47
next_opcode_as_byte = self .read (1 )
@@ -73,7 +77,7 @@ def seek(self, pc: int) -> Iterator['CodeStream']:
73
77
invalid_positions = None
74
78
75
79
def is_valid_opcode (self , position : int ) -> bool :
76
- if position >= len ( self ) :
80
+ if position >= self . _length_cache :
77
81
return False
78
82
if position in self .invalid_positions :
79
83
return False
0 commit comments