def xstack_effect(opcode, opc, oparg=None, jump=None):
    """Compute the stack effect of opcode with argument oparg, using
    oppush and oppop tables in opc.

    If the code has a jump target and jump is True, stack_effect()
    will return the stack effect of jumping. If jump is False, it will
    return the stack effect of not jumping. And if jump is None
    (default), it will return the maximal stack effect of both cases.
    """
    pop, push = opc.oppop[opcode], opc.oppush[opcode]
    opname = opc.opname[opcode]
    if opname in ('BUILD_MAP',):
        if opc.version >= 3.5:
            return 1 - 2 * oparg
    elif opname in ('UNPACK_SEQUENCE', 'UNPACK_EX') and opc.version >= 3.0:
        return push + oparg
    elif opname in 'BUILD_SLICE' and opc.version <= 2.7:
        if oparg == 3:
            return -2
        else:
            return -1
        pass
    elif opname == 'MAKE_FUNCTION':
        if opc.version >= 3.5:
            if 0 <= oparg <= 10:
                if opc.version == 3.5:
                    return [-1, -2, -3, -3, -2, -3, -3, -4, -2, -3, -3, -4][
                        oparg]
                elif opc.version >= 3.6:
                    return [-1, -2, -2, -3, -2, -3, -3, -4, -2, -3, -3, -4][
                        oparg]
            else:
                return None
    elif opname == 'CALL_FUNCTION_EX':
        if opc.version >= 3.5:
            if 0 <= oparg <= 10:
                return [-1, -2, -1][oparg]
            else:
                return None
    if push >= 0 and pop >= 0:
        return push - pop
    elif pop < 0:
        if opcode in opc.VARGS_OPS:
            return push - oparg + (pop + 1)
        elif opcode in opc.NARGS_OPS:
            return -oparg + pop + push
    return -100
