Exemple #1
0
    def exc_from_raise(self, w_arg1, w_arg2):
        """
        Create a wrapped exception from the arguments of a raise statement.

        Returns an FSException object whose w_value is an instance of w_type.
        """
        w_is_type = op.simple_call(const(isinstance), w_arg1, const(type)).eval(self)
        if self.guessbool(w_is_type):
            # this is for all cases of the form (Class, something)
            if self.guessbool(op.is_(w_arg2, w_None).eval(self)):
                # raise Type: we assume we have to instantiate Type
                w_value = op.simple_call(w_arg1).eval(self)
            else:
                w_valuetype = op.type(w_arg2).eval(self)
                if self.guessbool(op.issubtype(w_valuetype, w_arg1).eval(self)):
                    # raise Type, Instance: let etype be the exact type of value
                    w_value = w_arg2
                else:
                    # raise Type, X: assume X is the constructor argument
                    w_value = op.simple_call(w_arg1, w_arg2).eval(self)
        else:
            # the only case left here is (inst, None), from a 'raise inst'.
            if not self.guessbool(op.is_(w_arg2, const(None)).eval(self)):
                exc = TypeError("instance exception may not have a "
                                "separate value")
                raise Raise(const(exc))
            w_value = w_arg1
        w_type = op.type(w_value).eval(self)
        return FSException(w_type, w_value)
Exemple #2
0
    def exc_from_raise(self, w_arg1, w_arg2):
        """
        Create a wrapped exception from the arguments of a raise statement.

        Returns an FSException object whose w_value is an instance of w_type.
        """
        w_is_type = op.simple_call(const(isinstance), w_arg1, const(type)).eval(self)
        if self.guessbool(w_is_type):
            # this is for all cases of the form (Class, something)
            if self.guessbool(op.is_(w_arg2, w_None).eval(self)):
                # raise Type: we assume we have to instantiate Type
                w_value = op.simple_call(w_arg1).eval(self)
            else:
                w_valuetype = op.type(w_arg2).eval(self)
                if self.guessbool(op.issubtype(w_valuetype, w_arg1).eval(self)):
                    # raise Type, Instance: let etype be the exact type of value
                    w_value = w_arg2
                else:
                    # raise Type, X: assume X is the constructor argument
                    w_value = op.simple_call(w_arg1, w_arg2).eval(self)
        else:
            # the only case left here is (inst, None), from a 'raise inst'.
            if not self.guessbool(op.is_(w_arg2, const(None)).eval(self)):
                exc = TypeError("instance exception may not have a "
                                "separate value")
                raise Raise(const(exc))
            w_value = w_arg1
        w_type = op.type(w_value).eval(self)
        return FSException(w_type, w_value)
Exemple #3
0
 def unpack_sequence(self, w_iterable, expected_length):
     w_len = op.len(w_iterable).eval(self)
     w_correct = op.eq(w_len, const(expected_length)).eval(self)
     if not self.guessbool(op.bool(w_correct).eval(self)):
         w_exc = self.exc_from_raise(const(ValueError), const(None))
         raise Raise(w_exc)
     return [op.getitem(w_iterable, const(i)).eval(self)
             for i in range(expected_length)]
Exemple #4
0
 def unpack_sequence(self, w_iterable, expected_length):
     w_len = op.len(w_iterable).eval(self)
     w_correct = op.eq(w_len, const(expected_length)).eval(self)
     if not self.guessbool(op.bool(w_correct).eval(self)):
         w_exc = self.exc_from_raise(const(ValueError), const(None))
         raise Raise(w_exc)
     return [op.getitem(w_iterable, const(i)).eval(self)
             for i in range(expected_length)]
Exemple #5
0
 def test_raise_prebuilt(self):
     error = ValueError('ouch')
     def g(x): return x
     def f():
         raise g(error)
     x = self.codetest(f)
     simplify_graph(x)
     self.show(x)
     ops = x.startblock.operations
     assert ops[0].opname == 'simple_call'
     assert ops[0].args == [const(g), const(error)]
Exemple #6
0
 def SETUP_WITH(self, target):
     # A simpler version than the 'real' 2.7 one:
     # directly call manager.__enter__(), don't use special lookup functions
     # which don't make sense on the RPython type system.
     w_manager = self.peekvalue()
     w_exit = op.getattr(w_manager, const("__exit__")).eval(self)
     self.settopvalue(w_exit)
     w_enter = op.getattr(w_manager, const('__enter__')).eval(self)
     w_result = op.simple_call(w_enter).eval(self)
     block = WithBlock(self, target)
     self.blockstack.append(block)
     self.pushvalue(w_result)
Exemple #7
0
 def SETUP_WITH(self, target):
     # A simpler version than the 'real' 2.7 one:
     # directly call manager.__enter__(), don't use special lookup functions
     # which don't make sense on the RPython type system.
     w_manager = self.peekvalue()
     w_exit = op.getattr(w_manager, const("__exit__")).eval(self)
     self.settopvalue(w_exit)
     w_enter = op.getattr(w_manager, const('__enter__')).eval(self)
     w_result = op.simple_call(w_enter).eval(self)
     block = WithBlock(self, target)
     self.blockstack.append(block)
     self.pushvalue(w_result)
Exemple #8
0
def replace_graph_with_bootstrap(GeneratorIterator, graph):
    Entry = GeneratorIterator.Entry
    newblock = Block(graph.startblock.inputargs)
    op_entry = op.simple_call(const(Entry))
    v_entry = op_entry.result
    newblock.operations.append(op_entry)
    assert len(graph.startblock.inputargs) == len(Entry.varnames)
    for v, name in zip(graph.startblock.inputargs, Entry.varnames):
        newblock.operations.append(op.setattr(v_entry, Constant(name), v))
    op_generator = op.simple_call(const(GeneratorIterator), v_entry)
    newblock.operations.append(op_generator)
    newblock.closeblock(Link([op_generator.result], graph.returnblock))
    graph.startblock = newblock
Exemple #9
0
def replace_graph_with_bootstrap(GeneratorIterator, graph):
    Entry = GeneratorIterator.Entry
    newblock = Block(graph.startblock.inputargs)
    op_entry = op.simple_call(const(Entry))
    v_entry = op_entry.result
    newblock.operations.append(op_entry)
    assert len(graph.startblock.inputargs) == len(Entry.varnames)
    for v, name in zip(graph.startblock.inputargs, Entry.varnames):
        newblock.operations.append(op.setattr(v_entry, Constant(name), v))
    op_generator = op.simple_call(const(GeneratorIterator), v_entry)
    newblock.operations.append(op_generator)
    newblock.closeblock(Link([op_generator.result], graph.returnblock))
    graph.startblock = newblock
Exemple #10
0
 def eval(self, ctx):
     w_iter, = self.args
     if isinstance(w_iter, Constant):
         it = w_iter.value
         if isinstance(it, _unroller):
             try:
                 v, next_unroller = it.step()
             except IndexError:
                 from rpython.flowspace.flowcontext import Raise
                 raise Raise(const(StopIteration()))
             else:
                 ctx.replace_in_stack(it, next_unroller)
                 return const(v)
     return HLOperation.eval(self, ctx)
Exemple #11
0
 def eval(self, ctx):
     w_iter, = self.args
     if isinstance(w_iter, Constant):
         it = w_iter.value
         if isinstance(it, _unroller):
             try:
                 v, next_unroller = it.step()
             except IndexError:
                 from rpython.flowspace.flowcontext import Raise
                 raise Raise(const(StopIteration()))
             else:
                 ctx.replace_in_stack(it, next_unroller)
                 return const(v)
     w_item = ctx.do_op(self)
     ctx.guessexception([StopIteration, RuntimeError], force=True)
     return w_item
Exemple #12
0
 def handle(self, ctx, unroller):
     w_exc = unroller.w_exc
     if ctx.exception_match(w_exc.w_type, const(StopIteration)):
         ctx.popvalue()
         return self.handlerposition
     else:
         return ctx.unroll(unroller)
Exemple #13
0
 def constfold(self):
     args = []
     if all(w_arg.foldable() for w_arg in self.args):
         args = [w_arg.value for w_arg in self.args]
         # All arguments are constants: call the operator now
         try:
             result = self.pyfunc(*args)
         except Exception as e:
             from rpython.flowspace.flowcontext import FlowingError
             msg = "%s%r always raises %s: %s" % (
                 self.opname, tuple(args), type(e), e)
             raise FlowingError(msg)
         else:
             # don't try to constant-fold operations giving a 'long'
             # result.  The result is probably meant to be sent to
             # an intmask(), but the 'long' constant confuses the
             # annotator a lot.
             if self.can_overflow and type(result) is long:
                 pass
             # don't constant-fold getslice on lists, either
             elif self.opname == 'getslice' and type(result) is list:
                 pass
             # otherwise, fine
             else:
                 try:
                     return const(result)
                 except WrapException:
                     # type cannot sanely appear in flow graph,
                     # store operation with variable result instead
                     pass
Exemple #14
0
 def eval(self, ctx):
     w_iter, = self.args
     if isinstance(w_iter, Constant):
         it = w_iter.value
         if isinstance(it, _unroller):
             try:
                 v, next_unroller = it.step()
             except IndexError:
                 from rpython.flowspace.flowcontext import Raise
                 raise Raise(const(StopIteration()))
             else:
                 ctx.replace_in_stack(it, next_unroller)
                 return const(v)
     w_item = ctx.do_op(self)
     ctx.guessexception([StopIteration, RuntimeError], force=True)
     return w_item
Exemple #15
0
 def constfold(self):
     args = []
     if all(w_arg.foldable() for w_arg in self.args):
         args = [w_arg.value for w_arg in self.args]
         # All arguments are constants: call the operator now
         try:
             result = self.pyfunc(*args)
         except Exception as e:
             from rpython.flowspace.flowcontext import FlowingError
             msg = "%s%r always raises %s: %s" % (
                 self.opname, tuple(args), type(e), e)
             raise FlowingError(msg)
         else:
             # don't try to constant-fold operations giving a 'long'
             # result.  The result is probably meant to be sent to
             # an intmask(), but the 'long' constant confuses the
             # annotator a lot.
             if self.can_overflow and type(result) is long:
                 pass
             # don't constant-fold getslice on lists, either
             elif self.opname == 'getslice' and type(result) is list:
                 pass
             # otherwise, fine
             else:
                 try:
                     return const(result)
                 except WrapException:
                     # type cannot sanely appear in flow graph,
                     # store operation with variable result instead
                     pass
Exemple #16
0
def _insert_reads(block, varnames):
    assert len(varnames) == len(block.inputargs)
    v_entry1 = Variable('entry')
    for i, name in enumerate(varnames):
        hlop = op.getattr(v_entry1, const(name))
        hlop.result = block.inputargs[i]
        block.operations.insert(i, hlop)
    block.inputargs = [v_entry1]
Exemple #17
0
 def LOAD_DEREF(self, varindex):
     cell = self.closure[varindex]
     try:
         content = cell.cell_contents
     except ValueError:
         name = self.pycode.co_freevars[varindex]
         raise FlowingError("Undefined closure variable '%s'" % name)
     self.pushvalue(const(content))
Exemple #18
0
 def import_from(self, w_module, w_name):
     assert isinstance(w_module, Constant)
     assert isinstance(w_name, Constant)
     try:
         return op.getattr(w_module, w_name).eval(self)
     except FlowingError:
         exc = ImportError("cannot import name '%s'" % w_name.value)
         raise Raise(const(exc))
Exemple #19
0
 def nomoreblocks(self, ctx):
     w_exc = self.w_exc
     if w_exc.w_type == const(ImportError):
         msg = 'import statement always raises %s' % self
         raise ImportError(msg)
     link = Link([w_exc.w_type, w_exc.w_value], ctx.graph.exceptblock)
     ctx.recorder.crnt_block.closeblock(link)
     raise StopFlowing
Exemple #20
0
 def LOAD_DEREF(self, varindex):
     cell = self.closure[varindex]
     try:
         content = cell.cell_contents
     except ValueError:
         name = self.pycode.co_freevars[varindex]
         raise FlowingError("Undefined closure variable '%s'" % name)
     self.pushvalue(const(content))
Exemple #21
0
 def import_from(self, w_module, w_name):
     assert isinstance(w_module, Constant)
     assert isinstance(w_name, Constant)
     try:
         return op.getattr(w_module, w_name).eval(self)
     except FlowingError:
         exc = ImportError("cannot import name '%s'" % w_name.value)
         raise Raise(const(exc))
Exemple #22
0
def _insert_reads(block, varnames):
    assert len(varnames) == len(block.inputargs)
    v_entry1 = Variable('entry')
    for i, name in enumerate(varnames):
        hlop = op.getattr(v_entry1, const(name))
        hlop.result = block.inputargs[i]
        block.operations.insert(i, hlop)
    block.inputargs = [v_entry1]
Exemple #23
0
 def LIST_APPEND(self, oparg):
     w_value = self.popvalue()
     if sys.version_info < (2, 7):
         w_list = self.popvalue()
     else:
         w_list = self.peekvalue(oparg - 1)
     w_append_meth = op.getattr(w_list, const('append')).eval(self)
     op.simple_call(w_append_meth, w_value).eval(self)
Exemple #24
0
 def LIST_APPEND(self, oparg):
     w_value = self.popvalue()
     if sys.version_info < (2, 7):
         w_list = self.popvalue()
     else:
         w_list = self.peekvalue(oparg - 1)
     w_append_meth = op.getattr(w_list, const('append')).eval(self)
     op.simple_call(w_append_meth, w_value).eval(self)
Exemple #25
0
 def nomoreblocks(self, ctx):
     w_exc = self.w_exc
     if w_exc.w_type == const(ImportError):
         msg = 'ImportError is raised in RPython: %s' % (
             getattr(w_exc.w_value, 'value', '<not a constant message>'),)
         raise ImportError(msg)
     link = Link([w_exc.w_type, w_exc.w_value], ctx.graph.exceptblock)
     ctx.recorder.crnt_block.closeblock(link)
     raise StopFlowing
Exemple #26
0
 def nomoreblocks(self, ctx):
     w_exc = self.w_exc
     if w_exc.w_type == const(ImportError):
         msg = 'ImportError is raised in RPython: %s' % (getattr(
             w_exc.w_value, 'value', '<not a constant message>'), )
         raise ImportError(msg)
     link = Link([w_exc.w_type, w_exc.w_value], ctx.graph.exceptblock)
     ctx.recorder.crnt_block.closeblock(link)
     raise StopFlowing
Exemple #27
0
def transform_varargs(annotator, v_func, v_shape, *data_v):
    callspec = CallSpec.fromshape(v_shape.value, list(data_v))
    v_vararg = callspec.w_stararg
    if callspec.w_stararg:
        s_vararg = annotator.annotation(callspec.w_stararg)
        if not isinstance(s_vararg, SomeTuple):
            raise AnnotatorError(
                "Calls like f(..., *arg) require 'arg' to be a tuple")
        n_items = len(s_vararg.items)
        ops = [op.getitem(v_vararg, const(i)) for i in range(n_items)]
        new_args = callspec.arguments_w + [hlop.result for hlop in ops]
        if callspec.keywords:
            newspec = CallSpec(new_args, callspec.keywords)
            shape, data_v = newspec.flatten()
            call_op = op.call_args(v_func, const(shape), *data_v)
        else:
            call_op = op.simple_call(v_func, *new_args)
        ops.append(call_op)
        return ops
Exemple #28
0
 def find_global(self, w_globals, varname):
     try:
         value = w_globals.value[varname]
     except KeyError:
         # not in the globals, now look in the built-ins
         try:
             value = getattr(__builtin__, varname)
         except AttributeError:
             raise FlowingError("global name '%s' is not defined" % varname)
     return const(value)
Exemple #29
0
 def find_global(self, w_globals, varname):
     try:
         value = w_globals.value[varname]
     except KeyError:
         # not in the globals, now look in the built-ins
         try:
             value = getattr(__builtin__, varname)
         except AttributeError:
             raise FlowingError("global name '%s' is not defined" % varname)
     return const(value)
Exemple #30
0
def transform_varargs(annotator, v_func, v_shape, *data_v):
    callspec = CallSpec.fromshape(v_shape.value, list(data_v))
    v_vararg = callspec.w_stararg
    if callspec.w_stararg:
        s_vararg = annotator.annotation(callspec.w_stararg)
        if not isinstance(s_vararg, SomeTuple):
            raise AnnotatorError(
                "Calls like f(..., *arg) require 'arg' to be a tuple")
        n_items = len(s_vararg.items)
        ops = [op.getitem(v_vararg, const(i)) for i in range(n_items)]
        new_args = callspec.arguments_w + [hlop.result for hlop in ops]
        if callspec.keywords:
            newspec = CallSpec(new_args, callspec.keywords)
            shape, data_v = newspec.flatten()
            call_op = op.call_args(v_func, const(shape), *data_v)
        else:
            call_op = op.simple_call(v_func, *new_args)
        ops.append(call_op)
        return ops
Exemple #31
0
 def FOR_ITER(self, target):
     w_iterator = self.peekvalue()
     try:
         w_nextitem = op.next(w_iterator).eval(self)
         self.pushvalue(w_nextitem)
     except Raise as e:
         if self.exception_match(e.w_exc.w_type, const(StopIteration)):
             self.popvalue()
             return target
         else:
             raise
Exemple #32
0
 def exception_match(self, w_exc_type, w_check_class):
     """Checks if the given exception type matches 'w_check_class'."""
     if not isinstance(w_check_class, Constant):
         raise FlowingError("Non-constant except guard.")
     check_class = w_check_class.value
     if check_class in (NotImplementedError, AssertionError):
         raise FlowingError(
             "Catching %s is not valid in RPython" % check_class.__name__)
     if not isinstance(check_class, tuple):
         # the simple case
         return self.guessbool(op.issubtype(w_exc_type, w_check_class).eval(self))
     # special case for StackOverflow (see rlib/rstackovf.py)
     if check_class == rstackovf.StackOverflow:
         w_real_class = const(rstackovf._StackOverflow)
         return self.guessbool(op.issubtype(w_exc_type, w_real_class).eval(self))
     # checking a tuple of classes
     for klass in w_check_class.value:
         if self.exception_match(w_exc_type, const(klass)):
             return True
     return False
Exemple #33
0
 def FOR_ITER(self, target):
     w_iterator = self.peekvalue()
     try:
         w_nextitem = op.next(w_iterator).eval(self)
         self.pushvalue(w_nextitem)
     except Raise as e:
         if self.exception_match(e.w_exc.w_type, const(StopIteration)):
             self.popvalue()
             return target
         else:
             raise
Exemple #34
0
 def exception_match(self, w_exc_type, w_check_class):
     """Checks if the given exception type matches 'w_check_class'."""
     if not isinstance(w_check_class, Constant):
         raise FlowingError("Non-constant except guard.")
     check_class = w_check_class.value
     if check_class in (NotImplementedError, AssertionError):
         raise FlowingError(
             "Catching %s is not valid in RPython" % check_class.__name__)
     if not isinstance(check_class, tuple):
         # the simple case
         return self.guessbool(op.issubtype(w_exc_type, w_check_class).eval(self))
     # special case for StackOverflow (see rlib/rstackovf.py)
     if check_class == rstackovf.StackOverflow:
         w_real_class = const(rstackovf._StackOverflow)
         return self.guessbool(op.issubtype(w_exc_type, w_real_class).eval(self))
     # checking a tuple of classes
     for klass in w_check_class.value:
         if self.exception_match(w_exc_type, const(klass)):
             return True
     return False
Exemple #35
0
def setattr_SomeInstance(annotator, v_obj, v_attr, v_value):
    s_attr = annotator.annotation(v_attr)
    if not s_attr.is_constant() or not isinstance(s_attr.const, str):
        return
    attr = s_attr.const
    setters = _find_property_meth(annotator.annotation(v_obj), attr, 'fset')
    if setters:
        if all(setters):
            get_setter = op.getattr(v_obj, const(attr + '__setter__'))
            return [get_setter, op.simple_call(get_setter.result, v_value)]
        elif not any(setters):
            raise AnnotatorError("Attribute %r is unwritable" % attr)
Exemple #36
0
def setattr_SomeInstance(annotator, v_obj, v_attr, v_value):
    s_attr = annotator.annotation(v_attr)
    if not s_attr.is_constant() or not isinstance(s_attr.const, str):
        return
    attr = s_attr.const
    setters = _find_property_meth(annotator.annotation(v_obj), attr, 'fset')
    if setters:
        if all(setters):
            get_setter = op.getattr(v_obj, const(attr + '__setter__'))
            return [get_setter, op.simple_call(get_setter.result, v_value)]
        elif not any(setters):
            raise AnnotatorError("Attribute %r is unwritable" % attr)
def test_translate_cast():
    cdef = "typedef ssize_t Py_ssize_t;"
    cts = parse_source(cdef)

    def f():
        return cts.cast('Py_ssize_t*', 0)

    graph = build_flow(f)
    simplify_graph(graph)
    assert len(graph.startblock.operations) == 1
    op = graph.startblock.operations[0]
    assert op.args[0] == const(rffi.cast)
    assert op.args[1].value is cts.gettype('Py_ssize_t*')
def test_translate_gettype():
    cdef = "typedef ssize_t Py_ssize_t;"
    cts = parse_source(cdef)

    def f():
        return cts.gettype('Py_ssize_t*')

    graph = build_flow(f)
    simplify_graph(graph)
    # Check that the result is constant-folded
    assert graph.startblock.operations == []
    [link] = graph.startblock.exits
    assert link.target is graph.returnblock
    assert link.args[0] == const(rffi.CArrayPtr(rffi.SSIZE_T))
Exemple #39
0
    def RAISE_VARARGS(self, nbargs):
        if nbargs == 0:
            if self.last_exception is not None:
                w_exc = self.last_exception
            else:
                w_exc = const(TypeError(
                    "raise: no active exception to re-raise"))
            raise Raise(w_exc)

        if nbargs >= 3:
            self.popvalue()
        if nbargs >= 2:
            w_value = self.popvalue()
            w_type = self.popvalue()
            operror = self.exc_from_raise(w_type, w_value)
        else:
            w_type = self.popvalue()
            operror = self.exc_from_raise(w_type, w_None)
        raise Raise(operror)
Exemple #40
0
    def RAISE_VARARGS(self, nbargs):
        if nbargs == 0:
            if self.last_exception is not None:
                w_exc = self.last_exception
            else:
                w_exc = const(TypeError(
                    "raise: no active exception to re-raise"))
            raise Raise(w_exc)

        if nbargs >= 3:
            self.popvalue()
        if nbargs >= 2:
            w_value = self.popvalue()
            w_type = self.popvalue()
            operror = self.exc_from_raise(w_type, w_value)
        else:
            w_type = self.popvalue()
            operror = self.exc_from_raise(w_type, w_None)
        raise Raise(operror)
Exemple #41
0
    def record_block(self, block):
        self.setstate(block.framestate)
        next_offset = block.framestate.next_offset
        self.recorder = block.make_recorder()
        try:
            while True:
                next_offset = self.handle_bytecode(next_offset)
                self.recorder.final_state = self.getstate(next_offset)

        except RaiseImplicit as e:
            w_exc = e.w_exc
            if isinstance(w_exc.w_type, Constant):
                exc_cls = w_exc.w_type.value
            else:
                exc_cls = Exception
            msg = "implicit %s shouldn't occur" % exc_cls.__name__
            w_type = Constant(AssertionError)
            w_value = Constant(AssertionError(msg))
            link = Link([w_type, w_value], self.graph.exceptblock)
            self.recorder.crnt_block.closeblock(link)

        except Raise as e:
            w_exc = e.w_exc
            if w_exc.w_type == const(ImportError):
                msg = 'import statement always raises %s' % e
                raise ImportError(msg)
            link = Link([w_exc.w_type, w_exc.w_value], self.graph.exceptblock)
            self.recorder.crnt_block.closeblock(link)

        except StopFlowing:
            pass

        except Return as exc:
            w_result = exc.w_value
            link = Link([w_result], self.graph.returnblock)
            self.recorder.crnt_block.closeblock(link)

        except FlowingError as exc:
            if exc.ctx is None:
                exc.ctx = self
            raise

        self.recorder = None
Exemple #42
0
    def record_block(self, block):
        self.setstate(block.framestate)
        next_pos = block.framestate.next_instr
        self.recorder = block.make_recorder()
        try:
            while True:
                next_pos = self.handle_bytecode(next_pos)
                self.recorder.final_state = self.getstate(next_pos)

        except RaiseImplicit as e:
            w_exc = e.w_exc
            if isinstance(w_exc.w_type, Constant):
                exc_cls = w_exc.w_type.value
            else:
                exc_cls = Exception
            msg = "implicit %s shouldn't occur" % exc_cls.__name__
            w_type = Constant(AssertionError)
            w_value = Constant(AssertionError(msg))
            link = Link([w_type, w_value], self.graph.exceptblock)
            self.recorder.crnt_block.closeblock(link)

        except Raise as e:
            w_exc = e.w_exc
            if w_exc.w_type == const(ImportError):
                msg = 'import statement always raises %s' % e
                raise ImportError(msg)
            link = Link([w_exc.w_type, w_exc.w_value], self.graph.exceptblock)
            self.recorder.crnt_block.closeblock(link)

        except StopFlowing:
            pass

        except Return as exc:
            w_result = exc.w_value
            link = Link([w_result], self.graph.returnblock)
            self.recorder.crnt_block.closeblock(link)

        except FlowingError as exc:
            if exc.ctx is None:
                exc.ctx = self
            raise

        self.recorder = None
Exemple #43
0
 def constfold(self):
     w_obj, w_name = self.args
     # handling special things like sys
     if (w_obj in NOT_REALLY_CONST and
             w_name not in NOT_REALLY_CONST[w_obj]):
         return
     if w_obj.foldable() and w_name.foldable():
         obj, name = w_obj.value, w_name.value
         try:
             result = getattr(obj, name)
         except Exception as e:
             from rpython.flowspace.flowcontext import FlowingError
             etype = e.__class__
             msg = "getattr(%s, %s) always raises %s: %s" % (
                 obj, name, etype, e)
             raise FlowingError(msg)
         try:
             return const(result)
         except WrapException:
             pass
Exemple #44
0
def test_translate_enum():
    cdef = """
    typedef enum {
        mp_ass_subscript = 3,
        mp_length = 4,
        mp_subscript = 5,
    } Slot;
    """
    cts = parse_source(cdef)

    def f():
        return cts.gettype('Slot').mp_length

    graph = build_flow(f)
    simplify_graph(graph)
    # Check that the result is constant-folded
    assert graph.startblock.operations == []
    [link] = graph.startblock.exits
    assert link.target is graph.returnblock
    assert link.args[0] == const(4)
Exemple #45
0
 def constfold(self):
     from rpython.flowspace.flowcontext import FlowingError
     if len(self.args) == 3:
         raise FlowingError(
             "getattr() with three arguments not supported: %s" % (self,))
     w_obj, w_name = self.args
     # handling special things like sys
     if (w_obj in NOT_REALLY_CONST and
             w_name not in NOT_REALLY_CONST[w_obj]):
         return
     if w_obj.foldable() and w_name.foldable():
         obj, name = w_obj.value, w_name.value
         try:
             result = getattr(obj, name)
         except Exception as e:
             etype = e.__class__
             msg = "getattr(%s, %s) always raises %s: %s" % (
                 obj, name, etype, e)
             raise FlowingError(msg)
         try:
             return const(result)
         except WrapException:
             pass
Exemple #46
0
 def appcall(self, func, *args_w):
     """Call an app-level RPython function directly"""
     w_func = const(func)
     return self.do_op(op.simple_call(w_func, *args_w))
