Ejemplo n.º 1
0
def rewrite_optional_args(func, env):
    """
    Rewrite function application with missing arguments, which are supplied
    from defaults.

        def f(x, y=4):
            ...

        call(f, [x]) -> call(f, [x, const(4)])
    """
    from flypy import typeof

    def f(context, py_func, f_env, op):
        f, args = op.args

        # Add any potentially remaining values
        remaining = get_remaining_args(py_func, (None,) * len(args))
        consts = [allocate_const(func, env, op, value, typeof(value))
                      for value in remaining]
        op.set_args([f, args + consts])

    jitcallmap(f, func, env)
Ejemplo n.º 2
0
def rewrite_varargs(func, env):
    """
    Rewrite function application with arguments that go in the varargs:

        def f(x, *args):
            ...

        call(f, [x, y, z]) -> call(f, [x, (y, z)])
    """
    b = Builder(func)
    caller = Caller(b, env['flypy.typing.context'], env)
    caller = Caller(b, env['flypy.typing.context'], env)
    call_flags = env['flypy.state.call_flags']

    def f(context, py_func, f_env, op):
        f, args = op.args
        flags = call_flags.get(op, {})

        if flags.get('varargs'):
            return

        # Retrieve any remaining arguments meant for *args
        flattened = flatargs(py_func, args, {})
        if flattened.have_varargs:
            b.position_before(op)
            #print(py_func, flattened.varargs)

            # -- Build the tuple -- #
            result = caller.apply_constructor(EmptyTuple)
            for item in flattened.varargs:
                result = caller.apply_constructor(StaticTuple,
                                                  args=[item, result])

            # -- Patch callsite -- #
            args = list(flattened.positional) + [result]
            op.set_args([f, args])

    jitcallmap(f, func, env)
Ejemplo n.º 3
0
def rewrite_varargs(func, env):
    """
    Rewrite function application with arguments that go in the varargs:

        def f(x, *args):
            ...

        call(f, [x, y, z]) -> call(f, [x, (y, z)])
    """
    b = Builder(func)
    caller = Caller(b, env['flypy.typing.context'], env)
    caller = Caller(b, env['flypy.typing.context'], env)
    call_flags = env['flypy.state.call_flags']

    def f(context, py_func, f_env, op):
        f, args = op.args
        flags = call_flags.get(op, {})

        if flags.get('varargs'):
            return

        # Retrieve any remaining arguments meant for *args
        flattened = flatargs(py_func, args, {})
        if flattened.have_varargs:
            b.position_before(op)
            #print(py_func, flattened.varargs)

            # -- Build the tuple -- #
            result = caller.apply_constructor(EmptyTuple)
            for item in flattened.varargs:
                result = caller.apply_constructor(StaticTuple,
                                                  args=[item, result])

            # -- Patch callsite -- #
            args = list(flattened.positional) + [result]
            op.set_args([f, args])

    jitcallmap(f, func, env)
Ejemplo n.º 4
0
def rewrite_optional_args(func, env):
    """
    Rewrite function application with missing arguments, which are supplied
    from defaults.

        def f(x, y=4):
            ...

        call(f, [x]) -> call(f, [x, const(4)])
    """
    from flypy import typeof

    def f(context, py_func, f_env, op):
        f, args = op.args

        # Add any potentially remaining values
        remaining = get_remaining_args(py_func, (None, ) * len(args))
        consts = [
            allocate_const(func, env, op, value, typeof(value))
            for value in remaining
        ]
        op.set_args([f, args + consts])

    jitcallmap(f, func, env)
Ejemplo n.º 5
0
def rewrite_unpacking(func, env):
    """
    Rewrite argument unpacking:

        f(x, *args)
              ^^^^^

        temp = tuple(args)
        f(x, temp[0], temp[1])
    """
    from flypy.pipeline import phase

    b = Builder(func)
    caller = Caller(b, env['flypy.typing.context'], env)
    call_flags = env['flypy.state.call_flags']

    def f(context, py_func, f_env, op):
        f, args = op.args
        flags = call_flags.get(op, {})

        if not flags.get('varargs'):
            return

        # Unpack positional and varargs argument
        # For f(x, *args): positional = [x], varargs = args
        positional, varargs = args[:-1], args[-1]
        varargs_type = context[varargs]

        # Missing number of positional arguments (int)
        missing = compute_missing(py_func, positional)

        # Types in the tuple, may be heterogeneous
        eltypes = extract_tuple_eltypes(varargs_type, missing)

        # Now supply the missing positional arguments
        b.position_before(op)
        for i, argty in zip(range(missing), eltypes):
            idx = OConst(i)
            context[idx] = types.int32

            #hd = b.getfield(ptypes.Opaque, varargs, 'hd')
            #tl = b.getfield(ptypes.Opaque, varargs, 'tl')

            positional_arg = caller.call(phase.typing,
                                         primitives.getitem,
                                         [varargs, idx])
            positional.append(positional_arg)

        # TODO: For GenericTuple unpacking, assure that
        #       len(remaining_tuple) == missing

        if len(eltypes) > missing:
            # In case we have more element types than positional parameters,
            # we must have a function that takes varargs, e.g.
            #
            #   def f(x, y, *args):
            #       ...
            #
            # That we call as follows (for example):
            #
            #       f(x, *args)
            idx = OConst(missing)
            context[idx] = types.int32

            argstup = caller.call(phase.typing,
                                  slicetuple,
                                  [varargs, idx])
            positional.append(argstup)

        # Update with new positional arguments
        op.set_args([f, positional])

    jitcallmap(f, func, env)
Ejemplo n.º 6
0
def rewrite_unpacking(func, env):
    """
    Rewrite argument unpacking:

        f(x, *args)
              ^^^^^

        temp = tuple(args)
        f(x, temp[0], temp[1])
    """
    from flypy.pipeline import phase

    b = Builder(func)
    caller = Caller(b, env['flypy.typing.context'], env)
    call_flags = env['flypy.state.call_flags']

    def f(context, py_func, f_env, op):
        f, args = op.args
        flags = call_flags.get(op, {})

        if not flags.get('varargs'):
            return

        # Unpack positional and varargs argument
        # For f(x, *args): positional = [x], varargs = args
        positional, varargs = args[:-1], args[-1]
        varargs_type = context[varargs]

        # Missing number of positional arguments (int)
        missing = compute_missing(py_func, positional)

        # Types in the tuple, may be heterogeneous
        eltypes = extract_tuple_eltypes(varargs_type, missing)

        # Now supply the missing positional arguments
        b.position_before(op)
        for i, argty in zip(range(missing), eltypes):
            idx = OConst(i)
            context[idx] = types.int32

            #hd = b.getfield(ptypes.Opaque, varargs, 'hd')
            #tl = b.getfield(ptypes.Opaque, varargs, 'tl')

            positional_arg = caller.call(phase.typing, primitives.getitem,
                                         [varargs, idx])
            positional.append(positional_arg)

        # TODO: For GenericTuple unpacking, assure that
        #       len(remaining_tuple) == missing

        if len(eltypes) > missing:
            # In case we have more element types than positional parameters,
            # we must have a function that takes varargs, e.g.
            #
            #   def f(x, y, *args):
            #       ...
            #
            # That we call as follows (for example):
            #
            #       f(x, *args)
            idx = OConst(missing)
            context[idx] = types.int32

            argstup = caller.call(phase.typing, slicetuple, [varargs, idx])
            positional.append(argstup)

        # Update with new positional arguments
        op.set_args([f, positional])

    jitcallmap(f, func, env)