Exemplo n.º 1
0
 def translate_Attribute(self, node: ast.Attribute, _: List[Stmt],
                         ctx: Context) -> Expr:
     pos = self.to_position(node, ctx)
     assert isinstance(node.value, ast.Name)
     interface = ctx.current_program.interfaces[node.value.id]
     with ctx.program_scope(interface):
         self_address = ctx.self_address or helpers.self_address(
             self.viper_ast)
         return self._resource(node.attr, [self_address], ctx, pos)
Exemplo n.º 2
0
 def translate_Name(self, node: ast.Name, _: List[Stmt],
                    ctx: Context) -> Expr:
     pos = self.to_position(node, ctx)
     if node.id == names.UNDERLYING_WEI:
         return self._resource(node.id, [], ctx, pos)
     else:
         self_address = ctx.self_address or helpers.self_address(
             self.viper_ast)
         return self._resource(node.id, [self_address], ctx, pos)
Exemplo n.º 3
0
 def resource(self,
              name: str,
              args: List[Expr],
              ctx: Context,
              pos=None) -> Expr:
     self_address = ctx.self_address or helpers.self_address(self.viper_ast)
     args = list(args)
     args.append(self_address)
     _, expr = self._resource(name, args, ctx, pos)
     return expr
Exemplo n.º 4
0
    def translate(self,
                  resource: Optional[ast.Node],
                  res: List[Stmt],
                  ctx: Context,
                  return_resource=False) -> Union[Expr, Tuple[Resource, Expr]]:
        if resource:
            resource, expr = super().translate(resource, res, ctx)
        else:
            self_address = ctx.self_address or helpers.self_address(
                self.viper_ast)
            resource, expr = self._resource(names.WEI, [self_address], ctx)

        if return_resource:
            return resource, expr
        else:
            return expr
Exemplo n.º 5
0
 def translate_FunctionCall(self, node: ast.FunctionCall, res: List[Stmt],
                            ctx: Context) -> Expr:
     pos = self.to_position(node, ctx)
     if node.name == names.CREATOR:
         resource = self.translate(node.args[0], res, ctx)
         return None, self.creator_resource(resource, ctx, pos)
     elif node.resource:
         address = self.specification_translator.translate(
             node.resource, res, ctx)
     else:
         address = ctx.self_address or helpers.self_address(self.viper_ast)
     args = [
         self.specification_translator.translate(arg, res, ctx)
         for arg in node.args
     ]
     args.append(address)
     return self._resource(node.name, args, ctx, pos)
Exemplo n.º 6
0
    def translate_ReceiverCall(self, node: ast.ReceiverCall, res: List[Stmt],
                               ctx: Context) -> Expr:
        pos = self.to_position(node, ctx)
        if isinstance(node.receiver, ast.Name):
            interface = ctx.current_program.interfaces[node.receiver.id]
            address = ctx.self_address or helpers.self_address(self.viper_ast)
        elif isinstance(node.receiver, ast.Subscript):
            assert isinstance(node.receiver.value, ast.Attribute)
            assert isinstance(node.receiver.value.value, ast.Name)
            interface_name = node.receiver.value.value.id
            interface = ctx.current_program.interfaces[interface_name]
            address = self.specification_translator.translate(
                node.receiver.index, res, ctx)
        else:
            assert False

        with ctx.program_scope(interface):
            args = [
                self.specification_translator.translate(arg, res, ctx)
                for arg in node.args
            ]
            args.append(address)
            return self._resource(node.name, args, ctx, pos)
