Language Change Specification for Allow Protected Type Method Parameters to be Access Types, Protected Types (functions), and File Types

LCS Number: LCS-2016-004 History
Version: 2 {28-Jan-2017}
1 {08-Jan-2017}
Date: 08-Jan-2017
Status: Voting
Author: Jim Lewis
Email: Main.JimLewis
Source Doc: Method with AT and FT parms
Summary: Allow Protected Type Method Parameters to be Access Types, Protected Types (functions), and File Types
Full HTML Link

Voting Results: Cast your votes here

Yes:

  1. Jim Lewis - 2017-01-28 ver 2
  2. Farrell Ostler - 2014-01-17 ver 1
  3. Rob Gaddi - 2017-01-26 ver 1
  4. Lieven Lemiengre - 2017-01-27 ver 1 - (changed to version 1 by MartinZabel as there is no version 4)
  5. Hendrik Eeckhaut - 2017-01-27 ver 1 - (changed to version 1 by MartinZabel as there is no version 4)
  6. Martin Zabel - 2017-01-30 ver 2

No:

Abstain:

  1. Kevin Jennings - 2017-2-9 - Ver 2
  2. Brent Hayhoe - 2017-02-16 Version 2 - Abstain due to lack of personal time for review.

Revision Notes

Version 2:

  • Changed the last edit from a note to a regular paragraph.
  • Changed the text of the above paragraph in an attempt to remove ambiguity.

Relevant sections of the LRM

Parameter Interface - 4 PT Declarations - 5 Inteface Declarations - 6

Only relevant sections found in 5.6.2

Comments

Should we allow return types that are access types?

-- Jim Lewis - 2017-01-09

If it's possible, yes.

-- Patrick Lehmann - 2017-01-09

I favor this proposal to allow protected types and file types as parameters to the methods of a protected type, including allowing function methods to return them. (Return values are essentially out parameters.)

I do NOT favor the restrictions introduced in the "Note at bottom of page 58" (Note 1). First, I believe there are use cases that would be acceptable practice but would run afoul of the restrictions and, second, enforcement of the restrictions would be a burden to the VHDL tool and probably not even reliably possible.

-- Farrell Ostler - 2017-01-18

@FO1: Neither protected types and file types allow assignment. Hence, having a return value of PT or FT implies you are assigning it to something, which is not supported. OTOH, a out parameter associates a given object of PT or FT to something which is allowed - but following already established rules for procedures, a PT is always an inout.

@FO2: Allowing a pointer to point to an object that is internal to a protected type breaks all protection mechanisms. This would be a bad programming practice. If I had made it an ERROR the tool would be required to check for it and signal an ERROR if it happened. Making it ERRONEOUS on the other hand makes it illegal and if the tool detects it, it is permitted to signal an error. OTOH, if a tool does not have the capability to detect it, that is ok too.

Note the usage of ERROR and ERRONEOUS are an already established convention in the LRM.

-- Jim Lewis - 2017-01-21

Just for the record:

I don't like "NOTE 1", I don't think tools can enforce this rule so they will just allow it. Honestly I think it's a silly restriction if it can't be enforced. Still voting YES, this LCS will achieve it's goals.

-- Lieven Lemiengre - 2017-01-27

I have some questions about NOTE 1 which should be added at the bottom of page 58.

1) "It is erroneous to pass an object of an access type to a method and later, external to the protected type, use the object of the access type to access internals of the protected type."

Can you give an example of such a usage? How should the outer object (which is passed to the method) know something about the internals of the protected type?

2) "It is erroneous for a protected type to return an access typed value that references an object that is internal to the protected type."

If the object is explicitly declared within the protected type, then you cannot return a reference to it unless LCS-2016-014b is approved. And I hope, it will never be approved.

If the object is allocated within a method of the protected type, why should it not be returned?

-- Martin Zabel - 2017-01-28

In the following I have put in edits to correctly LCS_2016_014a when I referenced LCS_2016_14b.

