Ejemplo n.º 1
0
def regroup_attrs(hlir):
    """Groups hlir objects by their types into hlir attributes."""

    hlir.groups = P4Node({'node_type': 'groups'})

    groups = [
        ('control_types', 'Type_Control'),
        ('controls', 'P4Control'),
        ('decl_consts', 'Declaration_Constant'),
        ('decl_instances', 'Declaration_Instance'),
        ('decl_matchkinds', 'Declaration_MatchKind'),
        ('enums', 'Type_Enum'),
        ('errors', 'Type_Error'),
        ('externs', 'Type_Extern'),
        ('headers', 'Type_Header'),
        ('methods', 'Method'),
        ('packages', 'Type_Package'),
        ('parsers', 'P4Parser'),
        # note: structs are separated using attrs_regroup_structs()
        # ('structs', 'Type_Struct'),
        ('typedefs', 'Type_Typedef'),
        ('type_parsers', 'Type_Parser'),
    ]

    for new_group_name, node_type_name in groups:
        make_node_group(hlir, new_group_name, hlir.objects[node_type_name],
                        hlir.objects)
Ejemplo n.º 2
0
def attrs_regroup_path_expressions(hlir):
    """Makes hlir attributes for distinct kinds of structs."""

    pes = hlir.all_nodes.by_type('PathExpression')

    hlir.groups.pathexprs = P4Node({'node_type': 'grouped'})

    hlir.groups.pathexprs.under_mcall = remove_nodes(
        pes.filter(lambda m: m.parent().node_type == 'MethodCallExpression'),
        pes)
    hlir.groups.pathexprs.under_assign = remove_nodes(
        pes.filter(lambda m: m.parent().node_type == 'AssignmentStatement'),
        pes)
    hlir.groups.pathexprs.under_keyelement = remove_nodes(
        pes.filter(lambda m: m.parent().node_type == 'KeyElement'), pes)

    hlir.groups.pathexprs.extern_under_member = remove_nodes(
        pes.filter(lambda m: m.parent().node_type == 'Member' and m.type.
                   node_type == 'Type_Extern'), pes)

    hlir.groups.pathexprs.under_header = remove_nodes(
        pes.filter(lambda m: m.parent().node_type == 'Member' and m.parent().
                   type.node_type == 'Type_Header'), pes)
    hlir.groups.pathexprs.under_unknown = remove_nodes(
        pes.filter(lambda m: m.parent().node_type == 'Member' and m.parent().
                   type.node_type == 'Type_Unknown'), pes)

    hlir.groups.pathexprs.action = remove_nodes(
        pes.filter('type.node_type', 'Type_Action'), pes)
    hlir.groups.pathexprs.io = remove_nodes(
        pes.filter('type.node_type', 'Type_Extern'), pes)
    hlir.groups.pathexprs.header = remove_nodes(
        pes.filter('type.node_type', 'Type_Header'), pes)
    hlir.groups.pathexprs.struct = remove_nodes(
        pes.filter('type.node_type', 'Type_Struct'), pes)
    hlir.groups.pathexprs.state = remove_nodes(
        pes.filter('type.node_type', 'Type_State'), pes)
    hlir.groups.pathexprs.method = remove_nodes(
        pes.filter('type.node_type', 'Type_Method'), pes)
    hlir.groups.pathexprs.matchkind = remove_nodes(
        pes.filter('type.node_type', 'Type_MatchKind'), pes)
    hlir.groups.pathexprs.table = remove_nodes(
        pes.filter('type.node_type', 'Type_Table'), pes)
    hlir.groups.pathexprs.boolean = remove_nodes(
        pes.filter('type.node_type', 'Type_Boolean'), pes)
    hlir.groups.pathexprs.specialized_canonical = remove_nodes(
        pes.filter('type.node_type', 'Type_SpecializedCanonical'), pes)
    hlir.groups.pathexprs.package = remove_nodes(
        pes.filter('type.node_type', 'Type_Package'), pes)
    hlir.groups.pathexprs.bits = remove_nodes(
        pes.filter('type.node_type', 'Type_Bits'), pes)
    hlir.groups.pathexprs.varbits = remove_nodes(
        pes.filter('type.node_type', 'Type_Varbits'), pes)

    hlir.groups.pathexprs.arithmetic = remove_nodes(
        pes.filter(lambda m: (op := m.parent().node_type) in simple_binary_ops
                   or op in complex_binary_ops), pes)

    check_no_leftovers(hlir.groups.pathexprs, pes, "path expression")
Ejemplo n.º 3
0
def attrs_extern(hlir):
    infos = model_specific_infos[hlir.news.model]

    for extern in hlir.all_nodes.by_type('Type_Extern'):
        if 'smem_type' in extern:
            continue

        extern.constructors = P4Node(
            [ctor for ctor in extern.methods if ctor.name == extern.name])
        extern.interface_methods = P4Node(
            [ctor for ctor in extern.methods if ctor.name != extern.name])
        extern.is_repr_model_specific = extern.name in infos['extern_reprs']

        if extern.is_repr_model_specific:
            extern.repr = infos['extern_reprs'][extern.name]
            extern.is_unused = False
        else:
            extern.repr = get_extern_repr(extern)
            extern.is_unused = is_extern_unused(extern, extern.repr)
