Пример #1
0
 def validate(self):
     if self.value < SizeLimits.MIN_INT256:
         raise OverflowException(
             "Value is below lower bound for all numeric types", self)
     if self.value > SizeLimits.MAX_UINT256:
         raise OverflowException(
             "Value exceeds upper bound for all numeric types", self)
Пример #2
0
 def validate(self):
     if self.value.as_tuple().exponent < -MAX_DECIMAL_PLACES:
         raise InvalidLiteral("Vyper supports a maximum of ten decimal points", self)
     if self.value < SizeLimits.MIN_INT128:
         raise OverflowException("Value is below lower bound for decimal types", self)
     if self.value > SizeLimits.MAX_INT128:
         raise OverflowException("Value exceeds upper bound for decimal types", self)
Пример #3
0
 def from_literal(cls, node: vy_ast.Constant) -> BaseTypeDefinition:
     obj = super().from_literal(node)
     lower, upper = cls._bounds
     if node.value < lower:
         raise OverflowException(f"Value is below lower bound for given type ({lower})", node)
     if node.value > upper:
         raise OverflowException(f"Value exceeds upper bound for given type ({upper})", node)
     return obj
Пример #4
0
    def validate_numeric_op(
            self, node: Union[vy_ast.UnaryOp, vy_ast.BinOp,
                              vy_ast.AugAssign]) -> None:
        if self._invalid_op and isinstance(node.op, self._invalid_op):
            raise InvalidOperation(
                f"Cannot perform {node.op.description} on {self}", node)

        if isinstance(node.op, vy_ast.Pow):
            if isinstance(node, vy_ast.BinOp):
                left, right = node.left, node.right
            elif isinstance(node, vy_ast.AugAssign):
                left, right = node.target, node.value
            else:
                raise CompilerPanic(
                    f"Unexpected node type for numeric op: {type(node).__name__}"
                )

            value_bits = self._bits - (1 if self._is_signed else 0)

            # constant folding ensures one of `(left, right)` is never a literal
            if isinstance(left, vy_ast.Int):
                if left.value >= 2**value_bits:
                    raise OverflowException(
                        "Base is too large, calculation will always overflow",
                        left)
                elif left.value < -(2**value_bits):
                    raise OverflowException(
                        "Base is too small, calculation will always underflow",
                        left)
            elif isinstance(right, vy_ast.Int):
                if right.value < 0:
                    raise InvalidOperation("Cannot calculate a negative power",
                                           right)
                if right.value > value_bits:
                    raise OverflowException(
                        "Power is too large, calculation will always overflow",
                        right)
            else:
                msg = (
                    "Cannot apply an overflow check on exponentiation when both "
                    "the base and power are unknown at compile-time.")
                if not self._is_signed:
                    msg = (
                        f"{msg} To perform this operation without an overflow check, use "
                        f"`pow_mod256({left.node_source_code}, {right.node_source_code})`"
                    )
                raise InvalidOperation(msg, node)
Пример #5
0
def _validate_numeric_bounds(node: Union["BinOp", "UnaryOp"],
                             value: Union[decimal.Decimal, int]) -> None:
    if isinstance(value, decimal.Decimal):
        lower, upper = SizeLimits.MIN_INT128, SizeLimits.MAX_INT128
    elif isinstance(value, int):
        lower, upper = SizeLimits.MIN_INT256, SizeLimits.MAX_UINT256
    else:
        raise CompilerPanic(
            f"Unexpected return type from {node._op}: {type(value)}")
    if not lower <= value <= upper:
        raise OverflowException(
            f"Result of {node.op.description} ({value}) is outside bounds of all numeric types",
            node,
        )
Пример #6
0
    def types_from_Constant(self, node):
        # literal value (integer, string, etc)
        types_list = []
        for primitive in types.get_primitive_types().values():
            try:
                obj = primitive.from_literal(node)
                types_list.append(obj)
            except VyperException:
                continue
        if types_list:
            return types_list

        if isinstance(node, vy_ast.Num):
            raise OverflowException(
                "Numeric literal is outside of allowable range for number types", node,
            )
        raise InvalidLiteral(f"Could not determine type for literal value '{node.value}'", node)