@@ -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