@MZ.1 "It is erroneous to pass an object of an access type to a method and later, external to the protected type, use the object of the access type to access internals of the protected type." In general this means that a PT shall make a copy of the items pointed to by the AT before storing them. OTOH, if the AT is not created by a user program, but instead is created by a program called by a user program that passes an AT to the PT, the AT may not have a life time beyond storing a reference to it in the PT, so this use model may be considered to be ok - more correctly if we eventually introduce private types, if the helper function provided a pointer to the private type, then it would definitely be ok as there would be no way for the user program to create an object of the type.

@MZ.2B "If the object is explicitly declared within the protected type, then you cannot return a reference to it unless LCS-2016-014b is approved. And I hope, it will never be approved." Your assertion about 14b is incorrect. PT bodies allows variables of ordinary types, including an AT - for an example, see MemoryPkg.

You will need to address 014b issues there.

@MZ.2A "It is erroneous for a protected type to return an access typed value that references an object that is internal to the protected type." Hence, what this says is a PT may not pass a pointer to an internal object to the outside. Currently everything created in a package body and a protected type body is considered to be private.

OTOH, it may create an AT, copy things into it, and then return that - ie: it can return a ragged array, or with LCS_2016_014a 014b, it can do a deep copy of the current PT and return a pointer to that.

@MZ.2C "If the object is allocated within a method of the protected type, why should it not be returned? " PTs only allow one method of a given type to be running at a time. Hence, it provides mutual exclusive access to an internal object. If we handed out pointers to the private objects inside the PT, it would no longer be reasonable for the language to guarantee that.

Without LCS_2016_014a LCS_2016_014b, one cannot dynamically size a structure based on a PT. I see a PT as an testbench data structure creating item. As such it is important to me.

Currently in ScoreboardGenericPkg, I emulate arrays of scoreboards internally - it makes for more complicated than necessary programming. I never want to do this again. The current methodology allows scoreboards to be dynamically sized. However, perhaps this is not necessary.

Maybe arrays of PT are enough. Maybe arrays of PT plus generics on the PT interface are enough. Perhaps I don't need LCS_2016_014a (or LCS_2016_014b either) as much as I thought. I sure have an aversion to writing the part about "new" and variables.

OTOH, to do a deep copy of a PT, you need a pointer to a PT, or the ability to assign one PT to another. For a PT, currently the object is not the object, but a reference to it. Hence, it is as much like a pointer as you can be without being a pointer - the big thing missing from PT currently is the ability to assign one to another - which would be allowed with pointers to PT.

-- Jim Lewis - 2017-01-28

@JimLewis: It seems that my understanding of a PT differs much from your view. Let me explain my view which is, of course, inspired by object-oriented programming with Java and C++.

The LRM defines a PT as: "A protected type implements instantiatiable regions of sequential statements, each of which are guaranteed exclusive access to shared data. Shared data is a set of variable objects that may be potentially accessed as a unit by multiple processes."

1) From my view, the shared data only includes the objects which are declared in the body of the PT. Especially, if such an object is of an AT, then only the access value is shared data, not the object which is designated by the access value. This view has a lot of implications:

2) JL: "Currently everything created in a package body and a protected type body is considered to be private."

Here is the main difference between my view and your view, see above.

3) JL "PTs only allow one method of a given type to be running at a time. Hence, it provides mutual exclusive access to an internal object. If we handed out pointers to the private objects inside the PT, it would no longer be reasonable for the language to guarantee that."

Without 014b, you cannot hand out pointers to the declared objects of the PT, and in my view, mutual exclusive access only applies to the declared objects.

And also 014b cannot allow to hand-out pointers to the declared objects of the PT because this cannot be (easily) tracked by a garbage collector.

4) JL: "PT bodies allows variables of ordinary types, including an AT - for an example, see MemoryPkg"

No problem with AT in PT. And regarding the MemoryPkg, if you want to keep the internal representation private, then just do not hand out a pointer.

And if you do not hand-out them, then you will also have no problems with concurrent access: within the MemoryPType for example, all accesses to ArrayPtrVar will be mutually exclusive, and so will be the access to the designated MemArrayType array, as well as the MemBlockPtrType array elements, as well as the MemBlockType objects designated by the array elements, and so on --- in your view and also in my view (if you do not hand-out a pointer).