Exemple #47
0
def tweak_generator_body_graph(Entry, graph):
    # First, always run simplify_graph in order to reduce the number of
    # variables passed around
    simplify_graph(graph)
    insert_empty_startblock(graph)
    _insert_reads(graph.startblock, Entry.varnames)
    Entry.block = graph.startblock
    #
    mappings = [Entry]
    #
    stopblock = Block([])
    op0 = op.simple_call(const(StopIteration))
    op1 = op.type(op0.result)
    stopblock.operations = [op0, op1]
    stopblock.closeblock(Link([op1.result, op0.result], graph.exceptblock))
    #
    for block in list(graph.iterblocks()):
        for exit in block.exits:
            if exit.target is graph.returnblock:
                exit.args = []
                exit.target = stopblock
        assert block is not stopblock
        for index in range(len(block.operations) - 1, -1, -1):
            hlop = block.operations[index]
            if hlop.opname == 'yield_':
                [v_yielded_value] = hlop.args
                del block.operations[index]
                newlink = split_block(block, index)
                newblock = newlink.target

                #
                class Resume(AbstractPosition):
                    _immutable_ = True
                    block = newblock

                Resume.__name__ = 'Resume%d' % len(mappings)
                mappings.append(Resume)
                varnames = get_variable_names(newlink.args)
                #
                _insert_reads(newblock, varnames)
                #
                op_resume = op.simple_call(const(Resume))
                block.operations.append(op_resume)
                v_resume = op_resume.result
                for i, name in enumerate(varnames):
                    block.operations.append(
                        op.setattr(v_resume, const(name), newlink.args[i]))
                op_pair = op.newtuple(v_resume, v_yielded_value)
                block.operations.append(op_pair)
                newlink.args = [op_pair.result]
                newlink.target = graph.returnblock
    #
    regular_entry_block = Block([Variable('entry')])
    block = regular_entry_block
    for Resume in mappings:
        op_check = op.isinstance(block.inputargs[0], const(Resume))
        block.operations.append(op_check)
        block.exitswitch = op_check.result
        link1 = Link([block.inputargs[0]], Resume.block)
        link1.exitcase = True
        nextblock = Block([Variable('entry')])
        link2 = Link([block.inputargs[0]], nextblock)
        link2.exitcase = False
        block.closeblock(link1, link2)
        block = nextblock
    block.closeblock(
        Link([
            Constant(AssertionError),
            Constant(AssertionError("bad generator class"))
        ], graph.exceptblock))
    graph.startblock = regular_entry_block
    graph.signature = Signature(['entry'])
    graph.defaults = ()
    checkgraph(graph)
    eliminate_empty_blocks(graph)
Exemple #48
0
def contains_SomeInstance(annotator, v_ins, v_idx):
    get_contains = op.getattr(v_ins, const('__contains__'))
    return [get_contains, op.simple_call(get_contains.result, v_idx)]
Exemple #49
0
def setitem_SomeInstance(annotator, v_ins, v_idx, v_value):
    get_setitem = op.getattr(v_ins, const('__setitem__'))
    return [get_setitem, op.simple_call(get_setitem.result, v_idx, v_value)]
Exemple #50
0
import collections
import types
import __builtin__

from rpython.tool.error import source_lines
from rpython.rlib import rstackovf
from rpython.flowspace.argument import CallSpec
from rpython.flowspace.model import (Constant, Variable, Block, Link,
    c_last_exception, const, FSException)
from rpython.flowspace.framestate import (FrameState, recursively_unflatten,
    recursively_flatten)
from rpython.flowspace.specialcase import (rpython_print_item,
    rpython_print_newline)
from rpython.flowspace.operation import op

w_None = const(None)

class FlowingError(Exception):
    """ Signals invalid RPython in the function being analysed"""
    ctx = None

    def __str__(self):
        msg = ["\n"]
        msg += map(str, self.args)
        msg += [""]
        msg += source_lines(self.ctx.graph, None, offset=self.ctx.last_instr)
        return "\n".join(msg)

class StopFlowing(Exception):
    pass
Exemple #51
0
 def sc_gettype(ctx, v_decl):
     if not isinstance(v_decl, Constant):
         raise FlowingError(
             "The argument of cts.gettype() must be a constant.")
     return const(self.gettype(v_decl.value))
Exemple #52
0
 def state_unpack_variables(self):
     return [const(self.jump_to)]
Exemple #53
0
 def getconstant_w(self, index):
     return const(self.pycode.consts[index])
Exemple #54
0
 def not_(self, w_obj):
     w_bool = op.bool(w_obj).eval(self)
     return const(not self.guessbool(w_bool))
Exemple #55
0
 def cmp_exc_match(self, w_1, w_2):
     return const(self.exception_match(w_1, w_2))
Exemple #56
0
 def import_name(self, name, glob=None, loc=None, frm=None, level=-1):
     try:
         mod = __import__(name, glob, loc, frm, level)
     except ImportError as e:
         raise Raise(const(e))
     return const(mod)