Skip to content

Commit df52f90

Browse files
committed
Eagerly calculate the lists. Simpler code
1 parent 7a4a795 commit df52f90

File tree

1 file changed

+26
-33
lines changed

1 file changed

+26
-33
lines changed

pyevmasm/evmasm.py

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -621,25 +621,26 @@ class InstructionTable():
621621
Instruction(0x3, 'SUB', 0, 2, 1, 3, 'Subtraction operation.', None, 0)
622622
623623
"""
624-
__slots__ = ('_previous_fork', '_ilist', '_cache', '_name_to_opcode')
624+
__slots__ = ('_instruction_list', '__name_to_opcode')
625625
def __init__(self, *args, **kwargs):
626-
self._previous_fork = kwargs.get('previous_fork', None)
627-
self._ilist = dict(args[0])
628-
self._cache = {}
629-
self._name_to_opcode = None
626+
previous_fork = kwargs.get('previous_fork', None)
630627

631-
def _search_by_opcode(self, k):
632-
try:
633-
return (k, *self._ilist[k])
634-
except KeyError:
635-
if self._previous_fork is not None:
636-
return self._previous_fork._search_by_opcode(k)
637-
raise KeyError(k)
628+
self._instruction_list = {}
629+
self.__name_to_opcode = None
638630

639-
def _search_by_name(self, k):
640-
if self._name_to_opcode is None:
641-
self._name_to_opcode = {}
642-
for opcode, (name, operand_size, pushes, pops, gas, description) in self._ilist.items():
631+
if previous_fork is not None:
632+
if not isinstance(previous_fork, self.__class__):
633+
raise TypeError("{} expected".format(self.__class__))
634+
self._instruction_list.update(previous_fork._instruction_list)
635+
636+
self._instruction_list.update(args[0])
637+
self.__name_to_opcode = None
638+
639+
@property
640+
def _name_to_opcode(self):
641+
if self.__name_to_opcode is None:
642+
self.__name_to_opcode = {}
643+
for opcode, (name, operand_size, pushes, pops, gas, description) in self._instruction_list.items():
643644
if name == 'PUSH':
644645
long_name = 'PUSH%d' % operand_size
645646
elif name == 'DUP':
@@ -650,23 +651,20 @@ def _search_by_name(self, k):
650651
long_name ='LOG%d' % (pops - 2)
651652
else:
652653
long_name = name
653-
self._name_to_opcode[long_name] = opcode
654+
self.__name_to_opcode[long_name] = opcode
655+
return self.__name_to_opcode
654656

655-
try:
656-
return self._search_by_opcode(self._name_to_opcode[k])
657-
except KeyError:
658-
if self._previous_fork is not None:
659-
return self._previous_fork._search_by_name(k)
660-
raise KeyError(k)
657+
def _search_by_name(self, k):
658+
return self._search_by_opcode(self._name_to_opcode[k])
659+
660+
def _search_by_opcode(self, k):
661+
return (k, *self._instruction_list[k])
661662

662663
def _search(self, k):
663-
if k in self._cache:
664-
return self._cache[k]
665664
try:
666665
value = self._search_by_opcode(k)
667666
except KeyError:
668667
value = self._search_by_name(k)
669-
self._cache[k] = value
670668
return value
671669

672670
def __getitem__(self, k):
@@ -679,15 +677,10 @@ def get(self, k, default=None):
679677
return default
680678

681679
def __contains__(self, k):
682-
if k not in self._ilist:
683-
if self._previous_fork is not None:
684-
return k in self._previous_fork
680+
return k in self._instruction_list or k in self._name_to_opcode
685681

686682
def keys(self):
687-
keys = ()
688-
if self._previous_fork is not None:
689-
keys = self._previous_fork.keys()
690-
return tuple(set(tuple(self._ilist.keys()) + keys))
683+
return self._instruction_list.keys()
691684

692685
def __repr__(self):
693686
return '{}({})'.format(type(self).__name__, super(InstructionTable, self).__repr__())

0 commit comments

Comments
 (0)