コード例 #1
0
def update_variable_domains(variable_domains, node_list):
    '''Updates variable_domains by inserting mappings from a variable name to the to the number of
    elements in their data domain.

    Program variables are created in assignments of the form
    "{varName} = Var({size})" or "{varName} = Param({size})".

    '''
    for ch in node_list:
        if isinstance(ch, ast.Assign) and len(ch.targets) == 1:
            name = astunparse.unparse(ch.targets[0]).rstrip()
            rhs = ch.value

            if isinstance(rhs, ast.Call):
                decl_name = rhs.func.id
                args = rhs.args
            elif isinstance(rhs, ast.Subscript) and isinstance(rhs.value, ast.Call):
                decl_name = rhs.value.func.id
                args = rhs.value.args
            else:
                continue

            if decl_name not in ["Param", "Var", "Input", "Output"]:
                continue
            
            if len(args) > 1:
                error.error('More than one size parameter in variable declaration of "%s".' % (name), ch)
            size = args[0]

            if isinstance(size, ast.Num):
                if name in variable_domains and variable_domains[name] != size.n:
                    error.fatal_error("Trying to reset the domain of variable '%s' to '%i' (old value '%i')." % (name, size.n, variable_domains[name]), size) 
                variable_domains[name] = size.n
            else:
                error.fatal_error("Trying to declare variable '%s', but size parameters '%s' is not understood." % (name, astunparse.unparse(size).rstrip()), size)
コード例 #2
0
ファイル: unroller.py プロジェクト: ml-lab/TerpreT
def update_variable_domains(variable_domains, node_list):
    '''Updates variable_domains by inserting mappings from a variable name to the to the number of
    elements in their data domain.

    Program variables are created in assignments of the form
    "{varName} = Var({size})" or "{varName} = Param({size})".

    '''
    for ch in node_list:
        if isinstance(ch, ast.Assign) and len(ch.targets) == 1:
            name = astunparse.unparse(ch.targets[0]).rstrip()
            rhs = ch.value

            if isinstance(rhs, ast.Call):
                decl_name = rhs.func.id
                args = rhs.args
            elif isinstance(rhs, ast.Subscript) and isinstance(rhs.value, ast.Call):
                decl_name = rhs.value.func.id
                args = rhs.value.args
            else:
                continue

            if decl_name not in ["Param", "Var", "Input", "Output"]:
                continue
            
            if len(args) > 1:
                error.error('More than one size parameter in variable declaration of "%s".' % (name), ch)
            size = args[0]

            if isinstance(size, ast.Num):
                if name in variable_domains and variable_domains[name] != size.n:
                    error.fatal_error("Trying to reset the domain of variable '%s' to '%i' (old value '%i')." % (name, size.n, variable_domains[name]), size) 
                variable_domains[name] = size.n
            else:
                error.fatal_error("Trying to declare variable '%s', but size parameters '%s' is not understood." % (name, astunparse.unparse(size).rstrip()), size)
コード例 #3
0
        def visit_With(self, node):
            context_expr = self.visit(node.context_expr)

            result = if_node = ast.copy_location(ast.If(), node)
            variable_domain = get_variable_domain(context_expr)

            for i_value in range(0, variable_domain):
                # Create the test (context_expr == i_value).
                eq_node = ast.copy_location(ast.Eq(), node)
                value_node = ast.copy_location(ast.Num(n=i_value), node)
                if_node.test = ast.copy_location(ast.Compare(context_expr, [eq_node], [value_node]), node)

                # Substitute the current value of the context
                # expression into the body of the with. If the with
                # binds a name, substitute uses of that
                # name. Otherwise, substitute uses of the context
                # expression.
                if node.optional_vars is not None:
                    check_type(node.optional_vars, ast.Name)
                    replacements = {node.optional_vars.id : i_value}
                    if_node.body = eval_const_expressions(subs(node, **replacements)).body

                else:
                    if isinstance(context_expr, ast.Name):
                        replacements = {context_expr.id : i_value}
                        if_node.body = eval_const_expressions(subs(node, **replacements)).body

                    elif isinstance(context_expr, ast.Subscript):
                        replacements = {subscript_to_tuple(context_expr) : ast.copy_location(ast.Num(n=i_value), node)}
                        if_node.body = eval_const_expressions(sub_subscript(node, replacements)).body

                    else:
                        error.fatal_error('Unexpected expression in with.', context_expr)

                update_variable_domains(variable_domains, if_node.body)
                        
                # Recursively process withs inside the body. This must
                # be performed separately for each body, because withs
                # inside the body may depend on the current value of
                # the context expression.
                self.generic_visit(if_node)

                # If this is not the last iteration of the loop,
                # generate a new if node and add it to the else block
                # of the current if. We will use the new if node in
                # the next iteration.
                if i_value < variable_domain-1:
                    if_node.orelse = [ast.copy_location(ast.If(), node)]
                    if_node = if_node.orelse[0]
                else:
                    if_node.orelse = []

            if variable_domain == 0:
                result = []

            return result