And if you do hand-out a pointer, then you explicitly declare the designated object for public use.

5) JL: "[...] if the AT is not created by a user program, but instead is created by a program called by a user program that passes an AT to the PT, the AT may not have a life time beyond storing a reference to it in the PT [..]"

This will be ensured by LCS-2016-30 "Garbage Collection". There is also no need to copy the object pointed to by the parameter of an AT in a method call because the designated object is not considered as shared data.

Further remarks:

6) JL: "Without LCS_2016_014b, one cannot dynamically size a structure based on a PT."

014b is not required for dynamically sizeable structures. You already have done it in ScoreboardGenericPkg. And I do not see, how 014b can simplify this task. You can provide a use case on that LCS if you like.

7) JL: "the big thing missing from PT currently is the ability to assign one to another - which would be allowed with pointers to PT."

I definitely agree with that, and I already commented on 014a. Furthermore, I would have allowed only allocated objects of PT back in 2008, this would have simplified a lot of things. But I was not a port of the working group then.

-- Martin Zabel - 2017-01-28

@MZ. Thanks. 1) First I confused 014b with 014a. I edited my previous comments to change 14a to 14b (with red and strike outs) as it was incorrect and confusing to let it remain as it was..

2) Based on your comments and others, I changed note 1 to regular text and revised the wording to better match my intent.

@MZ.1 - @MZ.5 This LCS intends to make it erroneous if after a method completes a pointer inside the PT and a pointer outside the PT reference the same object. The sole intent of pointer exchange is to pass a ragged array or do a deep copy of a PT. When returning a pointer, the PT implementation must make sure it does not maintain a reference to the object it returns. When receiving a pointer, the PT implementation either copy the object or that it knows that another copy to the object does not exist. In OSVVM, we do the following:

    Cov.AddBins(GenBin(0, 1, 1)) ; 
There are places where I would like GenBin to be able to return a ragged array - specifically when a coverage bin is to hold something that is not a contiguous set, such as the values 1, 3, 5, 7 rather than a set that is 1 to 7. The only way to return ragged arrays is through the use of pointers. A user could foul this up by creating their own set without using GenBin. Currently we cannot prevent this, however, if the data object returned by GenBin were a private type, we could. Maybe we will add this additional level of security in the revision after 2017.

@MZ.4 "And if you do hand-out a pointer, then you explicitly declare the designated object for public use." Prior to this LCS, the language forbid this. Hence, the prior to this point, a PT provided mutual exclusive access to items internal to the PT, whether they are of a regular type or an access type.

I know of at least one person (our editor) who would negative ballot this if we allowed any public access to an object declared in or referenced (directly or indirectly) by an object declared in a PT. Perhaps we can consider something like that on a future revision, but I we need to get this version balloted as easily as possible to be able to meet our deadlines.

@MZ.6 You are correct. I confused 014a with 014b.

@MZ.7 PTs were added in 2000 and then refined in 2002.

-- Jim Lewis - 2017-01-29

@Jim: I can live with your view and the new paragraph at bottom of page 58.

Note that the new restrictions imply that if an access value (AV) to a data object is passed as a parameter to a method of a PT and this access value should be stored in the PT, then the AV must be passed with mode inout and set to null by the method.

type AT is access SOME_TYPE;

type PT is protected body
   procedure p(av : inout AT) is
   begin
      save := av;  -- save AV in PT
      av := null;    -- clears external reference
   end procedure;
end protected body;

-- Martin Zabel - 2017-01-30

@MZ. I see 3 scenarios: 1) As you elaborated above and set the outbound pointer to null. 2) As I elaborated above, where a helper function creates the pointer and there is no external variable holding the pointer. This is likely to require additional updates as it implies the pointer needs to be passed as a constant parameter. 3) External program needs to keep a copy of the object, so the PT does a deep copy of the referenced object.

-- Jim Lewis - 2017-01-30

Topic revision: r1 - 2017-07-16 - 19:00:44 - JimLewis
 
Copyright © 2008-2021 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback