Beispiel #1
0
Datei: cont.py Projekt: 8l/pycket
def make_label(func, enter=False):
    from pycket.AST import AST

    func = jit.unroll_safe(func)
    func_argnames, varargs, varkw, defaults = inspect.getargspec(func)
    assert not varkw and not defaults
    if varargs: # grrr, bad
        class Args(Cont):
            _immutable_fields_ = ["args"]
            def __init__(self, *args):
                Cont.__init__(self, args[-2], args[-1])
                self.args = args[:-2]

            def _get_args(self):
                return self.args

            def tostring(self):
                return "%s%s" % (self.__class__.__name__, len(self._get_args()))

    else:
        assert func_argnames[-2] == "env", "next to last argument to %s must be named 'env', not %r" % (func.func_name, func_argnames[-2])

        Args = _make_args_class(Cont, func_argnames[:-2])
        def __init__(self, *args):
            env = args[-2]
            cont = args[-1]
            Cont.__init__(self, env, cont)
            args = args[:-2]
            self._init_args(*args)
        Args.__init__ = __init__

    # The @label decorator will produce a new Label per each use, as an @label can be
    # used to encode a loop (as they act in a manner similar to an assembly label).
    if enter:
        clsname = "LoopLabel"
    else:
        clsname = "Label"
    strrepr = "%s(%s:%s:%s)" % (clsname, func.func_name, func.__module__,
                                func.__code__.co_firstlineno)
    class Label(AST):
        is_label = True
        should_enter = enter
        app_like     = False
        def interpret(self, env, cont):
            assert type(cont) is Args
            args = cont._get_args()
            args += (cont.env, cont.prev)
            return func(*args)
        def tostring(self):
            return strrepr
    Label.__name__ = clsname

    the_label = Label()

    def make(*args):
        env = args[-2]
        return the_label, env, Args(*args)

    return make
Beispiel #2
0
def make_label(func, enter=False):
    import pycket.values
    from pycket.AST import AST

    func = jit.unroll_safe(func)
    func_argnames, varargs, varkw, defaults = inspect.getargspec(func)
    assert not varkw and not defaults
    if varargs:  # grrr, bad

        class Args(Cont):
            _attrs_ = _immutable_fields_ = ["args"]

            def __init__(self, *args):
                Cont.__init__(self, args[-2], args[-1])
                self.args = args[:-2]

            def _get_args(self):
                return self.args

            def tostring(self):
                return "%s%s" % (self.__class__.__name__, len(
                    self._get_args()))

    else:
        assert func_argnames[
            -2] == "env", "next to last argument to %s must be named 'env', not %r" % (
                func.func_name, func_argnames[-2])

        Args = _make_args_class(Cont, func_argnames[:-2])

        def __init__(self, *args):
            env = args[-2]
            cont = args[-1]
            Cont.__init__(self, env, cont)
            args = args[:-2]
            self._init_args(*args)

        Args.__init__ = __init__

    # The @label decorator will produce a new Label per each use, as an @label can be
    # used to encode a loop (as they act in a manner similar to an assembly label).
    if enter:
        clsname = "LoopLabel"
    else:
        clsname = "Label"
    strrepr = "%s(%s:%s:%s)" % (clsname, func.func_name, func.__module__,
                                func.__code__.co_firstlineno)

    class Label(AST):
        should_enter = enter

        def interpret(self, env, cont):
            assert type(cont) is Args
            args = cont._get_args()
            args += (cont.env, cont.prev)
            return func(*args)

        def tostring(self):
            return strrepr

    Label.__name__ = clsname

    the_label = Label()

    def make(*args):
        env = args[-2]
        return the_label, env, Args(*args)

    return make
Beispiel #3
0
                break
            if has_key:
                w_compare_with = space.call_function(w_key, w_item)
            else:
                w_compare_with = w_item
            if not has_item or \
                    space.is_true(compare(w_compare_with, w_max_val)):
                has_item = True
                w_max_item = w_item
                w_max_val = w_compare_with
        if w_max_item is None:
            msg = "arg is an empty sequence"
            raise OperationError(space.w_ValueError, space.wrap(msg))
        return w_max_item
    if unroll:
        min_max_impl = jit.unroll_safe(min_max_impl)
    return min_max_impl

min_max_unroll = make_min_max(True)
min_max_normal = make_min_max(False)

@specialize.arg(2)
def min_max(space, args, implementation_of):
    if not jit.we_are_jitted() or len(args.arguments_w) != 1 and \
            jit.loop_unrolling_heuristic(args.arguments_w, len(args.arguments_w)):
        return min_max_unroll(space, args, implementation_of)
    else:
        return min_max_normal(space, args, implementation_of)
min_max._always_inline = True

def max(space, __args__):
Beispiel #4
0
def make_min_max(unroll):
    @specialize.arg(2)
    def min_max_impl(space, args, implementation_of):
        if implementation_of == "max":
            compare = space.gt
            jitdriver = max_jitdriver
        else:
            compare = space.lt
            jitdriver = min_jitdriver
        any_kwds = bool(args.keywords)
        args_w = args.arguments_w
        if len(args_w) > 1:
            if unroll and len(args_w) == 2 and not any_kwds:
                # a fast path for the common case, useful for interpreted
                # mode and to reduce the length of the jit trace
                w0, w1 = args_w
                if space.is_true(compare(w1, w0)):
                    return w1
                else:
                    return w0
            w_sequence = space.newtuple(args_w)
        elif len(args_w):
            w_sequence = args_w[0]
        else:
            raise oefmt(space.w_TypeError,
                        "%s() expects at least one argument",
                        implementation_of)
        w_key = None
        if any_kwds:
            kwds = args.keywords
            if kwds[0] == "key" and len(kwds) == 1:
                w_key = args.keywords_w[0]
            else:
                raise oefmt(space.w_TypeError,
                            "%s() got unexpected keyword argument",
                            implementation_of)

        w_iter = space.iter(w_sequence)
        w_type = space.type(w_iter)
        has_key = w_key is not None
        has_item = False
        w_max_item = None
        w_max_val = None
        while True:
            if not unroll:
                jitdriver.jit_merge_point(has_key=has_key,
                                          has_item=has_item,
                                          w_type=w_type)
            try:
                w_item = space.next(w_iter)
            except OperationError as e:
                if not e.match(space, space.w_StopIteration):
                    raise
                break
            if has_key:
                w_compare_with = space.call_function(w_key, w_item)
            else:
                w_compare_with = w_item
            if not has_item or \
                    space.is_true(compare(w_compare_with, w_max_val)):
                has_item = True
                w_max_item = w_item
                w_max_val = w_compare_with
        if w_max_item is None:
            raise oefmt(space.w_ValueError, "arg is an empty sequence")
        return w_max_item

    if unroll:
        min_max_impl = jit.unroll_safe(min_max_impl)
    return min_max_impl