示例#1
0
文件: convert.py 项目: rluijk/slither
def convert_to_push(ir):
    """
    Convert a call to a PUSH operaiton

    The funciton assume to receive a correct IR
    The checks must be done by the caller

    May necessitate to create an intermediate operation (InitArray)
    As a result, the function return may return a list
    """
    if isinstance(ir.arguments[0], list):
        ret = []

        val = TemporaryVariable()
        operation = InitArray(ir.arguments[0], val)
        ret.append(operation)

        ir = Push(ir.destination, val)

        length = Literal(len(operation.init_values))
        t = operation.init_values[0].type
        ir.lvalue.set_type(ArrayType(t, length))

        ret.append(ir)
        return ret

    ir = Push(ir.destination, ir.arguments[0])
    return ir
示例#2
0
def convert_to_push(ir, node):
    """
    Convert a call to a PUSH operaiton

    The funciton assume to receive a correct IR
    The checks must be done by the caller

    May necessitate to create an intermediate operation (InitArray)
    Necessitate to return the lenght (see push documentation)
    As a result, the function return may return a list
    """

    # TODO remove Push Operator, and change this to existing operators

    lvalue = ir.lvalue
    if isinstance(ir.arguments[0], list):
        ret = []

        val = TemporaryVariable(node)
        operation = InitArray(ir.arguments[0], val)
        operation.set_expression(ir.expression)
        ret.append(operation)

        prev_ir = ir
        ir = Push(ir.destination, val)
        ir.set_expression(prev_ir.expression)

        length = Literal(len(operation.init_values), 'uint256')
        t = operation.init_values[0].type
        ir.lvalue.set_type(ArrayType(t, length))

        ret.append(ir)

        if lvalue:
            length = Length(ir.array, lvalue)
            length.set_expression(ir.expression)
            length.lvalue.points_to = ir.lvalue
            ret.append(length)

        return ret

    prev_ir = ir
    ir = Push(ir.destination, ir.arguments[0])
    ir.set_expression(prev_ir.expression)

    if lvalue:
        ret = []
        ret.append(ir)

        length = Length(ir.array, lvalue)
        length.set_expression(ir.expression)
        length.lvalue.points_to = ir.lvalue
        ret.append(length)
        return ret

    return ir
示例#3
0
 def __init__(self, t, length):
     assert isinstance(t, Type)
     if length:
         if isinstance(length, int):
             length = Literal(length)
         assert isinstance(length, Expression)
     super(ArrayType, self).__init__()
     self._type = t
     self._length = length
示例#4
0
def parse_yul_literal(root: YulScope, node: YulNode,
                      ast: Dict) -> Optional[Expression]:
    type_ = ast['type']
    value = ast['value']

    if not type_:
        type_ = 'bool' if value in ['true', 'false'] else 'uint256'

    return Literal(value, ElementaryType(type_))
示例#5
0
def parse_yul_function_call(root: YulScope, node: YulNode,
                            ast: Dict) -> Optional[Expression]:
    args = [parse_yul(root, node, arg) for arg in ast["arguments"]]
    ident = parse_yul(root, node, ast["functionName"])

    if not isinstance(ident, Identifier):
        raise SlitherException(
            "expected identifier from parsing function name")

    if isinstance(ident.value, YulBuiltin):
        name = ident.value.name
        if name in binary_ops:
            if name in ["shl", "shr", "sar"]:
                # lmao ok
                return BinaryOperation(args[1], args[0], binary_ops[name])

            return BinaryOperation(args[0], args[1], binary_ops[name])

        if name in unary_ops:
            return UnaryOperation(args[0], unary_ops[name])

        if name == "stop":
            name = "return"
            ident = Identifier(
                SolidityFunction(format_function_descriptor(name)))
            args = [
                Literal("0", ElementaryType("uint256")),
                Literal("0", ElementaryType("uint256")),
            ]

        else:
            ident = Identifier(
                SolidityFunction(format_function_descriptor(ident.value.name)))

    if isinstance(ident.value, Function):
        return CallExpression(ident, args,
                              vars_to_typestr(ident.value.returns))
    if isinstance(ident.value, SolidityFunction):
        return CallExpression(ident, args,
                              vars_to_typestr(ident.value.return_type))

    raise SlitherException(
        f"unexpected function call target type {str(type(ident.value))}")
示例#6
0
def parse_yul_literal(_root: YulScope, _node: YulNode, ast: Dict) -> Optional[Expression]:
    kind = ast["kind"]
    value = ast["value"]

    if not kind:
        kind = "bool" if value in ["true", "false"] else "uint256"

    if kind == "number":
        kind = "uint256"

    return Literal(value, ElementaryType(kind))
示例#7
0
    def __init__(self, t, length):
        assert isinstance(t, Type)
        if length:
            if isinstance(length, int):
                length = Literal(length, 'uint256')
            assert isinstance(length, Expression)
        super(ArrayType, self).__init__()
        self._type = t
        self._length = length

        if length:
            if not isinstance(length, Literal):
                cf = ConstantFolding(length, "uint256")
                length = cf.result()
            self._length_value = length
        else:
            self._length_value = None
示例#8
0
 def result(self):
     return Literal(int(get_val(self._expression)), self._type)