Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify restrictions on runtime and compile-time call sites #1349

Open
jaehyun1ee opened this issue Nov 25, 2024 · 3 comments
Open

Clarify restrictions on runtime and compile-time call sites #1349

jaehyun1ee opened this issue Nov 25, 2024 · 3 comments

Comments

@jaehyun1ee
Copy link
Contributor

Spec Appendix F lists restrictions on compile time and run time calls. I have three questions regarding it.

(1) Calling function from a parser or control top-level

The appendix explicitly disallows invoking a function from a parser or control top-level at runtime. However, some p4c tests (issue1538.p4, issue2957.p4, issue2488-bmv2.p4, issue2543-1.p4) exhibit such a behavior, for example,

bit<16> incr(in bit<16> x) {
    return x + 1;
}
parser ParserImpl(packet_in packet,
                  out headers hdr,
                  inout metadata meta,
                  inout standard_metadata_t standard_metadata) {
    bit<16> tmp_port = incr((bit<16>) standard_metadata.ingress_port);
    ...
}

May I ask the rationale for disallowing such?

(2) Calling an extern function from a function body

Understanding extern as meaning both an extern method and an extern function in the below table,

image

a function cannot invoke an extern function.

However, issue3274.p4, issue3274-2.p4, issue3292.p4, and issue4500.p4 exhibit such a behavior.

extern bit<32> f(in bit<32> x, out bit<16> y);
bit<32> x() {
    return f(x = 1, y = _);
}

Also, what may be the rationale for disallowing such a behavior?

(3) Classification of a package initializer

The restriction of constructor call-sites is as follows.

image

I wonder how we can classify top-level package initializer, according to the above table.

control _c(out bit<32> r);
package top(_c _c);

top(c()) main;

Like the example, a package instantiation usually includes nameless instantiations of a control / parser type.

Then, how should unnamed instantiations within a package initializer be classified? Are they considered part of the package instantiation process (the package column), or do they have a distinct classification that is not reflected in the table? If it applies to the former case, then I believe the table should say "yes" for combinations (parser, package), (control, package), and (extern, package).

@jafingerhut
Copy link
Collaborator

Regarding (1)

The table in Appendix F of the spec with headings "This type" and "can be called at run time from this place in a P4 program" has a column labeled "parser or top level".

You are interpreting "top level" as "top level within a control", by which I think you mean "after the control name and parameters and opening brace, but before the control's apply block".

I interpret "top level" there as: "outside of any parser, control, action, or function definition, at the top level in your entire P4 program." If that is the intent, then unfortunately none of the columns specifies what the restrictions are at the top level within a control as described in the previous paragraph.

It does seem reasonable to me to explicitly allow function calls everywhere within a control, not just within the control apply block, especially if the current p4c implementation supports it.

I wrote the initial version of all tables in Appendix F, and I do not know recall the rationale for disallowing function calls within parsers. If the current implementation supports it, it seems reasonable to explicitly allow that to me.

@jafingerhut
Copy link
Collaborator

Regarding (2)

If the current p4c implementation supports extern function/method calls within function bodies, it seems worth it to me to explicitly allow it in the spec.

Again, these tables were written long enough ago that if there is no explicit rationale written in the spec (there is for some table entries, but not others), I do not recall. In many cases we were probably conservative, and only made something supported if we knew we wanted to. If a cell of the table was at all questionable whether it should be yes or no, we typically put "no".

@jaehyun1ee
Copy link
Contributor Author

Thank you for the comments!

Regarding (1) Calling function from a parser or control top-level, I interpreted the column as "top level within a parser/control" because the preceding columns, explicitly restrict their scope to the parser states and control apply block.

Also, I thought that it does not mean the top-level itself, because I believe it is allowed to call functions, e.g., static_assert from the top-level scope.

How about, (i) adding an explanation that the column "parser or control top-level" means, the local declarations within a parser/control block and (ii) allowing function calls within them?

Regarding (2) Calling an extern function from a function body, I'll write a PR soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants