Example #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)
Example #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)
Example #3
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)
Example #4
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)
Example #5
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
Example #6
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
Example #7
0
    def WITH_CLEANUP(self, oparg):
        # Note: RPython context managers receive None in lieu of tracebacks
        # and cannot suppress the exception.
        unroller = self.popvalue()
        w_exitfunc = self.popvalue()
        self.pushvalue(unroller)

        if isinstance(unroller, Raise):
            w_exc = unroller.w_exc
            # The annotator won't allow to merge exception types with None.
            # Replace it with the exception value...
            op.simple_call(w_exitfunc, w_exc.w_value, w_exc.w_value, w_None
                           ).eval(self)
        else:
            op.simple_call(w_exitfunc, w_None, w_None, w_None).eval(self)
Example #8
0
def rtypedelegate(callable, hop, revealargs=[0], revealresult=False):
    bk = hop.rtyper.annotator.bookkeeper
    c_meth = Constant(callable)
    s_meth = bk.immutablevalue(callable)
    hop2 = hop.copy()
    for index in revealargs:
        r_controlled = hop2.args_r[index]
        if not isinstance(r_controlled, ControlledInstanceRepr):
            raise TyperError("args_r[%d] = %r, expected ControlledInstanceRepr"
                             % (index, r_controlled))
        s_new, r_new = r_controlled.s_real_obj, r_controlled.r_real_obj
        hop2.args_s[index], hop2.args_r[index] = s_new, r_new
        v = hop2.args_v[index]
        if isinstance(v, Constant):
            real_value = r_controlled.controller.convert(v.value)
            hop2.args_v[index] = Constant(real_value)
    if revealresult:
        r_controlled = hop2.r_result
        if not isinstance(r_controlled, ControlledInstanceRepr):
            raise TyperError("r_result = %r, expected ControlledInstanceRepr"
                             % (r_controlled,))
        s_new, r_new = r_controlled.s_real_obj, r_controlled.r_real_obj
        hop2.s_result, hop2.r_result = s_new, r_new
    hop2.v_s_insertfirstarg(c_meth, s_meth)
    spaceop = op.simple_call(*hop2.args_v)
    spaceop.result = hop2.spaceop.result
    hop2.spaceop = spaceop
    return hop2.dispatch()
Example #9
0
    def WITH_CLEANUP(self, oparg):
        # Note: RPython context managers receive None in lieu of tracebacks
        # and cannot suppress the exception.
        # This opcode changed a lot between CPython versions
        if sys.version_info >= (2, 6):
            unroller = self.popvalue()
            w_exitfunc = self.popvalue()
            self.pushvalue(unroller)
        else:
            w_exitfunc = self.popvalue()
            unroller = self.peekvalue(0)

        if isinstance(unroller, Raise):
            w_exc = unroller.w_exc
            # The annotator won't allow to merge exception types with None.
            # Replace it with the exception value...
            op.simple_call(w_exitfunc, w_exc.w_value, w_exc.w_value, w_None
                           ).eval(self)
        else:
            op.simple_call(w_exitfunc, w_None, w_None, w_None).eval(self)
Example #10
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)
Example #11
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)
Example #12
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)
Example #13
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)
Example #14
0
 def _emulate_call(self, hop, meth_name):
     vinst, = hop.inputargs(self)
     clsdef = hop.args_s[0].classdef
     s_unbound_attr = clsdef.find_attribute(meth_name).getvalue()
     s_attr = clsdef.lookup_filter(s_unbound_attr, meth_name,
                                   hop.args_s[0].flags)
     # does that even happen?
     assert not s_attr.is_constant()
     if '__iter__' in self.allinstancefields:
         raise Exception("__iter__ on instance disallowed")
     r_method = self.rtyper.getrepr(s_attr)
     r_method.get_method_from_instance(self, vinst, hop.llops)
     hop2 = hop.copy()
     hop2.spaceop = op.simple_call(hop.spaceop.args[0])
     hop2.spaceop.result = hop.spaceop.result
     hop2.args_r = [r_method]
     hop2.args_s = [s_attr]
     return hop2.dispatch()
Example #15
0
 def _emulate_call(self, hop, meth_name):
     vinst = hop.args_v[0]
     clsdef = hop.args_s[0].classdef
     s_unbound_attr = clsdef.find_attribute(meth_name).getvalue()
     s_attr = clsdef.lookup_filter(s_unbound_attr, meth_name,
                                   hop.args_s[0].flags)
     # does that even happen?
     assert not s_attr.is_constant()
     if '__iter__' in self.allinstancefields:
         raise Exception("__iter__ on instance disallowed")
     r_method = self.rtyper.getrepr(s_attr)
     r_method.get_method_from_instance(self, vinst, hop.llops)
     hop2 = hop.copy()
     hop2.spaceop = op.simple_call(*hop.spaceop.args)
     hop2.spaceop.result = hop.spaceop.result
     hop2.args_r[0] = r_method
     hop2.args_s[0] = s_attr
     return hop2.dispatch()
Example #16
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
Example #17
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
Example #18
0
 def call_function(self, oparg, w_star=None, w_starstar=None):
     if w_starstar is not None:
         raise FlowingError("Dict-unpacking is not RPython")
     n_arguments = oparg & 0xff
     n_keywords = (oparg >> 8) & 0xff
     keywords = {}
     for _ in range(n_keywords):
         w_value = self.popvalue()
         w_key = self.popvalue()
         key = w_key.value
         keywords[key] = w_value
     arguments = self.popvalues(n_arguments)
     args = CallSpec(arguments, keywords, w_star)
     w_function = self.popvalue()
     if args.keywords or isinstance(args.w_stararg, Variable):
         shape, args_w = args.flatten()
         hlop = op.call_args(w_function, Constant(shape), *args_w)
     else:
         hlop = op.simple_call(w_function, *args.as_list())
     self.pushvalue(hlop.eval(self))
Example #19
0
 def call_function(self, oparg, w_star=None, w_starstar=None):
     if w_starstar is not None:
         raise FlowingError("Dict-unpacking is not RPython")
     n_arguments = oparg & 0xff
     n_keywords = (oparg >> 8) & 0xff
     keywords = {}
     for _ in range(n_keywords):
         w_value = self.popvalue()
         w_key = self.popvalue()
         key = w_key.value
         keywords[key] = w_value
     arguments = self.popvalues(n_arguments)
     args = CallSpec(arguments, keywords, w_star)
     w_function = self.popvalue()
     if args.keywords or isinstance(args.w_stararg, Variable):
         shape, args_w = args.flatten()
         hlop = op.call_args(w_function, Constant(shape), *args_w)
     else:
         hlop = op.simple_call(w_function, *args.as_list())
     self.pushvalue(hlop.eval(self))
Example #20
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)]
Example #21
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)]
Example #22
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(None, 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(None, 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.simple_call(
            const(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)
Example #23
0
def setslice_SomeInstance(annotator, v_obj, v_start, v_stop, v_iterable):
    get_setslice = op.getattr(v_obj, const('__setslice__'))
    return [
        get_setslice,
        op.simple_call(get_setslice.result, v_start, v_stop, v_iterable)
    ]
Example #24
0
def getslice_SomeInstance(annotator, v_obj, v_start, v_stop):
    get_getslice = op.getattr(v_obj, const('__getslice__'))
    return [get_getslice, op.simple_call(get_getslice.result, v_start, v_stop)]
Example #25
0
def next_SomeInstance(annotator, v_arg):
    get_next = op.getattr(v_arg, const('next'))
    return [get_next, op.simple_call(get_next.result)]
Example #26
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)]
Example #27
0
def len_SomeInstance(annotator, v_arg):
    get_len = op.getattr(v_arg, const('__len__'))
    return [get_len, op.simple_call(get_len.result)]
Example #28
0
def iter_SomeInstance(annotator, v_arg):
    get_iter = op.getattr(v_arg, const('__iter__'))
    return [get_iter, op.simple_call(get_iter.result)]
Example #29
0
def len_SomeInstance(annotator, v_arg):
    get_len = op.getattr(v_arg, const('__len__'))
    return [get_len, op.simple_call(get_len.result)]
Example #30
0
def next_SomeInstance(annotator, v_arg):
    get_next = op.getattr(v_arg, const('next'))
    return [get_next, op.simple_call(get_next.result)]
Example #31
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))
Example #32
0
def getslice_SomeInstance(annotator, v_obj, v_start, v_stop):
    get_getslice = op.getattr(v_obj, const('__getslice__'))
    return [get_getslice, op.simple_call(get_getslice.result, v_start, v_stop)]
Example #33
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)
Example #34
0
def iter_SomeInstance(annotator, v_arg):
    get_iter = op.getattr(v_arg, const('__iter__'))
    return [get_iter, op.simple_call(get_iter.result)]
Example #35
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))
Example #36
0
def setslice_SomeInstance(annotator, v_obj, v_start, v_stop, v_iterable):
    get_setslice = op.getattr(v_obj, const('__setslice__'))
    return [get_setslice,
            op.simple_call(get_setslice.result, v_start, v_stop, v_iterable)]