コード例 #4
0
ファイル: unroller.py プロジェクト: ml-lab/TerpreT
        def visit_With(self, node):
            context_expr = self.visit(node.context_expr)

            result = if_node = ast.copy_location(ast.If(), node)
            variable_domain = get_variable_domain(context_expr)

            for i_value in range(0, variable_domain):
                # Create the test (context_expr == i_value).
                eq_node = ast.copy_location(ast.Eq(), node)
                value_node = ast.copy_location(ast.Num(n=i_value), node)
                if_node.test = ast.copy_location(ast.Compare(context_expr, [eq_node], [value_node]), node)

                # Substitute the current value of the context
                # expression into the body of the with. If the with
                # binds a name, substitute uses of that
                # name. Otherwise, substitute uses of the context
                # expression.
                if node.optional_vars is not None:
                    check_type(node.optional_vars, ast.Name)
                    replacements = {node.optional_vars.id : i_value}
                    if_node.body = eval_const_expressions(subs(node, **replacements)).body

                else:
                    if isinstance(context_expr, ast.Name):
                        replacements = {context_expr.id : i_value}
                        if_node.body = eval_const_expressions(subs(node, **replacements)).body

                    elif isinstance(context_expr, ast.Subscript):
                        replacements = {subscript_to_tuple(context_expr) : ast.copy_location(ast.Num(n=i_value), node)}
                        if_node.body = eval_const_expressions(sub_subscript(node, replacements)).body

                    else:
                        error.fatal_error('Unexpected expression in with.', context_expr)

                update_variable_domains(variable_domains, if_node.body)
                        
                # Recursively process withs inside the body. This must
                # be performed separately for each body, because withs
                # inside the body may depend on the current value of
                # the context expression.
                self.generic_visit(if_node)

                # If this is not the last iteration of the loop,
                # generate a new if node and add it to the else block
                # of the current if. We will use the new if node in
                # the next iteration.
                if i_value < variable_domain-1:
                    if_node.orelse = [ast.copy_location(ast.If(), node)]
                    if_node = if_node.orelse[0]
                else:
                    if_node.orelse = []

            if variable_domain == 0:
                result = []

            return result
コード例 #5
0
 def get_variable_domain(node):
     # Look up the number of values to switch on.
     if isinstance(node, ast.Name):
         return variable_domains[node.id]
     if isinstance(node, str):
         return variable_domains[node]
     if isinstance(node, ast.Subscript):
         if node.value.id in variable_domains:
             return variable_domains[node.value.id]
         node_name = astunparse.unparse(node).rstrip()
         if node_name in variable_domains:
             return variable_domains[node_name]
     error.fatal_error("No variable domain known for expression '%s', for which we want to unroll a for/with." % (astunparse.unparse(node).rstrip()), node)
コード例 #6
0
ファイル: unroller.py プロジェクト: ml-lab/TerpreT
 def get_variable_domain(node):
     # Look up the number of values to switch on.
     if isinstance(node, ast.Name):
         return variable_domains[node.id]
     if isinstance(node, str):
         return variable_domains[node]
     if isinstance(node, ast.Subscript):
         if node.value.id in variable_domains:
             return variable_domains[node.value.id]
         node_name = astunparse.unparse(node).rstrip()
         if node_name in variable_domains:
             return variable_domains[node_name]
     error.fatal_error("No variable domain known for expression '%s', for which we want to unroll a for/with." % (astunparse.unparse(node).rstrip()), node)
