def pop1_bytes(self) -> bytes: """ Pop and return a bytes element from the stack. Raise `eth.exceptions.InsufficientStack` if the stack was empty. """ # # Note: This function is optimized for speed over readability. # Knowing the popped type means that we can pop *very* quickly # when the popped type matches the pushed type. # if not self.values: raise InsufficientStack( "Wanted 1 stack item, only had %d", len(self.values), ) else: item_type, popped = self._pop_typed() if item_type is int: return int_to_big_endian(popped) # type: ignore elif item_type is bytes: return popped # type: ignore else: raise _busted_type(item_type, popped)
def pop_bytes(self, num_items: int) -> Tuple[bytes, ...]: # # Note: This function is optimized for speed over readability. # if num_items > len(self.values): raise InsufficientStack( "Wanted %d stack items, only had %d", num_items, len(self.values), ) else: neg_num_items = -1 * num_items all_popped = reversed(self.values[neg_num_items:]) del self.values[neg_num_items:] type_cast_popped = [] # Convert any non-matching types to the requested type (int) # This doesn't use the @to_tuple(generator) pattern, for added performance for item_type, popped in all_popped: if item_type is int: type_cast_popped.append( int_to_big_endian(popped)) # type: ignore elif item_type is bytes: type_cast_popped.append(popped) # type: ignore else: raise _busted_type(item_type, popped) return tuple(type_cast_popped)
def pop_any(self, num_items: int) -> Tuple[Union[int, bytes], ...]: """ Pop and return a tuple of items of length ``num_items`` from the stack. The type of each element will be int or bytes, depending on whether it was pushed with stack_push_bytes or stack_push_int. Raise `eth.exceptions.InsufficientStack` if there are not enough items on the stack. Items are ordered with the top of the stack as the first item in the tuple. """ # # Note: This function is optimized for speed over readability. # if num_items > len(self.values): raise InsufficientStack( "Wanted %d stack items, only had %d", num_items, len(self.values), ) else: neg_num_items = -1 * num_items # Quickest way to pop off multiple values from the end, in place all_popped = reversed(self.values[neg_num_items:]) del self.values[neg_num_items:] # This doesn't use the @to_tuple(generator) pattern, for added performance return tuple(val for _, val in all_popped)
def swap(self, position: int) -> None: idx = -1 * position - 1 try: self.values[-1], self.values[idx] = self.values[idx], self.values[ -1] except IndexError: raise InsufficientStack( f"Insufficient stack items for SWAP{position}")
def dup(self, position: int) -> None: """ Perform a DUP operation on the stack. """ idx = -1 * position try: self.push(self.values[idx]) except IndexError: raise InsufficientStack("Insufficient stack items for DUP{0}".format(position))
def swap(self, position: int) -> None: """ Perform a SWAP operation on the stack. """ idx = -1 * position - 1 try: self.values[-1], self.values[idx] = self.values[idx], self.values[-1] except IndexError: raise InsufficientStack("Insufficient stack items for SWAP{0}".format(position))
def pop1_any(self) -> Union[int, bytes]: # # Note: This function is optimized for speed over readability. # if not self.values: raise InsufficientStack("Wanted 1 stack item, had none") else: _, popped = self._pop_typed() return popped
def dup(self, position: int) -> None: if len(self.values) > 1023: raise FullStack('Stack limit reached') peek_index = -1 * position try: self._append(self.values[peek_index]) except IndexError: raise InsufficientStack( f"Insufficient stack items for DUP{position}")
def dup(self, position: int) -> None: """ Perform a DUP operation on the stack. """ if len(self.values) > 1023: raise FullStack('Stack limit reached') peek_index = -1 * position try: self._append(self.values[peek_index]) except IndexError: raise InsufficientStack( "Insufficient stack items for DUP{0}".format(position))
def pop(self, num_items, type_hint): """ Pop an item off thes stack. Note: This function is optimized for speed over readability. """ try: if num_items == 1: return next(self._pop(num_items, type_hint)) else: return tuple(self._pop(num_items, type_hint)) except IndexError: raise InsufficientStack("No stack items")
def pop1_int(self) -> int: # # Note: This function is optimized for speed over readability. # if not self.values: raise InsufficientStack("Wanted 1 stack item as int, had none") else: item_type, popped = self._pop_typed() if item_type is int: return popped # type: ignore elif item_type is bytes: return big_endian_to_int(popped) # type: ignore else: raise _busted_type(item_type, popped)
def pop1_bytes(self) -> bytes: # # Note: This function is optimized for speed over readability. # Knowing the popped type means that we can pop *very* quickly # when the popped type matches the pushed type. # if not self.values: raise InsufficientStack("Wanted 1 stack item as bytes, had none") else: item_type, popped = self._pop_typed() if item_type is int: return int_to_big_endian(popped) # type: ignore elif item_type is bytes: return popped # type: ignore else: raise _busted_type(item_type, popped)
def pop1_any(self) -> Union[int, bytes]: """ Pop and return an element from the stack. The type of each element will be int or bytes, depending on whether it was pushed with push_bytes or push_int. Raise `eth.exceptions.InsufficientStack` if the stack was empty. """ # # Note: This function is optimized for speed over readability. # if not self.values: raise InsufficientStack("Wanted 1 stack item, had none") else: _, popped = self._pop_typed() return popped
def pop_any(self, num_items: int) -> Tuple[Union[int, bytes], ...]: # # Note: This function is optimized for speed over readability. # if num_items > len(self.values): raise InsufficientStack( "Wanted %d stack items, only had %d", num_items, len(self.values), ) else: neg_num_items = -1 * num_items # Quickest way to pop off multiple values from the end, in place all_popped = reversed(self.values[neg_num_items:]) del self.values[neg_num_items:] # This doesn't use the @to_tuple(generator) pattern, for added performance return tuple(val for _, val in all_popped)
def pop1_int(self) -> int: """ Pop and return an integer from the stack. Raise `eth.exceptions.InsufficientStack` if the stack was empty. """ # # Note: This function is optimized for speed over readability. # if not self.values: raise InsufficientStack("Wanted 1 stack item as int, had none") else: item_type, popped = self._pop_typed() if item_type is int: return popped # type: ignore elif item_type is bytes: return big_endian_to_int(popped) # type: ignore else: raise _busted_type(item_type, popped)
def pop_ints(self, num_items: int) -> Tuple[int, ...]: """ Pop and return a tuple of integers of length ``num_items`` from the stack. Raise `eth.exceptions.InsufficientStack` if there are not enough items on the stack. Items are ordered with the top of the stack as the first item in the tuple. """ # # Note: This function is optimized for speed over readability. # if num_items > len(self.values): raise InsufficientStack( "Wanted %d stack items, only had %d", num_items, len(self.values), ) else: neg_num_items = -1 * num_items # Quickest way to pop off multiple values from the end, in place all_popped = reversed(self.values[neg_num_items:]) del self.values[neg_num_items:] type_cast_popped = [] # Convert any non-matching types to the requested type (int) # This doesn't use the @to_tuple(generator) pattern, for added performance for item_type, popped in all_popped: if item_type is int: type_cast_popped.append(popped) elif item_type is bytes: type_cast_popped.append( big_endian_to_int(popped)) # type: ignore else: raise _busted_type(item_type, popped) return tuple(type_cast_popped) # type: ignore