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
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
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
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_))
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))}")
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))
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
def result(self): return Literal(int(get_val(self._expression)), self._type)