コード例 #7
0
def slice_node_to_tuple_of_numbers(slice_node):
    if isinstance(slice_node.value, ast.Tuple):
        indices = (elt for elt in slice_node.value.elts)
    else:
        indices = (slice_node.value,)

    indices = list(indices)
    for index in indices:
        if not(isinstance(index, ast.Num)):
            error.fatal_error("Trying to use non-constant value '%s' as array index." % (astunparse.unparse(index).rstrip()), index)

    # Convert to python numbers
    indices = (index.n for index in indices)

    return indices
コード例 #8
0
ファイル: unroller.py プロジェクト: ml-lab/TerpreT
def slice_node_to_tuple_of_numbers(slice_node):
    if isinstance(slice_node.value, ast.Tuple):
        indices = (elt for elt in slice_node.value.elts)
    else:
        indices = (slice_node.value,)

    indices = list(indices)
    for index in indices:
        if not(isinstance(index, ast.Num)):
            error.fatal_error("Trying to use non-constant value '%s' as array index." % (astunparse.unparse(index).rstrip()), index)

    # Convert to python numbers
    indices = (index.n for index in indices)

    return indices
コード例 #9
0
def main():
    parser = argparse.ArgumentParser(description='RPC client')
    parser.add_argument('--id', required=True, type=int, help='instance id')
    parser.add_argument('--peer', action='store_true', help='peer mode')
    parser.add_argument('--node', action='store_true', help='node mode')
    parser.add_argument('--command', required=True, type=str, help='command')
    base_args = sys.argv[1:6]
    parsed_args = parser.parse_args(base_args)

    cmd_args = sys.argv[6:]
    cmd_args_dict = {}
    for i, arg in enumerate(cmd_args):
        if i % 2 == 0:
            opt = arg[2:]
            if not arg.startswith("--"):
                error.fatal_error("Invalid option '%s'." % arg)
        else:
            cmd_args_dict[opt] = arg

    if len(cmd_args) % 2 != 0:
        error.fatal_error("Invalid command arguments.")

    is_peer = False
    if parsed_args.peer and not parsed_args.node:
        is_peer = True

    rpc_client = rpc.RPC(parsed_args.id, is_peer)
    success = rpc_client.init()
    if not success:
        error.fatal_error("Cannot connect to RPC server (%s %d)." % (
            ("peer" if is_peer else "node"), parsed_args.id))

    if parsed_args.command == "message":
        if "from" in cmd_args_dict and "to" in cmd_args_dict and "message" in cmd_args_dict:
            rpc_client.message(
                cmd_args_dict["from"], cmd_args_dict["to"], cmd_args_dict["message"])
        else:
            error.fatal_error("Missing arguments for command message.")
    elif parsed_args.command == "getlist":
        rpc_client.getlist()
    elif parsed_args.command == "peers":
        rpc_client.peers()
        print(rpc_client.recv_out())
    elif parsed_args.command == "reconnect":
        if "reg-ipv4" in cmd_args_dict and "reg-port" in cmd_args_dict:
            rpc_client.reconnect(
                cmd_args_dict["reg-ipv4"], cmd_args_dict["reg-port"])
        else:
            error.fatal_error("Missing arguments for command reconnect.")
    elif parsed_args.command == "database":
        rpc_client.database()
        print(rpc_client.recv_out())
    elif parsed_args.command == "neighbors":
        rpc_client.neighbors()
        print(rpc_client.recv_out())
    elif parsed_args.command == "connect":
        if "reg-ipv4" in cmd_args_dict and "reg-port" in cmd_args_dict:
            rpc_client.connect(
                cmd_args_dict["reg-ipv4"], cmd_args_dict["reg-port"])
        else:
            error.fatal_error("Missing arguments for command connect.")
    elif parsed_args.command == "disconnect":
        rpc_client.disconnect()
    elif parsed_args.command == "sync":
        rpc_client.sync()
    else:
        error.fatal_error("Unknown command '%s'." % parsed_args.command)
コード例 #10
0
ファイル: pds18-node.py プロジェクト: xsukyz/FITVUT-Projects
def main():
    global g_id
    global g_reg_ip
    global g_reg_port
    global g_database
    global g_node_run
    global g_node
    global g_ACK
    global g_neighbours
    global g_dead_node_timers
    global g_my_key
    # Parse command line arguments
    parser = argparse.ArgumentParser(description='pds18-node')
    parser.add_argument('--id',
                        required=True,
                        type=int,
                        help='Identificator of node')
    parser.add_argument('--reg-ipv4',
                        required=True,
                        type=str,
                        help='Listining IPv4 address')
    parser.add_argument('--reg-port',
                        required=True,
                        type=int,
                        help='Listining port')
    parsed_args = parser.parse_args()

    g_id = parsed_args.id
    # Register SIGINT handler
    signal.signal(signal.SIGINT, signal_handler)

    # Open UDP socket
    g_node = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        g_node.bind((parsed_args.reg_ipv4, parsed_args.reg_port))
        g_node.settimeout(0.1)
    except:
        error.fatal_error("Unable to bind to IP " + parsed_args.reg_ipv4 +
                          " and port " + str(parsed_args.reg_port))

    # Start RPC listener thread
    t1 = threading.Thread(target=rpc_listener)
    t1.start()

    g_reg_ip = parsed_args.reg_ipv4
    g_reg_port = str(parsed_args.reg_port)
    g_my_key = g_reg_ip + "," + g_reg_port

    # Start with empty db, empty list of neighbours
    g_database = {}
    g_database[g_my_key] = []
    g_neighbours = []

    while g_node_run:
        try:
            protocol_data, address = g_node.recvfrom(65565)
            dst_ip = address[0]
            dst_port = address[1]
            dst_key = dst_ip + "," + str(dst_port)
        except socket.timeout:
            continue

        # Try to decode received data
        try:
            m = bencode.bdecode(protocol_data.decode())
        except Exception:
            send_error("Unable to decode message.", 0, dst_ip, dst_port)
            continue

        # Check if message is OK
        if "type" not in m or "txid" not in m:
            send_error("Malformed protocol message.", 0, dst_ip, dst_port)
            continue

        # Check seq number
        if m["txid"] not in range(0, 65536):
            send_error(
                "Sequence number is out of allowed unsigned short range.", 0,
                dst_ip, dst_port)
            continue

        if m["type"] == "error":
            if "verbose" not in m:
                send_error("Malformed ERROR - missing verbose field.",
                           m["txid"], dst_ip, dst_port)
                continue
            sys.stderr.write("Error: %s\n" % m["verbose"])

        elif m["type"] == "ack":
            g_ACK[m["txid"]] = True

        elif m["type"] == "hello":
            if "username" not in m or "ipv4" not in m or "port" not in m:
                send_error("Malformed HELLO - missing required fields.",
                           m["txid"], dst_ip, dst_port)
                continue
            if manage_peer(m["username"], m["ipv4"], m["port"]):
                # DB changed, force sync
                sync()

        elif m["type"] == "update":
            if "db" not in m:
                send_error("Malformed UPDATE - missing db field.", m["txid"],
                           dst_ip, dst_port)
                continue
            if dst_key in g_neighbours:
                if dst_key in g_dead_node_timers:
                    # Ok, node is alive, cancel timer
                    g_dead_node_timers[dst_key].cancel()

                g_dead_node_timers[dst_key] = threading.Timer(
                    NODE_LIVENESS_CHECK_SECONDS, remove_node, [dst_key])
                g_dead_node_timers[dst_key].start()

            # Refresh database
            refresh_db(m["db"], dst_ip, dst_port)

        elif m["type"] == "getlist":
            send_ACK(m["txid"], dst_ip, dst_port)
            is_my_peer = False
            for p in g_database[g_my_key]:
                if p["ipv4"] == dst_ip and p["port"] == dst_port:
                    is_my_peer = True
            if not is_my_peer:
                send_error(
                    "Unable to send LIST. Requestor is not registered to me.",
                    m["txid"], dst_ip, dst_port)
                continue
            send_list(m["txid"], dst_ip, dst_port)
        elif m["type"] == "disconnect":
            send_ACK(m["txid"], dst_ip, dst_port)
            remove_node(dst_key)
            if dst_key in g_dead_node_timers:
                g_dead_node_timers[dst_key].cancel()
        else:
            send_error("Unknown type of command.", m["txid"], dst_ip, dst_port)
            continue
コード例 #11
0
ファイル: pds18-peer.py プロジェクト: xsukyz/FITVUT-Projects
def main():
    global g_id
    global g_reg_ip
    global g_reg_port
    global g_chat_ip
    global g_chat_port
    global g_username
    global g_ACK
    global g_rpc_client
    global g_rpc_send_list_peers
    global g_peers_dict_cache
    global g_peer
    global g_list_new
    # Parse command line arguments
    parser = argparse.ArgumentParser(description='pds18-peer')
    parser.add_argument('--id',
                        required=True,
                        type=int,
                        help='Idenitificator of peer')
    parser.add_argument('--username',
                        required=True,
                        type=str,
                        help='Username of peer')
    parser.add_argument('--chat-ipv4',
                        required=True,
                        type=str,
                        help='Listening IP for chat')
    parser.add_argument('--chat-port',
                        required=True,
                        type=int,
                        help='Listening port for chat')
    parser.add_argument('--reg-ipv4',
                        required=True,
                        type=str,
                        help='IP of registration node')
    parser.add_argument('--reg-port',
                        required=True,
                        type=int,
                        help='Port of of registration node')
    parsed_args = parser.parse_args()

    g_id = parsed_args.id
    g_reg_ip = parsed_args.reg_ipv4
    g_reg_port = parsed_args.reg_port
    g_chat_ip = parsed_args.chat_ipv4
    g_chat_port = parsed_args.chat_port
    g_username = parsed_args.username

    # Register SIGINT handler
    signal.signal(signal.SIGINT, signal_handler)

    # Open UDP socket
    g_peer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        g_peer.bind((g_chat_ip, g_chat_port))
        g_peer.settimeout(0.1)
    except:
        error.fatal_error("Unable to bind to IP " + parsed_args.reg_ipv4 +
                          " and port " + str(parsed_args.reg_port))

    # Start RPC listener thread
    t1 = threading.Thread(target=rpc_listener)
    t1.start()

    def say_hello():
        global g_hello_timer, g_peer, g_reg_ip, g_reg_port
        m = {}
        m["type"] = "hello"
        m["username"] = g_username
        m["ipv4"] = g_chat_ip
        m["port"] = g_chat_port
        m["txid"] = g_seq_number
        hello_msg = bencode.bencode(m)
        # Repeat HELLO
        g_peer.sendto(hello_msg.encode(), ((g_reg_ip, g_reg_port)))
        inc_seq_num()
        g_hello_timer = threading.Timer(REPEAT_HELLO_SECONDS, say_hello)
        g_hello_timer.start()

    # Send first HELLO
    say_hello()

    while g_chat_listener_run:
        try:
            protocol_data, address = g_peer.recvfrom(65565)
            dst_ip = address[0]
            dst_port = address[1]
        except socket.timeout:
            continue
        # Try to decode received data
        try:
            m = bencode.bdecode(protocol_data.decode())
        except Exception:
            send_error("Unable to decode message.", 0, dst_ip, dst_port)
            continue

        # Check if message is OK
        if "type" not in m or "txid" not in m:
            send_error("Malformed protocol message.", 0, dst_ip, dst_port)
            continue

        # Check seq number
        if m["txid"] not in range(0, 65536):
            send_error(
                "Sequence number is out of allowed unsigned short range.", 0,
                dst_ip, dst_port)
            continue

        if m["type"] == "error":
            if "verbose" not in m:
                send_error("Malformed ERROR - missing verbose field.",
                           m["txid"], dst_ip, dst_port)
                continue
            sys.stderr.write("Error: %s\n" % m["verbose"])
            continue

        if m["type"] == "ack":
            g_ACK[m["txid"]] = True
            continue

        if m["type"] == "list":
            send_ACK(m["txid"], dst_ip, dst_port)
            if "peers" not in m:
                send_error("Malformed LIST - missing peers field.", m["txid"],
                           dst_ip, dst_port)
                continue
            if g_rpc_send_list_peers:
                g_rpc_client.sendall(str(m["peers"]).encode())
                g_rpc_send_list_peers = False

            # We received LIST, use it as a local cache
            g_peers_dict_cache = m["peers"]
            # Inform RPC thread that a new LIST was received
            g_list_new = True
            continue

        if m["type"] == "message":
            if "from" not in m or "message" not in m:
                send_error("Malformed MESSAGE - missing required fields.",
                           m["txid"], dst_ip, dst_port)
                continue
            print("Message from %s: %s" % (m["from"], m["message"]))
            send_ACK(m["txid"], dst_ip, dst_port)
            continue

        else:
            send_error("Unknown type of command.", m["txid"], dst_ip, dst_port)
            continue