Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)
Exemplo n.º 4
0
 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))
Exemplo n.º 7
0
 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
Exemplo n.º 8
0
    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}")
Exemplo n.º 9
0
    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))
Exemplo n.º 10
0
Arquivo: stack.py Projeto: sjyi/py-evm
    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")
Exemplo n.º 11
0
 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)
Exemplo n.º 12
0
 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)
Exemplo n.º 13
0
    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
Exemplo n.º 14
0
    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)
Exemplo n.º 15
0
    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)
Exemplo n.º 16
0
    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