@@ -1307,7 +1307,7 @@ There are also built-in types for
13071307representing constructs such as parsers, pipelines, actions, and
13081308tables. Users can
13091309construct new types based on these: structures, enumerations, headers,
1310- header stacks, header unions, etc.
1310+ arrays, header stacks, header unions, etc.
13111311
13121312In this document we adopt the following conventions:
13131313
@@ -1416,6 +1416,7 @@ include::grammar.adoc[tag=lvalue]
14161416* Identifiers of a base or derived type.
14171417* Structure, header, and header union field member access operations
14181418 (using the dot notation).
1419+ * References to elements within arrays (see <<sec-expr-array>>)
14191420* References to elements within header stacks (see
14201421 <<sec-expr-hs>>): indexing, and references to `last` and `next`.
14211422* The result of a bit-slice operator `[m:l]`.
@@ -1615,8 +1616,8 @@ There are additional benefits of using copy-in copy-out semantics:
16151616
16161617* It enables P4 to be compiled for architectures that do not support
16171618 references (e.g., where all data is allocated to named
1618- registers. Such architectures may require indices into header stacks that appear
1619- in a program to be compile-time known values.)
1619+ registers. Such architectures may require indices into arrays and header
1620+ stacks that appear in a program to be compile-time known values.)
16201621* It simplifies some compiler analyses, since function parameters can
16211622 never alias to each other within the function body.
16221623
@@ -2131,6 +2132,7 @@ additional types including:
21312132
21322133* `enum`
21332134* `header`
2135+ * arrays
21342136* header stacks
21352137* `struct`
21362138* `header_union`
@@ -2398,22 +2400,30 @@ parsing steps.
23982400Notice that the names `isValid`, `setValid`, `minSizeInBits`, etc. are all
23992401valid header field names.
24002402
2401- [#sec-header-stacks ]
2402- ==== Header stacks
2403+ [#sec-arrays ]
2404+ ==== Arrays
24032405
2404- A header stack represents an array of headers or header unions. A header stack type is
2405- defined as:
2406+ An array is a fixed-size vector of elements of the same type. It is defined as:
24062407
24072408[source,bison]
24082409----
2409- include::grammar.adoc[tag=headerStackType ]
2410+ include::grammar.adoc[tag=arrayType ]
24102411----
24112412
2412- where `typeName` is the name of a header or header union type. For a
2413+ where `typeRef` refers to the element type and the expression is a compile-time
2414+ known value that is the size of the array. For an array type such as `arr[n]`,
2415+ `n-1` is the maximum defined index.
2416+
2417+ [#sec-header-stacks]
2418+ ==== Header stacks
2419+
2420+ A header stack represents an array of headers or header unions. A header stack type is
2421+ defined as an array declaration
2422+ where `typeRef` is the name of a header or header union type. For a
24132423header stack `hs[n]`, the term `n` is the maximum defined size, and
24142424must be a local compile-time known value that is a positive
24152425integer. Nested header stacks are not supported. At runtime a stack
2416- contains `n` values with type `typeName `, only some of which may be
2426+ contains `n` values with type `typeRef `, only some of which may be
24172427valid. Expressions on header stacks are discussed in Section
24182428<<#sec-expr-hs>>.
24192429
@@ -2549,39 +2559,43 @@ arbitrary-precision integer, without a width specified.
25492559|===
25502560| Element type 5+^| Container kind
25512561
2552- | | header | header_union | struct or tuple | list | header stack
2562+ | | header | header_union | struct or tuple | list | array [4] | header stack
2563+
2564+ | `bit<W>` | allowed | error | allowed | allowed | allowed | error
2565+
2566+ | `int<W>` | allowed | error | allowed | allowed | allowed | error
25532567
2554- | `bit <W>` | allowed | error | allowed | allowed | error
2568+ | `varbit <W>` | allowed | error | allowed | allowed | allowed | error
25552569
2556- | `int<W> ` | allowed | error | allowed | allowed | error
2570+ | `int` | error | error | error | allowed | error | error
25572571
2558- | `varbit<W> ` | allowed | error | allowed | allowed | error
2572+ | `void ` | error | error | error | error | error | error
25592573
2560- | `int ` | error | error | error | allowed | error
2574+ | `string ` | error | error | error | allowed | error | error
25612575
2562- | `void ` | error | error | error | error | error
2576+ | `error ` | error | error | allowed | allowed | error | error
25632577
2564- | `string ` | error | error | error | allowed | error
2578+ | `match_kind ` | error | error | error | allowed | error | error
25652579
2566- | `error ` | error | error | allowed | allowed | error
2580+ | `bool ` | allowed | error | allowed | allowed | allowed | error
25672581
2568- | `match_kind` | error | error | error | allowed | error
2582+ | `enumeration types` | allowed [1] | error | allowed | allowed | allowed | error
25692583
2570- | `bool ` | allowed | error | allowed | allowed | error
2584+ | `header types ` | error | allowed | allowed | allowed | NA [3] | allowed
25712585
2572- | `enumeration types` | allowed [1] | error | allowed | allowed | error
2586+ | `array types` [4] | allowed | error | allowed | error [7] | allowed [5] | error
25732587
2574- | `header types ` | error | allowed | allowed | allowed | allowed
2588+ | `header stacks ` | error | error | allowed | allowed | error | error
25752589
2576- | `header stacks` | error | error | allowed | allowed | error
2590+ | `header_unions` | error | error | allowed | allowed | NA [3] | allowed
25772591
2578- | `header_unions` | error | error | allowed | allowed | allowed
2592+ | `struct types` | allowed [2] | error | allowed | allowed | allowed | error
25792593
2580- | `struct types` | allowed [2] | error | allowed | allowed | error
2594+ | `tuple types` | error | error | allowed | allowed | error [7] | error
25812595
2582- | `tuple types` | error | error | allowed | allowed | error
2596+ | `list types` | error | error | error | allowed | error [7] | error
25832597
2584- | `list types ` | error | error | error | allowed | error
2598+ | `extern instances ` | error | error | error | erroe | allowed [6] | error
25852599
25862600| `extern types` | error | error | error | error | error
25872601
@@ -2599,6 +2613,19 @@ underlying type and representation for `enum` elements.
25992613used as a field in a `header` must contain only `bit<W>`, `int<W>`, a
26002614serializable `enum`, or a `bool`.
26012615
2616+ [3] An array whose element type is a header or header union type is a
2617+ header stack.
2618+
2619+ [4] This is for array types that are not header stacks (the array element
2620+ type is not a header or header_union.)
2621+
2622+ [5] Architectures may disallow arrays of arrays.
2623+
2624+ [6] Architectures may disallow arrays of extern instances.
2625+
2626+ [7] Currently these are disallowed because there doesn't seem to be any use case for
2627+ them, but there do not appear to be any particular pitfalls to allowing them.
2628+
26022629Rationale: `int` does not have precise storage requirements,
26032630unlike `bit<>` or `int<>` types. `match_kind`
26042631values are not useful to store in a variable, as they
@@ -2639,6 +2666,8 @@ The table below lists all types that may appear as base types in a
26392666
26402667| `enumeration types` | allowed | error
26412668
2669+ | `array types` | allowed | error
2670+
26422671| `header types` | allowed | error
26432672
26442673| `header stacks` | allowed | error
@@ -3014,6 +3043,7 @@ as follows:
30143043 even if 0 is actually not one of the named values in the enum.
30153044* For `enum` values without an underlying type the default value is the
30163045 first value that appears in the `enum` type declaration.
3046+ * For arrays the default value is that all elements have their default value.
30173047* For `header` types the default value is `invalid`.
30183048* For header stacks the default value is that all elements are invalid and the
30193049 `nextIndex` is 0.
@@ -3929,7 +3959,7 @@ The following casts are legal in P4:
39293959* casts between a type introduced by `type` and the original type.
39303960* casts between an `enum` with an explicit type and its underlying type
39313961* casts of a key-value list to a struct type or a header type (see <<sec-structure-expressions>>)
3932- * casts of a tuple expression to a header stack type
3962+ * casts of a tuple expression to an array or header stack type
39333963* casts of an invalid expression `+{#}+` to a header or a header union type
39343964* casts where the destination type is the same as the source type
39353965 if the destination type appears in this list (this excludes
@@ -3946,7 +3976,7 @@ expression with a fixed-width type will implicitly cast the `int`
39463976expression to the type of the other expression. For enums with an underlying
39473977type, it can be implicitly cast to its underlying type whenever appropriate,
39483978including but not limited to in shifts, concatenation, bit slicing indexes,
3949- header stack indexes as well as other unary and binary operations.
3979+ array and header stack indexes as well as other unary and binary operations.
39503980
39513981For example, given the following declarations,
39523982
@@ -4481,6 +4511,16 @@ for a description of the behavior if header fields are read without
44814511being initialized, or header fields are written to a currently invalid
44824512header.
44834513
4514+ [#sec-expr-array]
4515+ === Operations on arrays
4516+
4517+ Arrays can be indexed with an expression to select one element of the
4518+ array. `arr[index]` refers to that element and is an l-value if `arr` is
4519+ an l-value.
4520+
4521+ Arrays can be assigned to another array with the same element type and
4522+ size.
4523+
44844524[#sec-expr-hs]
44854525=== Operations on header stacks
44864526
@@ -5369,7 +5409,7 @@ headers and other header-related types, which are initialized to invalid in the
53695409same way as described for direction `out` parameters in <<sec-calling-convention>>). The language places few restrictions on
53705410the types of the variables: most P4 types that can be written
53715411explicitly can be used (e.g., base types, `struct`, `header`,
5372- header stack, `tuple`). However, it is impossible to declare variables with type `int`,
5412+ array, header stack, `tuple`). However, it is impossible to declare variables with type `int`,
53735413or with types that are only synthesized by the compiler (e.g., `set`)
53745414In addition, variables of type `parser`, `control`, `package`,
53755415or `extern` types must be declared using instantiations (see <<sec-instantiations>>).
@@ -5660,7 +5700,7 @@ following behavior after the expression evaluation is interrupted.
56605700 then neither expression `e2` nor `e3` are evaluated.
56615701** If the expression is the right hand side of an assignment
56625702 statement, or part of the calculation of the L-value on the left
5663- hand side (e.g. the index expression of a header stack reference),
5703+ hand side (e.g. the index expression of an array or header stack reference),
56645704 then no assignment occurs.
56655705** If the expression is an argument passed to a function or method
56665706 call, then the function/method call does not occur.
@@ -5828,7 +5868,7 @@ The update statements will be executed after the loop body and before evaluating
58285868condition again for the next iteration.
58295869
58305870The `for`-`in` statement executes the body once for each value in a range or each
5831- element in a list expression or header stack. The list or range expression itself
5871+ element in a list expression, array or header stack. The list or range expression itself
58325872will only be evaluated once, before the first iteration of the loop. All side effects
58335873in the list or range expression will occur before the first iteration of the loop body.
58345874
@@ -7919,11 +7959,11 @@ extern packet_out {
79197959----
79207960
79217961The `emit` method supports appending the data contained in a
7922- header, header stack, `struct`, or header union to the output packet.
7962+ header, array, header stack, `struct`, or header union to the output packet.
79237963
79247964- When applied to a header, `emit` appends the data in the header to
79257965 the packet if it is valid and otherwise behaves like a no-op.
7926- - When applied to a header stack, `emit` recursively invokes itself to
7966+ - When applied to an array or header stack, `emit` recursively invokes itself to
79277967 each element of the stack.
79287968- When applied to a `struct` or header union, `emit` recursively
79297969 invokes itself to each field. Note, a `struct` must not contain
@@ -9401,7 +9441,7 @@ error {
94019441 NoError, /// No error.
94029442 PacketTooShort, /// Not enough bits in packet for 'extract'.
94039443 NoMatch, /// 'select' expression has no matches.
9404- StackOutOfBounds, /// Reference to invalid element of a header stack.
9444+ StackOutOfBounds, /// Reference to invalid element of an array or header stack.
94059445 HeaderTooShort, /// Extracting too many bits into a varbit field.
94069446 ParserTimeout, /// Parser execution time limit exceeded.
94079447 ParserInvalidArgument /// Parser operation was called with a value
0 commit comments