コード例 #1
0
ファイル: definition.py プロジェクト: marcoeilers/nagini
    def _create_termination_check(self, operation: PythonIOOperation,
                                  ctx: Context) -> Method:
        """Create a termination check."""
        assert not ctx.current_function
        ctx.current_function = operation

        name = ctx.module.get_fresh_name(operation.sil_name +
                                         '__termination_check')
        if operation.sil_name not in self.viper.used_names_sets:
            self.viper.used_names_sets[operation.sil_name] = set()
        self.viper.used_names_sets[operation.sil_name].add(name)
        parameters = [
            parameter.decl for parameter in operation.get_parameters()
        ]

        locals = [v.decl for v in operation._io_universals]

        info = self.no_info(ctx)
        pos = self.to_position(operation.get_termination_measure(), ctx)

        local_type_assumptions = [
            self.viper.Inhale(
                self.type_check(v.ref(), v.type, pos, ctx, False), pos, info)
            for v in operation._io_universals
        ]

        statement, termination_condition = self.translate_expr(
            operation.get_terminates(), ctx, target_type=self.viper.Bool)
        assert not statement
        statement, termination_measure = self.translate_expr(
            operation.get_termination_measure(),
            ctx,
            target_type=self.viper.Int)
        assert not statement

        generator = TerminationCheckGenerator(
            self, ctx, termination_condition, termination_measure,
            operation.get_termination_measure())
        if operation.is_basic():
            checks = generator.create_checks()
        else:
            checks = generator.create_checks(operation.get_body())

        body = self.translate_block(local_type_assumptions + checks, pos, info)
        pres = self._create_typeof_pres(operation.get_parameters(), ctx)
        ctx.current_function = None
        result = self.viper.Method(name=name,
                                   args=parameters,
                                   returns=[],
                                   pres=pres,
                                   posts=[],
                                   locals=locals,
                                   body=body,
                                   position=self.no_position(ctx),
                                   info=info)

        return result
コード例 #2
0
ファイル: definition.py プロジェクト: marcoeilers/nagini
    def _translate_defining_getters(self, main_operation: PythonIOOperation,
                                    ctx: Context) -> None:
        """Translate defining getter instances of existential variables."""
        assert not main_operation.is_basic()
        assert ctx.current_function is None
        ctx.current_function = main_operation

        existentials = main_operation.get_io_existentials()
        existentials.sort(key=lambda var: var.defining_order)

        for existential in existentials:
            node, result = existential.get_defining_info()
            getter = self.create_result_getter(node, result, ctx)
            existential.set_existential_ref(getter)

        ctx.current_function = None
コード例 #3
0
ファイル: definition.py プロジェクト: zeta1999/nagini
    def _create_termination_check(self, operation: PythonIOOperation,
                                  ctx: Context) -> Method:
        """Create a termination check."""
        assert not ctx.current_function
        ctx.current_function = operation

        name = ctx.module.get_fresh_name(operation.sil_name +
                                         '__termination_check')
        parameters = [
            parameter.decl for parameter in operation.get_parameters()
        ]

        statement, termination_condition = self.translate_expr(
            operation.get_terminates(), ctx, target_type=self.viper.Bool)
        assert not statement
        statement, termination_measure = self.translate_expr(
            operation.get_termination_measure(),
            ctx,
            target_type=self.viper.Int)
        assert not statement

        generator = TerminationCheckGenerator(
            self, ctx, termination_condition, termination_measure,
            operation.get_termination_measure())
        if operation.is_basic():
            checks = generator.create_checks()
        else:
            checks = generator.create_checks(operation.get_body())

        info = self.no_info(ctx)
        position = self.to_position(operation.get_termination_measure(), ctx)

        body = self.translate_block(checks, position, info)
        pres = self._create_typeof_pres(operation.get_parameters(), ctx)
        ctx.current_function = None
        result = self.viper.Method(name=name,
                                   args=parameters,
                                   returns=[],
                                   pres=pres,
                                   posts=[],
                                   locals=[],
                                   body=body,
                                   position=self.no_position(ctx),
                                   info=info)

        return result
コード例 #4
0
ファイル: common.py プロジェクト: zeta1999/nagini
    def set_up_io_operation_input_aliases(self, operation: PythonIOOperation,
                                          node: ast.Call,
                                          ctx: Context) -> List[str]:
        """Set up aliases from operation's parameters to its arguments."""
        aliases = []

        parameters = operation.get_parameters()
        py_args = node.args[:len(parameters)]
        sil_args = self.translate_args(py_args, parameters, ctx)
        for parameter, py_arg, sil_arg in zip(parameters, py_args, sil_args):
            var_type = self.get_type(py_arg, ctx).try_unbox()
            var = PythonIOExistentialVar(parameter.name, py_arg, var_type)
            var.set_ref(sil_arg, None)
            ctx.set_alias(parameter.name, var)
            aliases.append(parameter.name)

        return aliases
コード例 #5
0
ファイル: common.py プロジェクト: marcoeilers/nagini
 def add_handlers_for_inlines(self, ctx: Context) -> List[Stmt]:
     stmts = []
     old_var_valiases = ctx.var_aliases
     old_lbl_aliases = ctx.label_aliases
     for (added_method, var_aliases, lbl_aliases) in ctx.added_handlers:
         ctx.var_aliases = var_aliases
         ctx.label_aliases = lbl_aliases
         ctx.inlined_calls.append(added_method)
         for block in added_method.try_blocks:
             for handler in block.handlers:
                 stmts += self.translate_handler(handler, ctx)
             if block.else_block:
                 stmts += self.translate_handler(block.else_block, ctx)
             if block.finally_block:
                 stmts += self.translate_finally(block, ctx)
         ctx.inlined_calls.remove(added_method)
     ctx.added_handlers = []
     ctx.var_aliases = old_var_valiases
     ctx.label_aliases = old_lbl_aliases
     return stmts
コード例 #6
0
ファイル: method.py プロジェクト: zeta1999/nagini
    def create_method_node(  # pylint: disable=too-many-arguments,too-many-locals
            self,
            ctx: Context,
            name: str,
            original_args: List[VarDecl],
            returns: List[VarDecl],
            pres: List[Expr],
            posts: List[Expr],
            local_vars: List[VarDecl],
            body: List[Stmt],
            position: Position,
            info: Info,
            method: PythonMethod = None,
            overriding_check: bool = False) -> Method:
        """Construct method AST node with additional obligation stuff."""
        if method is None:
            method = find_method_by_sil_name(ctx, name)
        if method is None:
            # Assume that this is a method that is never called from
            # Python and, as a result, does not need obligation stuff.
            return self.viper.Method(name, original_args, returns, pres, posts,
                                     local_vars, body, position, info)

        assert (ctx.current_function is None or ctx.current_function == method)
        old_method = ctx.current_function
        ctx.current_function = method

        obligation_method = ObligationMethod(name, original_args, returns,
                                             pres, posts, local_vars, body)
        constructor = ObligationMethodNodeConstructor(obligation_method,
                                                      method, self, ctx,
                                                      self._obligation_manager,
                                                      position, info,
                                                      overriding_check)
        constructor.add_obligations()
        node = constructor.construct_node()

        ctx.current_function = old_method
        return node
コード例 #7
0
ファイル: common.py プロジェクト: marcoeilers/nagini
 def get_fresh_int_lit(self, ctx: Context) -> Expr:
     """
     Returns an integer literal with a fresh value.
     """
     return self.viper.IntLit(ctx.get_fresh_int(), self.no_position(ctx),
                              self.no_info(ctx))