예제 #1
0
def to_bool(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise TypeMismatchException(
                "Cannot convert bytes array of max length {} to bool".format(
                    in_arg.value,
                ),
                expr,
            )
        else:
            num = byte_array_to_num(in_arg, expr, 'uint256')
            return LLLnode.from_list(
                ['iszero', ['iszero', num]],
                typ=BaseType('bool'),
                pos=getpos(expr)
            )

    else:
        return LLLnode.from_list(
            ['iszero', ['iszero', in_arg]],
            typ=BaseType('bool', in_arg.typ.unit),
            pos=getpos(expr)
        )
예제 #2
0
파일: convert.py 프로젝트: olwee/vyper
def to_int128(expr, args, kwargs, context):
    in_node = args[0]
    input_type, _ = get_type(in_node)
    if input_type in ('uint256', 'bytes32'):
        if in_node.typ.is_literal and not SizeLimits.in_bounds(
                'int128', in_node.value):
            raise InvalidLiteralException(
                "Number out of range: {}".format(in_node.value), expr)
        return LLLnode.from_list([
            'clamp', ['mload', MemoryPositions.MINNUM], in_node,
            ['mload', MemoryPositions.MAXNUM]
        ],
                                 typ=BaseType('int128', in_node.typ.unit),
                                 pos=getpos(expr))

    elif input_type is 'bytes':
        if in_node.typ.maxlen > 32:
            raise InvalidLiteralException(
                "Cannot convert bytes array of max length {} to int128".format(
                    in_node.value), expr)
        return byte_array_to_num(in_node, expr, 'int128')

    elif input_type is 'bool':
        return LLLnode.from_list([
            'clamp', ['mload', MemoryPositions.MINNUM], in_node,
            ['mload', MemoryPositions.MAXNUM]
        ],
                                 typ=BaseType('int128', in_node.typ.unit),
                                 pos=getpos(expr))

    else:
        raise InvalidLiteralException("Invalid input for int128: %r" % in_node,
                                      expr)
예제 #3
0
def pack_logging_topics(event_id, args, expected_topics, context, pos):
    topics = [event_id]
    for pos, expected_topic in enumerate(expected_topics):
        expected_type = expected_topic.typ
        arg = args[pos]
        value = parse_expr(arg, context)
        arg_type = value.typ

        if isinstance(arg_type, ByteArrayType) and isinstance(expected_type, ByteArrayType):
            if arg_type.maxlen > expected_type.maxlen:
                raise TypeMismatchException("Topic input bytes are too big: %r %r" % (arg_type, expected_type), pos)
            if isinstance(arg, ast.Str):
                bytez, bytez_length = string_to_bytes(arg.s)
                if len(bytez) > 32:
                    raise InvalidLiteralException("Can only log a maximum of 32 bytes at a time.", pos)
                topics.append(bytes_to_int(bytez + b'\x00' * (32 - bytez_length)))
            else:
                if value.location == "memory":
                    size = ['mload', value]
                elif value.location == "storage":
                    size = ['sload', ['sha3_32', value]]
                topics.append(byte_array_to_num(value, arg, 'uint256', size))
        else:
            value = unwrap_location(value)
            value = base_type_conversion(value, arg_type, expected_type, pos=pos)
            topics.append(value)

    return topics
예제 #4
0
파일: convert.py 프로젝트: maciejry/vyper
def to_uint256(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)
    _unit = in_arg.typ.unit if input_type in ('int128', 'decimal') else None

    if input_type == 'num_literal':
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds('uint256', in_arg):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg))
            return LLLnode.from_list(in_arg,
                                     typ=BaseType('uint256', _unit),
                                     pos=getpos(expr))
        elif isinstance(in_arg, float):
            if not SizeLimits.in_bounds('uint256', math.trunc(in_arg)):
                raise InvalidLiteralException("Number out of range: {}".format(
                    math.trunc(in_arg)))
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType('uint256', _unit),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteralException(
                "Unknown numeric literal type: {}".fornat(in_arg))

    elif isinstance(in_arg, LLLnode) and input_type == 'int128':
        return LLLnode.from_list(['clampge', in_arg, 0],
                                 typ=BaseType('uint256', _unit),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == 'decimal':
        return LLLnode.from_list(
            ['div', ['clampge', in_arg, 0], DECIMAL_DIVISOR],
            typ=BaseType('uint256', _unit),
            pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == 'bool':
        return LLLnode.from_list(in_arg,
                                 typ=BaseType('uint256'),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type in ('bytes32', 'address'):
        return LLLnode(value=in_arg.value,
                       args=in_arg.args,
                       typ=BaseType('uint256'),
                       pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise InvalidLiteralException(
                "Cannot convert bytes array of max length {} to uint256".
                format(in_arg.value),
                expr,
            )
        return byte_array_to_num(in_arg, expr, 'uint256')

    else:
        raise InvalidLiteralException("Invalid input for uint256: %r" % in_arg,
                                      expr)
예제 #5
0
def to_int128(expr, args, kwargs, context):
    input = args[0]
    typ, len = get_type(input)
    if typ in ('int128', 'uint256', 'bytes32'):
        return LLLnode.from_list(
            ['clamp', ['mload', MemoryPositions.MINNUM], input, ['mload', MemoryPositions.MAXNUM]], typ=BaseType('int128'), pos=getpos(expr)
        )
    else:
        return byte_array_to_num(input, expr, 'int128')
예제 #6
0
파일: convert.py 프로젝트: hskang9/vyper
def to_int128(expr, args, kwargs, context):
    in_node = args[0]
    typ, len = get_type(in_node)
    if typ in ('int128', 'uint256', 'bytes32'):
        if in_node.typ.is_literal and not SizeLimits.in_bounds(
                'int128', in_node.value):
            raise InvalidLiteralException(
                "Number out of range: {}".format(in_node.value), expr)
        return LLLnode.from_list([
            'clamp', ['mload', MemoryPositions.MINNUM], in_node,
            ['mload', MemoryPositions.MAXNUM]
        ],
                                 typ=BaseType('int128', in_node.typ.unit),
                                 pos=getpos(expr))
    if in_node.typ.is_literal and in_node[:2] == '0x':
        return byte_array_to_num(binascii.unhexlify(in_node[2:]), expr,
                                 'int128')
    else:
        return byte_array_to_num(in_node, expr, 'int128')
예제 #7
0
def to_uint256(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "num_literal":
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds("uint256", in_arg):
                raise InvalidLiteral(f"Number out of range: {in_arg}")
            return LLLnode.from_list(in_arg,
                                     typ=BaseType("uint256", ),
                                     pos=getpos(expr))
        elif isinstance(in_arg, Decimal):
            if not SizeLimits.in_bounds("uint256", math.trunc(in_arg)):
                raise InvalidLiteral(
                    f"Number out of range: {math.trunc(in_arg)}")
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType("uint256"),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteral(f"Unknown numeric literal type: {in_arg}")

    elif isinstance(in_arg, LLLnode) and input_type == "int128":
        return LLLnode.from_list(["clampge", in_arg, 0],
                                 typ=BaseType("uint256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == "decimal":
        return LLLnode.from_list(
            ["div", ["clampge", in_arg, 0], DECIMAL_DIVISOR],
            typ=BaseType("uint256"),
            pos=getpos(expr),
        )

    elif isinstance(in_arg, LLLnode) and input_type == "bool":
        return LLLnode.from_list(in_arg,
                                 typ=BaseType("uint256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type in ("bytes32", "address"):
        return LLLnode(value=in_arg.value,
                       args=in_arg.args,
                       typ=BaseType("uint256"),
                       pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == "Bytes":
        if in_arg.typ.maxlen > 32:
            raise InvalidLiteral(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to uint256",
                expr,
            )
        return byte_array_to_num(in_arg, expr, "uint256")

    else:
        raise InvalidLiteral(f"Invalid input for uint256: {in_arg}", expr)
예제 #8
0
파일: convert.py 프로젝트: smarx/vyper
def to_decimal(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise TypeMismatchException(
                "Cannot convert bytes array of max length {} to decimal".
                format(in_arg.value), expr)
        num = byte_array_to_num(in_arg, expr, 'int128')
        return LLLnode.from_list(['mul', num, DECIMAL_DIVISOR],
                                 typ=BaseType('decimal'),
                                 pos=getpos(expr))

    else:
        _unit = in_arg.typ.unit
        _positional = in_arg.typ.positional

        if input_type == 'uint256':
            if in_arg.typ.is_literal and not SizeLimits.in_bounds(
                    'int128', (in_arg.value * DECIMAL_DIVISOR)):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg.value), expr)
            return LLLnode.from_list([
                'uclample', ['mul', in_arg, DECIMAL_DIVISOR],
                ['mload', MemoryPositions.MAXDECIMAL]
            ],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        elif input_type == 'bytes32':
            if in_arg.typ.is_literal and not SizeLimits.in_bounds(
                    'int128', (in_arg.value * DECIMAL_DIVISOR)):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg.value), expr)
            return LLLnode.from_list([
                'clamp', ['mload', MemoryPositions.MINDECIMAL],
                ['mul', in_arg, DECIMAL_DIVISOR],
                ['mload', MemoryPositions.MAXDECIMAL]
            ],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        elif input_type in ('int128', 'bool'):
            return LLLnode.from_list(['mul', in_arg, DECIMAL_DIVISOR],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        else:
            raise InvalidLiteralException(
                "Invalid input for decimal: %r" % in_arg, expr)
예제 #9
0
def to_bool(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "Bytes":
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to bool", expr,
            )
        else:
            num = byte_array_to_num(in_arg, expr, "uint256")
            return LLLnode.from_list(
                ["iszero", ["iszero", num]], typ=BaseType("bool"), pos=getpos(expr)
            )

    else:
        return LLLnode.from_list(
            ["iszero", ["iszero", in_arg]], typ=BaseType("bool"), pos=getpos(expr)
        )
예제 #10
0
def pack_logging_topics(event_id, args, expected_topics, context, pos):
    topics = [event_id]
    code_pos = pos
    for pos, expected_topic in enumerate(expected_topics):
        expected_type = expected_topic.typ
        arg = args[pos]
        value = Expr(arg, context).lll_node
        arg_type = value.typ

        if isinstance(arg_type, ByteArrayLike) and isinstance(
                expected_type, ByteArrayLike):
            if arg_type.maxlen > expected_type.maxlen:
                raise TypeMismatch(
                    f"Topic input bytes are too big: {arg_type} {expected_type}",
                    code_pos)
            if isinstance(arg, vy_ast.Str):
                bytez, bytez_length = string_to_bytes(arg.s)
                if len(bytez) > 32:
                    raise InvalidLiteral(
                        "Can only log a maximum of 32 bytes at a time.",
                        code_pos)
                topics.append(
                    bytes_to_int(bytez + b'\x00' * (32 - bytez_length)))
            else:
                if value.location == "memory":
                    size = ['mload', value]
                elif value.location == "storage":
                    size = ['sload', ['sha3_32', value]]
                topics.append(byte_array_to_num(value, arg, 'uint256', size))
        else:
            if arg_type != expected_type:
                raise TypeMismatch(
                    f"Invalid type for logging topic, got {arg_type} expected {expected_type}",
                    value.pos)
            value = unwrap_location(value)
            value = base_type_conversion(value,
                                         arg_type,
                                         expected_type,
                                         pos=code_pos)
            topics.append(value)

    return topics
예제 #11
0
파일: convert.py 프로젝트: smarx/vyper
def to_bool(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise TypeMismatchException(
                "Cannot convert bytes array of max length {} to int128".format(
                    in_arg.value), expr)
        else:
            num = byte_array_to_num(in_arg, expr, 'uint256')
            return LLLnode.from_list(['iszero', ['iszero', num]],
                                     typ=BaseType('bool'),
                                     pos=getpos(expr))

    elif in_arg.typ.is_literal and in_arg.typ.typ == 'bool':
        raise InvalidLiteralException(
            "Cannot convert to `bool` with boolean input literal.", expr)

    else:
        return LLLnode.from_list(['iszero', ['iszero', in_arg]],
                                 typ=BaseType('bool', in_arg.typ.unit),
                                 pos=getpos(expr))
예제 #12
0
파일: convert.py 프로젝트: olwee/vyper
def to_uint256(expr, args, kwargs, context):
    in_node = args[0]
    input_type, _ = get_type(in_node)

    if isinstance(in_node, int):
        if not SizeLimits.in_bounds('uint256', in_node):
            raise InvalidLiteralException(
                "Number out of range: {}".format(in_node))
        _unit = in_node.typ.unit if input_type == 'int128' else None
        return LLLnode.from_list(in_node,
                                 typ=BaseType('uint256', _unit),
                                 pos=getpos(expr))

    elif isinstance(
            in_node,
            LLLnode) and input_type in ('int128', 'num_literal', 'bool'):
        _unit = in_node.typ.unit if input_type == 'int128' else None
        return LLLnode.from_list(['clampge', in_node, 0],
                                 typ=BaseType('uint256', _unit),
                                 pos=getpos(expr))

    elif isinstance(in_node, LLLnode) and input_type in ('bytes32', 'address'):
        return LLLnode(value=in_node.value,
                       args=in_node.args,
                       typ=BaseType('uint256'),
                       pos=getpos(expr))

    elif isinstance(in_node, LLLnode) and input_type is 'bytes':
        if in_node.typ.maxlen > 32:
            raise InvalidLiteralException(
                "Cannot convert bytes array of max length {} to uint256".
                format(in_node.value), expr)
        return byte_array_to_num(in_node, expr, 'uint256')

    else:
        raise InvalidLiteralException(
            "Invalid input for uint256: %r" % in_node, expr)
예제 #13
0
def _RLPlist(expr, args, kwargs, context):
    # Second argument must be a list of types
    if not isinstance(args[1], ast.List):
        raise TypeMismatchException("Expecting list of types for second argument", args[1])
    if len(args[1].elts) == 0:
        raise TypeMismatchException("RLP list must have at least one item", expr)
    if len(args[1].elts) > 32:
        raise TypeMismatchException("RLP list must have at most 32 items", expr)
    # Get the output format
    _format = []
    for arg in args[1].elts:
        if isinstance(arg, ast.Name) and arg.id == "bytes":
            subtyp = ByteArrayType(args[0].typ.maxlen)
        else:
            subtyp = context.parse_type(arg, 'memory')
            if not isinstance(subtyp, BaseType):
                raise TypeMismatchException("RLP lists only accept BaseTypes and byte arrays", arg)
            if not is_base_type(subtyp, ('int128', 'uint256', 'bytes32', 'address', 'bool')):
                raise TypeMismatchException("Unsupported base type: %s" % subtyp.typ, arg)
        _format.append(subtyp)
    output_type = TupleType(_format)
    output_placeholder_type = ByteArrayType(
        (2 * len(_format) + 1 + get_size_of_type(output_type)) * 32,
    )
    output_placeholder = context.new_placeholder(output_placeholder_type)
    output_node = LLLnode.from_list(
        output_placeholder,
        typ=output_placeholder_type,
        location='memory',
    )
    # Create a decoder for each element in the tuple
    decoder = []
    for i, typ in enumerate(_format):
        # Decoder for bytes32
        if is_base_type(typ, 'bytes32'):
            decoder.append(LLLnode.from_list(
                [
                    'seq',
                    [
                        'assert',
                        [
                            'eq',
                            [
                                'mload',
                                [
                                    'add',
                                    output_node,
                                    ['mload', ['add', output_node, 32 * i]],
                                ],
                            ],
                            32,
                        ],
                    ],
                    [
                        'mload',
                        [
                            'add',
                            32,
                            [
                                'add',
                                output_node,
                                ['mload', ['add', output_node, 32 * i]],
                            ],
                        ],
                    ],
                ],
                typ,
                annotation='getting and checking bytes32 item',
            ))
        # Decoder for address
        elif is_base_type(typ, 'address'):
            decoder.append(LLLnode.from_list(
                [
                    'seq',
                    [
                        'assert',
                        [
                            'eq',
                            [
                                'mload',
                                [
                                    'add',
                                    output_node,
                                    ['mload', ['add', output_node, 32 * i]],
                                ],
                            ],
                            20,
                        ]
                    ],
                    [
                        'mod',
                        [
                            'mload',
                            [
                                'add',
                                20,
                                ['add', output_node, ['mload', ['add', output_node, 32 * i]]],
                            ],
                        ],
                        ['mload', MemoryPositions.ADDRSIZE],
                    ]
                ],
                typ,
                annotation='getting and checking address item',
            ))
        # Decoder for bytes
        elif isinstance(typ, ByteArrayType):
            decoder.append(LLLnode.from_list(
                [
                    'add',
                    output_node,
                    ['mload', ['add', output_node, 32 * i]],
                ],
                typ,
                location='memory',
                annotation='getting byte array',
            ))
        # Decoder for num and uint256
        elif is_base_type(typ, ('int128', 'uint256')):
            bytez = LLLnode.from_list(
                [
                    'add',
                    output_node,
                    ['mload', ['add', output_node, 32 * i]],
                ],
                typ,
                location='memory',
                annotation='getting and checking %s' % typ.typ,
            )
            decoder.append(byte_array_to_num(bytez, expr, typ.typ))
        # Decoder for bools
        elif is_base_type(typ, ('bool')):
            # This is basically a really clever way to test for a
            # length-prefixed one or zero. We take the 32 bytes starting one
            # byte *after* the start of the length declaration; this includes
            # the last 31 bytes of the length and the first byte of the value.
            # 0 corresponds to length 0, first byte 0, and 257 corresponds to
            # length 1, first byte \x01
            decoder.append(LLLnode.from_list(
                [
                    'with', '_ans', [
                        'mload',
                        [
                            'add',
                            1,
                            ['add', output_node, ['mload', ['add', output_node, 32 * i]]]
                        ],
                    ],
                    [
                        'seq',
                        ['assert', ['or', ['eq', '_ans', 0], ['eq', '_ans', 257]]],
                        ['div', '_ans', 257],
                    ],
                ],
                typ,
                annotation='getting and checking bool',
            ))
        else:
            # Should never reach because of top level base level check.
            raise Exception("Type not yet supported")  # pragma: no cover
    # Copy the input data to memory
    if args[0].location == "memory":
        variable_pointer = args[0]
    elif args[0].location == "storage":
        placeholder = context.new_placeholder(args[0].typ)
        placeholder_node = LLLnode.from_list(placeholder, typ=args[0].typ, location='memory')
        copier = make_byte_array_copier(
            placeholder_node,
            LLLnode.from_list('_ptr', typ=args[0].typ, location=args[0].location),
        )
        variable_pointer = ['with', '_ptr', args[0], ['seq', copier, placeholder_node]]
    else:
        # Should never reach because of top level base level check.
        raise Exception("Location not yet supported")  # pragma: no cover
    # Decode the input data
    initial_setter = LLLnode.from_list(
        ['seq',
            ['with', '_sub', variable_pointer,
                ['pop', ['call',
                         1500 + 400 * len(_format) + 10 * len(args),
                         LLLnode.from_list(RLP_DECODER_ADDRESS, annotation='RLP decoder'),
                         0,
                         ['add', '_sub', 32],
                         ['mload', '_sub'],
                         output_node,
                         64 * len(_format) + 32 + 32 * get_size_of_type(output_type)]]],
            ['assert', ['eq', ['mload', output_node], 32 * len(_format) + 32]]],
        typ=None)
    # Shove the input data decoder in front of the first variable decoder
    decoder[0] = LLLnode.from_list(
        ['seq', initial_setter, decoder[0]],
        typ=decoder[0].typ,
        location=decoder[0].location,
    )
    return LLLnode.from_list(
        ["multi"] + decoder,
        typ=output_type,
        location='memory',
        pos=getpos(expr),
    )
예제 #14
0
def bytes_to_num(expr, args, kwargs, context):
    return byte_array_to_num(args[0], expr, 'num')
예제 #15
0
파일: convert.py 프로젝트: maciejry/vyper
def to_int128(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)
    _unit = in_arg.typ.unit if input_type in ('uint256', 'decimal') else None

    if input_type == 'num_literal':
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds('int128', in_arg):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg))
            return LLLnode.from_list(in_arg,
                                     typ=BaseType('int128', _unit),
                                     pos=getpos(expr))
        elif isinstance(in_arg, float):
            if not SizeLimits.in_bounds('int128', math.trunc(in_arg)):
                raise InvalidLiteralException("Number out of range: {}".format(
                    math.trunc(in_arg)))
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType('int128', _unit),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteralException(
                "Unknown numeric literal type: {}".fornat(in_arg))

    elif input_type == 'bytes32':
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds('int128', in_arg.value):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg.value), expr)
            else:
                return LLLnode.from_list(in_arg,
                                         typ=BaseType('int128', _unit),
                                         pos=getpos(expr))
        else:
            return LLLnode.from_list([
                'clamp',
                ['mload', MemoryPositions.MINNUM],
                in_arg,
                ['mload', MemoryPositions.MAXNUM],
            ],
                                     typ=BaseType('int128', _unit),
                                     pos=getpos(expr))

    elif input_type in ('string', 'bytes'):
        if in_arg.typ.maxlen > 32:
            raise TypeMismatchException(
                "Cannot convert bytes array of max length {} to int128".format(
                    in_arg.value),
                expr,
            )
        return byte_array_to_num(in_arg, expr, 'int128')

    elif input_type == 'uint256':
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds('int128', in_arg.value):
                raise InvalidLiteralException(
                    "Number out of range: {}".format(in_arg.value), expr)
            else:
                return LLLnode.from_list(in_arg,
                                         typ=BaseType('int128', _unit),
                                         pos=getpos(expr))

        else:
            return LLLnode.from_list(
                ['uclample', in_arg, ['mload', MemoryPositions.MAXNUM]],
                typ=BaseType('int128', _unit),
                pos=getpos(expr))

    elif input_type == 'decimal':
        return LLLnode.from_list([
            'clamp',
            ['mload', MemoryPositions.MINNUM],
            ['sdiv', in_arg, DECIMAL_DIVISOR],
            ['mload', MemoryPositions.MAXNUM],
        ],
                                 typ=BaseType('int128', _unit),
                                 pos=getpos(expr))

    elif input_type == 'bool':
        return LLLnode.from_list(in_arg,
                                 typ=BaseType('int128', _unit),
                                 pos=getpos(expr))

    else:
        raise InvalidLiteralException("Invalid input for int128: %r" % in_arg,
                                      expr)
예제 #16
0
def to_decimal(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'bytes':
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to decimal",
                expr,
            )
        num = byte_array_to_num(in_arg, expr, 'int128')
        return LLLnode.from_list(['mul', num, DECIMAL_DIVISOR],
                                 typ=BaseType('decimal'),
                                 pos=getpos(expr))

    else:
        _unit = in_arg.typ.unit
        _positional = in_arg.typ.positional

        if input_type == 'uint256':
            if in_arg.typ.is_literal:
                if not SizeLimits.in_bounds('int128',
                                            (in_arg.value * DECIMAL_DIVISOR)):
                    raise InvalidLiteral(
                        f"Number out of range: {in_arg.value}",
                        expr,
                    )
                else:
                    return LLLnode.from_list(['mul', in_arg, DECIMAL_DIVISOR],
                                             typ=BaseType(
                                                 'decimal', _unit,
                                                 _positional),
                                             pos=getpos(expr))
            else:
                return LLLnode.from_list([
                    'uclample', ['mul', in_arg, DECIMAL_DIVISOR],
                    ['mload', MemoryPositions.MAXDECIMAL]
                ],
                                         typ=BaseType('decimal', _unit,
                                                      _positional),
                                         pos=getpos(expr))

        elif input_type == 'address':
            return LLLnode.from_list([
                'mul',
                [
                    'signextend',
                    15,
                    ['and', in_arg, (SizeLimits.ADDRSIZE - 1)],
                ], DECIMAL_DIVISOR
            ],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        elif input_type == 'bytes32':
            if in_arg.typ.is_literal:
                if not SizeLimits.in_bounds('int128',
                                            (in_arg.value * DECIMAL_DIVISOR)):
                    raise InvalidLiteral(
                        f"Number out of range: {in_arg.value}",
                        expr,
                    )
                else:
                    return LLLnode.from_list(['mul', in_arg, DECIMAL_DIVISOR],
                                             typ=BaseType(
                                                 'decimal', _unit,
                                                 _positional),
                                             pos=getpos(expr))
            else:
                return LLLnode.from_list([
                    'clamp',
                    ['mload', MemoryPositions.MINDECIMAL],
                    ['mul', in_arg, DECIMAL_DIVISOR],
                    ['mload', MemoryPositions.MAXDECIMAL],
                ],
                                         typ=BaseType('decimal', _unit,
                                                      _positional),
                                         pos=getpos(expr))

        elif input_type in ('int128', 'bool'):
            return LLLnode.from_list(['mul', in_arg, DECIMAL_DIVISOR],
                                     typ=BaseType('decimal', _unit,
                                                  _positional),
                                     pos=getpos(expr))

        else:
            raise InvalidLiteral(f"Invalid input for decimal: {in_arg}", expr)
예제 #17
0
def to_int256(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "num_literal":
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds("int256", in_arg):
                raise InvalidLiteral(f"Number out of range: {in_arg}")
            return LLLnode.from_list(in_arg,
                                     typ=BaseType("int256", ),
                                     pos=getpos(expr))
        elif isinstance(in_arg, Decimal):
            if not SizeLimits.in_bounds("int256", math.trunc(in_arg)):
                raise InvalidLiteral(
                    f"Number out of range: {math.trunc(in_arg)}")
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType("int256"),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteral(f"Unknown numeric literal type: {in_arg}")

    elif isinstance(in_arg, LLLnode) and input_type == "int128":
        return LLLnode.from_list(in_arg,
                                 typ=BaseType("int256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == "uint256":
        if version_check(begin="constantinople"):
            upper_bound = ["shl", 255, 1]
        else:
            upper_bound = -(2**255)
        return LLLnode.from_list(["uclamplt", in_arg, upper_bound],
                                 typ=BaseType("int256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type == "decimal":
        return LLLnode.from_list(
            ["sdiv", in_arg, DECIMAL_DIVISOR],
            typ=BaseType("int256"),
            pos=getpos(expr),
        )

    elif isinstance(in_arg, LLLnode) and input_type == "bool":
        return LLLnode.from_list(in_arg,
                                 typ=BaseType("int256"),
                                 pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type in ("bytes32", "address"):
        return LLLnode(value=in_arg.value,
                       args=in_arg.args,
                       typ=BaseType("int256"),
                       pos=getpos(expr))

    elif isinstance(in_arg, LLLnode) and input_type in ("Bytes", "String"):
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to int256",
                expr,
            )
        return byte_array_to_num(in_arg, expr, "int256")

    else:
        raise InvalidLiteral(f"Invalid input for int256: {in_arg}", expr)
예제 #18
0
def to_int128(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "num_literal":
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds("int128", in_arg):
                raise InvalidLiteral(f"Number out of range: {in_arg}")
            return LLLnode.from_list(in_arg, typ=BaseType("int128"), pos=getpos(expr))
        elif isinstance(in_arg, Decimal):
            if not SizeLimits.in_bounds("int128", math.trunc(in_arg)):
                raise InvalidLiteral(f"Number out of range: {math.trunc(in_arg)}")
            return LLLnode.from_list(math.trunc(in_arg), typ=BaseType("int128"), pos=getpos(expr))
        else:
            raise InvalidLiteral(f"Unknown numeric literal type: {in_arg}")

    elif input_type == "bytes32":
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds("int128", in_arg.value):
                raise InvalidLiteral(f"Number out of range: {in_arg.value}", expr)
            else:
                return LLLnode.from_list(in_arg, typ=BaseType("int128"), pos=getpos(expr))
        else:
            return LLLnode.from_list(
                [
                    "clamp",
                    ["mload", MemoryPositions.MINNUM],
                    in_arg,
                    ["mload", MemoryPositions.MAXNUM],
                ],
                typ=BaseType("int128"),
                pos=getpos(expr),
            )

    elif input_type == "address":
        return LLLnode.from_list(
            ["signextend", 15, ["and", in_arg, (SizeLimits.ADDRSIZE - 1)]],
            typ=BaseType("int128"),
            pos=getpos(expr),
        )

    elif input_type in ("String", "Bytes"):
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to int128", expr,
            )
        return byte_array_to_num(in_arg, expr, "int128")

    elif input_type == "uint256":
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds("int128", in_arg.value):
                raise InvalidLiteral(f"Number out of range: {in_arg.value}", expr)
            else:
                return LLLnode.from_list(in_arg, typ=BaseType("int128"), pos=getpos(expr))

        else:
            return LLLnode.from_list(
                ["uclample", in_arg, ["mload", MemoryPositions.MAXNUM]],
                typ=BaseType("int128"),
                pos=getpos(expr),
            )

    elif input_type == "decimal":
        return LLLnode.from_list(
            [
                "clamp",
                ["mload", MemoryPositions.MINNUM],
                ["sdiv", in_arg, DECIMAL_DIVISOR],
                ["mload", MemoryPositions.MAXNUM],
            ],
            typ=BaseType("int128"),
            pos=getpos(expr),
        )

    elif input_type == "bool":
        return LLLnode.from_list(in_arg, typ=BaseType("int128"), pos=getpos(expr))

    else:
        raise InvalidLiteral(f"Invalid input for int128: {in_arg}", expr)
예제 #19
0
def to_decimal(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == "Bytes":
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to decimal", expr,
            )
        num = byte_array_to_num(in_arg, expr, "int128")
        return LLLnode.from_list(
            ["mul", num, DECIMAL_DIVISOR], typ=BaseType("decimal"), pos=getpos(expr)
        )

    else:
        if input_type == "uint256":
            if in_arg.typ.is_literal:
                if not SizeLimits.in_bounds("int128", (in_arg.value * DECIMAL_DIVISOR)):
                    raise InvalidLiteral(
                        f"Number out of range: {in_arg.value}", expr,
                    )
                else:
                    return LLLnode.from_list(
                        ["mul", in_arg, DECIMAL_DIVISOR], typ=BaseType("decimal"), pos=getpos(expr)
                    )
            else:
                return LLLnode.from_list(
                    [
                        "uclample",
                        ["mul", in_arg, DECIMAL_DIVISOR],
                        ["mload", MemoryPositions.MAXDECIMAL],
                    ],
                    typ=BaseType("decimal"),
                    pos=getpos(expr),
                )

        elif input_type == "address":
            return LLLnode.from_list(
                [
                    "mul",
                    ["signextend", 15, ["and", in_arg, (SizeLimits.ADDRSIZE - 1)]],
                    DECIMAL_DIVISOR,
                ],
                typ=BaseType("decimal"),
                pos=getpos(expr),
            )

        elif input_type == "bytes32":
            if in_arg.typ.is_literal:
                if not SizeLimits.in_bounds("int128", (in_arg.value * DECIMAL_DIVISOR)):
                    raise InvalidLiteral(
                        f"Number out of range: {in_arg.value}", expr,
                    )
                else:
                    return LLLnode.from_list(
                        ["mul", in_arg, DECIMAL_DIVISOR], typ=BaseType("decimal"), pos=getpos(expr)
                    )
            else:
                return LLLnode.from_list(
                    [
                        "clamp",
                        ["mload", MemoryPositions.MINDECIMAL],
                        ["mul", in_arg, DECIMAL_DIVISOR],
                        ["mload", MemoryPositions.MAXDECIMAL],
                    ],
                    typ=BaseType("decimal"),
                    pos=getpos(expr),
                )

        elif input_type in ("int128", "bool"):
            return LLLnode.from_list(
                ["mul", in_arg, DECIMAL_DIVISOR], typ=BaseType("decimal"), pos=getpos(expr)
            )

        else:
            raise InvalidLiteral(f"Invalid input for decimal: {in_arg}", expr)
예제 #20
0
파일: convert.py 프로젝트: 6pakla/vyper
def to_int128(expr, args, kwargs, context):
    in_arg = args[0]
    input_type, _ = get_type(in_arg)

    if input_type == 'num_literal':
        if isinstance(in_arg, int):
            if not SizeLimits.in_bounds('int128', in_arg):
                raise InvalidLiteral(f"Number out of range: {in_arg}")
            return LLLnode.from_list(in_arg,
                                     typ=BaseType('int128'),
                                     pos=getpos(expr))
        elif isinstance(in_arg, Decimal):
            if not SizeLimits.in_bounds('int128', math.trunc(in_arg)):
                raise InvalidLiteral(
                    f"Number out of range: {math.trunc(in_arg)}")
            return LLLnode.from_list(math.trunc(in_arg),
                                     typ=BaseType('int128'),
                                     pos=getpos(expr))
        else:
            raise InvalidLiteral(f"Unknown numeric literal type: {in_arg}")

    elif input_type == 'bytes32':
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds('int128', in_arg.value):
                raise InvalidLiteral(f"Number out of range: {in_arg.value}",
                                     expr)
            else:
                return LLLnode.from_list(in_arg,
                                         typ=BaseType('int128'),
                                         pos=getpos(expr))
        else:
            return LLLnode.from_list([
                'clamp',
                ['mload', MemoryPositions.MINNUM],
                in_arg,
                ['mload', MemoryPositions.MAXNUM],
            ],
                                     typ=BaseType('int128'),
                                     pos=getpos(expr))

    elif input_type == 'address':
        return LLLnode.from_list([
            'signextend',
            15,
            ['and', in_arg, (SizeLimits.ADDRSIZE - 1)],
        ],
                                 typ=BaseType('int128'),
                                 pos=getpos(expr))

    elif input_type in ('string', 'bytes'):
        if in_arg.typ.maxlen > 32:
            raise TypeMismatch(
                f"Cannot convert bytes array of max length {in_arg.typ.maxlen} to int128",
                expr,
            )
        return byte_array_to_num(in_arg, expr, 'int128')

    elif input_type == 'uint256':
        if in_arg.typ.is_literal:
            if not SizeLimits.in_bounds('int128', in_arg.value):
                raise InvalidLiteral(f"Number out of range: {in_arg.value}",
                                     expr)
            else:
                return LLLnode.from_list(in_arg,
                                         typ=BaseType('int128'),
                                         pos=getpos(expr))

        else:
            return LLLnode.from_list(
                ['uclample', in_arg, ['mload', MemoryPositions.MAXNUM]],
                typ=BaseType('int128'),
                pos=getpos(expr))

    elif input_type == 'decimal':
        return LLLnode.from_list([
            'clamp',
            ['mload', MemoryPositions.MINNUM],
            ['sdiv', in_arg, DECIMAL_DIVISOR],
            ['mload', MemoryPositions.MAXNUM],
        ],
                                 typ=BaseType('int128'),
                                 pos=getpos(expr))

    elif input_type == 'bool':
        return LLLnode.from_list(in_arg,
                                 typ=BaseType('int128'),
                                 pos=getpos(expr))

    else:
        raise InvalidLiteral(f"Invalid input for int128: {in_arg}", expr)