Exemplo n.º 7
0
    def translate(self, function: VyperFunction, ctx: Context) -> Function:
        with ctx.function_scope():
            pos = self.to_position(function.node, ctx)

            ctx.function = function
            ctx.is_pure_function = True

            args = {
                name: self._translate_pure_non_local_var(var, ctx)
                for name, var in function.args.items()
            }
            state = {
                names.SELF:
                TranslatedVar(names.SELF,
                              mangled.present_state_var_name(names.SELF),
                              types.AnyStructType(), self.viper_ast, pos)
            }
            ctx.present_state = state
            ctx.old_state = ctx.present_state
            ctx.pre_state = ctx.present_state
            ctx.issued_state = ctx.present_state
            ctx.current_state = ctx.present_state
            ctx.current_old_state = ctx.present_state

            ctx.args = args.copy()
            ctx.locals = {}

            ctx.success_var = TranslatedPureIndexedVar(names.SUCCESS,
                                                       mangled.SUCCESS_VAR,
                                                       types.VYPER_BOOL,
                                                       self.viper_ast)

            ctx.return_label = None
            ctx.revert_label = None

            ctx.result_var = TranslatedPureIndexedVar(
                names.RESULT, mangled.RESULT_VAR, function.type.return_type,
                self.viper_ast)

            body = []

            # State type assumptions
            for state_var in ctx.present_state.values():
                type_assumptions = self.type_translator.type_assumptions(
                    state_var.local_var(ctx), state_var.type, ctx)
                body.extend(type_assumptions)

            # Assume type assumptions for self address
            self_address = helpers.self_address(self.viper_ast)
            self_address_ass = self.type_translator.type_assumptions(
                self_address, types.VYPER_ADDRESS, ctx)
            body.extend(self_address_ass)

            # Assume type assumptions for arguments
            for var in function.args.values():
                local_var = args[var.name].local_var(ctx)
                assumptions = self.type_translator.type_assumptions(
                    local_var, var.type, ctx)
                body.extend(assumptions)

            # If we do not encounter an exception we will return success
            ctx.success_var.new_idx()
            body.append(
                self.viper_ast.EqCmp(ctx.success_var.local_var(ctx),
                                     self.viper_ast.TrueLit()))

            self.statement_translator.translate_stmts(function.node.body, body,
                                                      ctx)

            viper_struct_type = helpers.struct_type(self.viper_ast)
            function_result = self.viper_ast.Result(viper_struct_type)

            def partial_unfinished_cond_expression(cond_and_idx):
                cond, idx = cond_and_idx

                def unfinished_cond_expression(expr):
                    val = helpers.struct_get_idx(self.viper_ast,
                                                 function_result, idx,
                                                 viper_type, pos)
                    return self.viper_ast.CondExp(cond, val, expr)

                return unfinished_cond_expression

            # Generate success variable
            viper_type = self.viper_ast.Bool
            unfinished_cond_expressions = list(
                map(partial_unfinished_cond_expression, ctx.pure_success))
            value = reduce(lambda expr, func: func(expr),
                           reversed(unfinished_cond_expressions),
                           self.viper_ast.TrueLit())
            # Set success variable at slot 0
            success_var = helpers.struct_pure_get_success(
                self.viper_ast, function_result, pos)
            success_cond_expr = self.viper_ast.CondExp(
                value, self.viper_ast.TrueLit(), self.viper_ast.FalseLit())
            body.append(self.viper_ast.EqCmp(success_var, success_cond_expr))

            # Generate result variable
            viper_type = self.viper_ast.Bool
            default_value = self.viper_ast.TrueLit()
            if function.type.return_type:
                viper_type = self.type_translator.translate(
                    function.type.return_type, ctx)
                default_value = self.type_translator.default_value(
                    function.node, function.type.return_type, body, ctx)
            unfinished_cond_expressions = list(
                map(partial_unfinished_cond_expression, ctx.pure_returns))
            value = reduce(lambda expr, func: func(expr),
                           reversed(unfinished_cond_expressions),
                           default_value)
            # Set result variable at slot 1
            result_var = helpers.struct_pure_get_result(
                self.viper_ast, function_result, viper_type, pos)
            body.append(self.viper_ast.EqCmp(result_var, value))

            # Arguments have to be TranslatedVar. Therefore, transform the non-local TranslatedPureIndexedVar to
            # local TranslatedVar.
            arg_transform = []
            new_args = {}
            for arg_name, arg in args.items():
                assert isinstance(arg, TranslatedPureIndexedVar)
                if not arg.is_local:
                    lhs = arg.local_var(ctx)
                    new_arg = TranslatedVar(arg.name,
                                            arg.mangled_name,
                                            arg.type,
                                            arg.viper_ast,
                                            arg.pos,
                                            arg.info,
                                            is_local=True)
                    rhs = new_arg.local_var(ctx)
                    arg_transform.append(self.viper_ast.EqCmp(lhs, rhs))
                    new_args[arg_name] = new_arg
            body = arg_transform + body
            args_list = [
                arg.var_decl(ctx)
                for arg in chain(state.values(), new_args.values())
            ]

            viper_name = mangled.pure_function_name(function.name)
            function = self.viper_ast.Function(
                viper_name, args_list, helpers.struct_type(self.viper_ast), [],
                body, None, pos)
            return function