@@ -1289,7 +1289,7 @@ There are also built-in types for
12891289representing constructs such as parsers, pipelines, actions, and
12901290tables. Users can
12911291construct new types based on these: structures, enumerations, headers,
1292- header stacks, header unions, etc.
1292+ arrays, header stacks, header unions, etc.
12931293
12941294In this document we adopt the following conventions:
12951295
@@ -1398,6 +1398,7 @@ include::grammar.adoc[tag=lvalue]
13981398* Identifiers of a base or derived type.
13991399* Structure, header, and header union field member access operations
14001400 (using the dot notation).
1401+ * References to elements within arrays (see <<sec-expr-array>>)
14011402* References to elements within header stacks (see
14021403 <<sec-expr-hs>>): indexing, and references to `last` and `next`.
14031404* The result of a bit-slice operator `[m:l]`.
@@ -1597,8 +1598,8 @@ There are additional benefits of using copy-in copy-out semantics:
15971598
15981599* It enables P4 to be compiled for architectures that do not support
15991600 references (e.g., where all data is allocated to named
1600- registers. Such architectures may require indices into header stacks that appear
1601- in a program to be compile-time known values.)
1601+ registers. Such architectures may require indices into arrays and header
1602+ stacks that appear in a program to be compile-time known values.)
16021603* It simplifies some compiler analyses, since function parameters can
16031604 never alias to each other within the function body.
16041605
@@ -2108,6 +2109,7 @@ additional types including:
21082109
21092110* `enum`
21102111* `header`
2112+ * arrays
21112113* header stacks
21122114* `struct`
21132115* `header_union`
@@ -2375,22 +2377,30 @@ parsing steps.
23752377Notice that the names `isValid`, `setValid`, `minSizeInBits`, etc. are all
23762378valid header field names.
23772379
2378- [#sec-header-stacks ]
2379- ==== Header stacks
2380+ [#sec-arrays ]
2381+ ==== Arrays
23802382
2381- A header stack represents an array of headers or header unions. A header stack type is
2382- defined as:
2383+ An array is a fixed-size vector of elements of the same type. It is defined as:
23832384
23842385[source,bison]
23852386----
2386- include::grammar.adoc[tag=headerStackType ]
2387+ include::grammar.adoc[tag=arrayType ]
23872388----
23882389
2389- where `typeName` is the name of a header or header union type. For a
2390+ where `typeRef` refers to the element type and the expression is a compile-time
2391+ known value that is the size of the array. For an array type such as `arr[n]`,
2392+ `n-1` is the maximum defined index.
2393+
2394+ [#sec-header-stacks]
2395+ ==== Header stacks
2396+
2397+ A header stack represents an array of headers or header unions. A header stack type is
2398+ defined as an array declaration
2399+ where `typeRef` is the name of a header or header union type. For a
23902400header stack `hs[n]`, the term `n` is the maximum defined size, and
23912401must be a local compile-time known value that is a positive
23922402integer. Nested header stacks are not supported. At runtime a stack
2393- contains `n` values with type `typeName `, only some of which may be
2403+ contains `n` values with type `typeRef `, only some of which may be
23942404valid. Expressions on header stacks are discussed in Section
23952405<<#sec-expr-hs>>.
23962406
@@ -2526,39 +2536,41 @@ arbitrary-precision integer, without a width specified.
25262536|===
25272537| Element type 5+^| Container kind
25282538
2529- | | header | header_union | struct or tuple | list | header stack
2539+ | | header | header_union | struct or tuple | list | array [4] | header stack
25302540
2531- | `bit<W>` | allowed | error | allowed | allowed | error
2541+ | `bit<W>` | allowed | error | allowed | allowed | allowed | error
25322542
2533- | `int<W>` | allowed | error | allowed | allowed | error
2543+ | `int<W>` | allowed | error | allowed | allowed | allowed | error
25342544
2535- | `varbit<W>` | allowed | error | allowed | allowed | error
2545+ | `varbit<W>` | allowed | error | allowed | allowed | allowed | error
25362546
2537- | `int` | error | error | error | allowed | error
2547+ | `int` | error | error | error | allowed | error | error
25382548
2539- | `void` | error | error | error | error | error
2549+ | `void` | error | error | error | error | error | error
25402550
2541- | `string` | error | error | error | allowed | error
2551+ | `string` | error | error | error | allowed | error | error
25422552
2543- | `error` | error | error | allowed | allowed | error
2553+ | `error` | error | error | allowed | allowed | error | error
25442554
2545- | `match_kind` | error | error | error | allowed | error
2555+ | `match_kind` | error | error | error | allowed | error | error
25462556
2547- | `bool` | allowed | error | allowed | allowed | error
2557+ | `bool` | allowed | error | allowed | allowed | allowed | error
25482558
2549- | `enumeration types` | allowed [1] | error | allowed | allowed | error
2559+ | `enumeration types` | allowed [1] | error | allowed | allowed | allowed | error
25502560
2551- | `header types` | error | allowed | allowed | allowed | allowed
2561+ | `header types` | error | allowed | allowed | allowed | NA [3] | allowed
25522562
2553- | `header stacks` | error | error | allowed | allowed | error
2563+ | `array types` [4] | allowed | error | allowed | error? | allowed [5] | error
25542564
2555- | `header_unions` | error | error | allowed | allowed | allowed
2565+ | `header stacks` | error | error | allowed | allowed | error | error
25562566
2557- | `struct types` | allowed [2] | error | allowed | allowed | error
2567+ | `header_unions` | error | error | allowed | allowed | NA [3] | allowed
25582568
2559- | `tuple types` | error | error | allowed | allowed | error
2569+ | `struct types` | allowed [2] | error | allowed | allowed | allowed | error
25602570
2561- | `list types` | error | error | error | allowed | error
2571+ | `tuple types` | error | error | allowed | allowed | error? | error
2572+
2573+ | `list types` | error | error | error | allowed | error? | error
25622574
25632575|===
25642576
@@ -2569,6 +2581,14 @@ underlying type and representation for `enum` elements.
25692581used as a field in a `header` must contain only `bit<W>`, `int<W>`, a
25702582serializable `enum`, or a `bool`.
25712583
2584+ [3] An array whose element type is a header or header union type is a
2585+ header stack.
2586+
2587+ [4] This is for array types that are not header stacks (the array element
2588+ type is not a header or header_union)
2589+
2590+ [5] Architectures may disallow arrays of arrays
2591+
25722592Rationale: `int` does not have precise storage requirements,
25732593unlike `bit<>` or `int<>` types. `match_kind`
25742594values are not useful to store in a variable, as they
@@ -2609,6 +2629,8 @@ The table below lists all types that may appear as base types in a
26092629
26102630| enumeration types | allowed | error
26112631
2632+ | array types | allowed | error
2633+
26122634| header types | allowed | error
26132635
26142636| header stacks | allowed | error
@@ -2980,6 +3002,7 @@ as follows:
29803002 even if 0 is actually not one of the named values in the enum.
29813003* For `enum` values without an underlying type the default value is the
29823004 first value that appears in the `enum` type declaration.
3005+ * For arrays the default value is that all elements have their default value.
29833006* For `header` types the default value is `invalid`.
29843007* For header stacks the default value is that all elements are invalid and the
29853008 `nextIndex` is 0.
@@ -3879,7 +3902,7 @@ The following casts are legal in P4:
38793902* casts between a type introduced by `type` and the original type.
38803903* casts between an `enum` with an explicit type and its underlying type
38813904* casts of a key-value list to a struct type or a header type (see <<sec-structure-expressions>>)
3882- * casts of a tuple expression to a header stack type
3905+ * casts of a tuple expression to an array or header stack type
38833906* casts of an invalid expression `+{#}+` to a header or a header union type
38843907* casts where the destination type is the same as the source type
38853908 if the destination type appears in this list (this excludes
@@ -3896,7 +3919,7 @@ expression with a fixed-width type will implicitly cast the `int`
38963919expression to the type of the other expression. For enums with an underlying
38973920type, it can be implicitly cast to its underlying type whenever appropriate,
38983921including but not limited to in shifts, concatenation, bit slicing indexes,
3899- header stack indexes as well as other unary and binary operations.
3922+ array and header stack indexes as well as other unary and binary operations.
39003923
39013924For example, given the following declarations,
39023925
@@ -4431,6 +4454,16 @@ for a description of the behavior if header fields are read without
44314454being initialized, or header fields are written to a currently invalid
44324455header.
44334456
4457+ [#sec-expr-array]
4458+ === Operations on arrays
4459+
4460+ Arrays can be indexed with an expression to select one element of the
4461+ array. `arr[index]` refers to that element and is an l-value if `arr` is
4462+ an l-value.
4463+
4464+ Arrays can be assigned to another array with the same element type and
4465+ size.
4466+
44344467[#sec-expr-hs]
44354468=== Operations on header stacks
44364469
@@ -5321,7 +5354,7 @@ headers and other header-related types, which are initialized to invalid in the
53215354same way as described for direction `out` parameters in <<sec-calling-convention>>). The language places few restrictions on
53225355the types of the variables: most P4 types that can be written
53235356explicitly can be used (e.g., base types, `struct`, `header`,
5324- header stack, `tuple`). However, it is impossible to declare variables with type `int`,
5357+ array, header stack, `tuple`). However, it is impossible to declare variables with type `int`,
53255358or with types that are only synthesized by the compiler (e.g., `set`)
53265359In addition, variables of type `parser`, `control`, `package`,
53275360or `extern` types must be declared using instantiations (see <<sec-instantiations>>).
@@ -5596,7 +5629,7 @@ following behavior after the expression evaluation is interrupted.
55965629 then neither expression `e2` nor `e3` are evaluated.
55975630** If the expression is the right hand side of an assignment
55985631 statement, or part of the calculation of the L-value on the left
5599- hand side (e.g. the index expression of a header stack reference),
5632+ hand side (e.g. the index expression of an array or header stack reference),
56005633 then no assignment occurs.
56015634** If the expression is an argument passed to a function or method
56025635 call, then the function/method call does not occur.
@@ -5752,7 +5785,7 @@ The update statements will be executed after the loop body and before evaluating
57525785condition again for the next iteration.
57535786
57545787The `for`-`in` statement executes the body once for each value in a range or each
5755- element in a list expression or header stack. The list or range expression itself
5788+ element in a list expression, array or header stack. The list or range expression itself
57565789will only be evaluated once, before the first iteration of the loop. All side effects
57575790in the list or range expression will occur before the first iteration of the loop body.
57585791
@@ -7837,11 +7870,11 @@ extern packet_out {
78377870----
78387871
78397872The `emit` method supports appending the data contained in a
7840- header, header stack, `struct`, or header union to the output packet.
7873+ header, array, header stack, `struct`, or header union to the output packet.
78417874
78427875- When applied to a header, `emit` appends the data in the header to
78437876 the packet if it is valid and otherwise behaves like a no-op.
7844- - When applied to a header stack, `emit` recursively invokes itself to
7877+ - When applied to an array or header stack, `emit` recursively invokes itself to
78457878 each element of the stack.
78467879- When applied to a `struct` or header union, `emit` recursively
78477880 invokes itself to each field. Note, a `struct` must not contain
@@ -9279,7 +9312,7 @@ error {
92799312 NoError, /// No error.
92809313 PacketTooShort, /// Not enough bits in packet for 'extract'.
92819314 NoMatch, /// 'select' expression has no matches.
9282- StackOutOfBounds, /// Reference to invalid element of a header stack.
9315+ StackOutOfBounds, /// Reference to invalid element of an array or header stack.
92839316 HeaderTooShort, /// Extracting too many bits into a varbit field.
92849317 ParserTimeout, /// Parser execution time limit exceeded.
92859318 ParserInvalidArgument /// Parser operation was called with a value
0 commit comments