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 instantiation of objects with abstract methods #1346

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

Clarify instantiation of objects with abstract methods #1346

jaehyun1ee opened this issue Nov 25, 2024 · 0 comments

Comments

@jaehyun1ee
Copy link
Contributor

The spec defines instantiation of objects with abstract methods in section 11.3.1, and I found two points where the semantics is unclear.

(1) Restriction on the parameter names of instantiated abstract methods

The spec mentions only that:

When instantiating an extern type that has abstract methods users have to supply implementations for all such methods.

However, it does not restrict that the parameter names in the implementation must match the parameter names in the abstract method signatures. For instance, virtual.p4 in the p4c test suite exhibits such a behavior.

extern Virtual {
    Virtual();
    abstract bit<16> f();
    abstract void g(inout data ix);
}
...
Virtual() cntr = {
    bit<16> f() {
        return 1;
    }
    void g(inout data x) {}
};

Notice that while the abstract method g was declared as having an inout parameter of data type and name ix, the provided implementation of g has parameter name x instead. Also, issue2175-1.p4, issue2175-3.p4, and issue2175-4.p4 behave similarly.

While the code above seems okay, it can get problematic considering another feature of P4, which is method overloading. P4 allows overloading of extern methods through parameter arity or names. This allows a developer to define extern objects like:

extern Virtual {
    Virtual();
    abstract void g(inout data x);
    abstract void g(inout data y);
}

Then, when instantiating the above object, we should be clear in which abstract method we are supplying an implementation for.

Virtual() cntr = {
    void g(inout data x) {}
    void g(inout data y) {}
};

Thus, I believe that the spec should make clear that the method implementations must have the same parameter names as in the abstract method signature. Without such a restriction, it would be unclear whether void g(inout data x) {} implements abstract void g(inout data x); or abstract void g(inout data y);.

(2) Scope when implementing an abstract method

When implementing an abstract method, the scope is limited to:

The abstract methods can only use the supplied arguments or refer to values that are in the top-level scope. When calling another method of the same instance the this keyword is used to indicate the current object instance.

But this overlooks the case where an instantiation declaration is used inside an object initializer block. According to the P4 grammar, instantiation may be used inside an object initializer block.

objDeclaration
    : functionDeclaration
    | instantiation
    ;

virtual2.p4 illustrates its use case.

extern Virtual {
    Virtual();
    void run(in bit<16> ix);
    @synchronous(run) abstract bit<16> f(in bit<16> ix);
}
extern State {
    State(int<16> size);
    bit<16> get(in bit<16> index);
}
...
Virtual() cntr = {
    State(16s1024) state;
    bit<16> f(in bit<16> ix) {
        return state.get(ix);
    }
};

Notice that f uses state in its implementation.

Strictly applying what is written in the spec, the program should not typecheck, since f refers to an identifier state that is neither in the top-level scope or the parameter list. i.e., the current spec syntactically allows instantiation inside object initializer but semantically disallows any way to refer to the instantiated instance.

So, I believe the spec should make clear that the scope of abstract methods is: the supplied arguments, values that are in the top-level scope, or instances in the object initializer.

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

1 participant