Ejemplo n.º 4
0
def walk_json(node, fun, nodes, skip_elems=['Node_Type', 'Node_ID', 'Source_Info'], node_parent_chain=[]):
    rets = []
    if type(node) is dict or type(node) is list:
        node_id = node['Node_ID']
        if node_id not in nodes:
            nodes[node_id] = P4Node({
                'Node_ID': node_id,
                'node_type': '(incomplete_json_data)',
                'node_parents': [node_parent_chain],
            })

        if 'vec' in node.keys():
            elems = [(None, elem) for elem in node['vec']]
        else:
            elems = [(key, node[key]) for key in node.keys() if key not in skip_elems]
        rets = [(key, walk_json(elem, fun, nodes, skip_elems, node_parent_chain + [nodes[node_id]])) for (key, elem) in elems if elem != {}]

    return fun(node, rets, nodes, skip_elems, node_parent_chain)
Ejemplo n.º 5
0
        "user_meta_var":
        "user_meta",
        "meta_types": [
            "psa_ingress_parser_input_metadata_t",
            "psa_egress_parser_input_metadata_t",
            "psa_ingress_input_metadata_t",
            "psa_ingress_output_metadata_t",
            "psa_egress_input_metadata_t",
            "psa_egress_deparser_input_metadata_t",
            "psa_egress_output_metadata_t",
        ],
        "extern_reprs": {
            'InternetChecksum':
            P4Node({
                'node_type': 'Type_Bits',
                'isSigned': False,
                'size': 16,
                'padded_size': 16
            }),
            'Digest':
            P4Node({
                'node_type': 'Type_Bits',
                'isSigned': False,
                'size': 32,
                'padded_size': 32
            }),
        },
        # psa.p4 does not mark deparsers with @deparser, hence this hack
        "deparsers": ["IngressDeparser", "EgressDeparser"],
    },
}
Ejemplo n.º 6
0
def attrs_regroup_members(hlir):
    mes = hlir.all_nodes.by_type('Member')

    hlir.groups.member_exprs = P4Node({'node_type': 'grouped'})
    mem_exprs = hlir.groups.member_exprs

    mem_methods = mes.filter('type.node_type', 'Type_Method')

    mem_path_members = mem_methods.filter(lambda m: 'member' in m)
    mem_path_methods = mem_methods.filter(lambda m: 'path' in m.expr)
    mem_path_pathexpressions = mes.filter('expr.node_type', 'PathExpression')

    hlir.groups.member_exprs.enums = remove_nodes(
        mes.filter('type.node_type', 'Type_Enum'), mes)
    hlir.groups.member_exprs.booleans = remove_nodes(
        mes.filter('type.node_type', 'Type_Boolean'), mes)
    hlir.groups.member_exprs.errors = remove_nodes(
        mes.filter('type.node_type', 'Type_Error'), mes)
    hlir.groups.member_exprs.action_enums = remove_nodes(
        mes.filter('type.node_type', 'Type_ActionEnum'), mes)
    hlir.groups.member_exprs.header_stacks = remove_nodes(
        mes.filter('type.node_type', 'Type_Stack'), mes)

    hlir.groups.member_exprs.indexed_header_stack = remove_nodes(
        mes.filter('expr.node_type', 'ArrayIndex'), mes)

    hlir.groups.member_exprs.specialized_canonical = remove_nodes(
        mes.filter('expr.type.node_type', 'Type_SpecializedCanonical'), mes)
    hlir.groups.member_exprs.tables = remove_nodes(
        mem_path_methods.filter('expr.type.node_type', 'Type_Table'), mes)
    hlir.groups.member_exprs.externs = remove_nodes(
        mem_path_methods.filter('expr.type.node_type', 'Type_Extern'), mes)

    hlir.groups.member_exprs.headers = remove_nodes(
        mem_path_pathexpressions.filter('type.node_type', 'Type_Header'), mes)
    hlir.groups.member_exprs.structs = remove_nodes(
        mem_path_pathexpressions.filter('type.node_type', 'Type_Struct'), mes)
    hlir.groups.member_exprs.bits = remove_nodes(
        mem_path_pathexpressions.filter('type.node_type', 'Type_Bits'), mes)
    hlir.groups.member_exprs.varbits = remove_nodes(
        mem_path_pathexpressions.filter('type.node_type', 'Type_Varbits'), mes)

    hlir.groups.member_exprs.members = remove_nodes(
        mem_methods.filter(lambda m: 'member' in m.expr), mes)
    hlir.groups.member_exprs.exprs = remove_nodes(
        mes.filter(lambda m: 'expr' in m.expr), mes)
    hlir.groups.member_exprs.under_mcall = remove_nodes(
        mes.filter(lambda m: m.parent().node_type == 'MethodCallExpression'),
        mes)
    hlir.groups.member_exprs.keyelement = remove_nodes(
        mes.filter(lambda m: m.parent().node_type == 'KeyElement'), mes)

    check_no_leftovers(hlir.groups.member_exprs, mes, "member expression")

    hlir.object_groups = P4Node([
        hlir.control_types,
        hlir.controls,
        hlir.decl_instances,
        hlir.decl_matchkinds,
        hlir.enums,
        hlir.errors,
        hlir.externs,
        hlir.headers,
        hlir.methods,
        hlir.packages,
        hlir.parsers,
        hlir.typedefs,
        hlir.type_parsers,
        hlir.news.data,
        hlir.news.meta,
    ])
Ejemplo n.º 7
0
def walk_json_from_top(node, fun=p4node_creator):
    nodes = {}
    hlir = walk_json(node, fun, nodes)
    hlir.all_nodes = P4Node({'node_type': 'all_nodes'}, [nodes[idx] for idx in nodes.keys()])
    return hlir