Example #1
0
def replace_with_value(node, var, value):
    if node.value == "with" and node.args[0].value == var:
        return LLLnode(node.value, [
            node.args[0],
            replace_with_value(node.args[1], var, value), node.args[2]
        ], node.typ, node.location, node.annotation)
    elif node.value == var:
        return LLLnode(value, [], node.typ, node.location, node.annotation)
    else:
        return LLLnode(
            node.value,
            [replace_with_value(arg, var, value)
             for arg in node.args], node.typ, node.location, node.annotation)
Example #2
0
def as_num256(expr, args, kwargs, context):
    if isinstance(args[0], int):
        if not(0 <= args[0] <= 2**256 - 1):
            raise InvalidLiteralException("Number out of range: " + str(expr.args[0].n), expr.args[0])
        return LLLnode.from_list(args[0], typ=BaseType('num256', None), pos=getpos(expr))
    elif isinstance(args[0], LLLnode):
        if args[0].value == "sub" and args[0].args[0].value == 0 and args[0].args[1].value > 0:
            raise InvalidLiteralException("Negative numbers cannot be num256 literals")
        return LLLnode(value=args[0].value, args=args[0].args, typ=BaseType('num256'), pos=getpos(expr))
    else:
        raise InvalidLiteralException("Invalid input for num256: %r" % args[0], expr)
Example #3
0
def as_num256(expr, args, kwargs, context):
    if isinstance(args[0], int):
        if not (0 <= args[0] <= 2**256 - 1):
            raise InvalidLiteralException(
                "Number out of range: " + str(expr.args[0].n), expr.args[0])
        return LLLnode.from_list(args[0],
                                 typ=BaseType('num256'),
                                 pos=getpos(expr))
    elif isinstance(
            args[0],
            LLLnode) and args[0].typ.typ in ('num', 'num_literal', 'address'):
        return LLLnode.from_list(['clampge', args[0], 0],
                                 typ=BaseType('num256'),
                                 pos=getpos(expr))
    elif isinstance(args[0], LLLnode):
        return LLLnode(value=args[0].value,
                       args=args[0].args,
                       typ=BaseType('num256'),
                       pos=getpos(expr))
    else:
        raise InvalidLiteralException("Invalid input for num256: %r" % args[0],
                                      expr)
Example #4
0
def method_id(expr, args, kwargs, context):
    method_id = fourbytes_to_int(sha3(args[0])[:4])
    return LLLnode(method_id, typ=BaseType('method_id'), pos=getpos(expr))
Example #5
0
def as_bytes32(expr, args, kwargs, context):
    return LLLnode(value=args[0].value, args=args[0].args, typ=BaseType('bytes32'), pos=getpos(expr))
Example #6
0
def as_unitless_number(expr, args, kwargs, context):
    return LLLnode(value=args[0].value, args=args[0].args, typ=BaseType(args[0].typ.typ, {}), pos=getpos(expr))
Example #7
0
def optimize(node):
    argz = [optimize(arg) for arg in node.args]
    if node.value in arith and int_at(argz, 0) and int_at(argz, 1):
        left, right = get_int_at(argz, 0), get_int_at(argz, 1)
        calcer, symb = arith[node.value]
        new_value = calcer(left, right)
        if argz[0].annotation and argz[1].annotation:
            annotation = argz[0].annotation + symb + argz[1].annotation
        elif argz[0].annotation or argz[1].annotation:
            annotation = (argz[0].annotation or str(left)) + symb + (
                argz[1].annotation or str(right))
        else:
            annotation = ''
        return LLLnode(new_value, [], node.typ, None, node.pos, annotation)
    elif node.value == "add" and int_at(
            argz, 0) and argz[1].value == "add" and int_at(argz[1].args, 0):
        calcer, symb = arith[node.value]
        if argz[0].annotation and argz[1].args[0].annotation:
            annotation = argz[0].annotation + symb + argz[1].args[0].annotation
        elif argz[0].annotation or argz[1].args[0].annotation:
            annotation = (argz[0].annotation or str(argz[0].value)) + symb + (
                argz[1].args[0].annotation or str(argz[1].args[0].value))
        else:
            annotation = ''
        return LLLnode("add", [
            LLLnode(argz[0].value + argz[1].args[0].value,
                    annotation=annotation), argz[1].args[1]
        ], node.typ, None, node.annotation)
    elif node.value == "add" and get_int_at(argz, 0) == 0:
        return LLLnode(argz[1].value, argz[1].args, node.typ, node.location,
                       node.pos, argz[1].annotation)
    elif node.value == "add" and get_int_at(argz, 1) == 0:
        return LLLnode(argz[0].value, argz[0].args, node.typ, node.location,
                       node.pos, argz[0].annotation)
    elif node.value == "clamp" and int_at(argz, 0) and int_at(
            argz, 1) and int_at(argz, 2):
        if get_int_at(argz, 0, True) > get_int_at(argz, 1, True):
            raise Exception("Clamp always fails")
        elif get_int_at(argz, 1, True) > get_int_at(argz, 2, True):
            raise Exception("Clamp always fails")
        else:
            return argz[1]
    elif node.value == "clamp" and int_at(argz, 0) and int_at(argz, 1):
        if get_int_at(argz, 0, True) > get_int_at(argz, 1, True):
            raise Exception("Clamp always fails")
        else:
            return LLLnode("clample", [argz[1], argz[2]], node.typ,
                           node.location, node.pos, node.annotation)
    elif node.value == "clamp_nonzero" and int_at(argz, 0):
        if get_int_at(argz, 0) != 0:
            return LLLnode(argz[0].value, [], node.typ, node.location,
                           node.pos, node.annotation)
        else:
            raise Exception("Clamp always fails")
    # Turns out this is actually not such a good optimization after all
    elif node.value == "with" and int_at(
            argz, 1) and not search_for_set(argz[2], argz[0].value) and False:
        o = replace_with_value(argz[2], argz[0].value, argz[1].value)
        return o
    elif node.value == "seq":
        o = []
        for arg in argz:
            if arg.value == "seq":
                o.extend(arg.args)
            elif arg.value != "pass":
                o.append(arg)
        return LLLnode(node.value,
                       o,
                       node.typ,
                       node.location,
                       node.pos,
                       node.annotation,
                       add_gas_estimate=node.add_gas_estimate)
    elif hasattr(node, 'total_gas'):
        o = LLLnode(node.value,
                    argz,
                    node.typ,
                    node.location,
                    node.pos,
                    node.annotation,
                    add_gas_estimate=node.add_gas_estimate)
        o.total_gas = node.total_gas - node.gas + o.gas
        o.func_name = node.func_name
        return o
    else:
        return LLLnode(node.value,
                       argz,
                       node.typ,
                       node.location,
                       node.pos,
                       node.annotation,
                       add_gas_estimate=node.add_gas_estimate)