LINNIG@eg.csc.ti.COM (Mike Linnig) (06/01/88)
Folks, The following package was compiled with two compilers (DEC Ada and Tartan 1750a Ada). Both allowed the declaration of X. DEC ada complained about the type conversion used for the rep clause in ANOTHER. Assuming one or both is legal, what do they mean??? Mike Linnig, Texase Instruments ------------------------------------------------------------ with SYSTEM; use SYSTEM; package DYNAMIC_ADDR is subtype STUPID is SYSTEM.ADDRESS; function DYNAMIC return STUPID; -- just some function X: INTEGER; for X use at DYNAMIC; -- just what does this mean?? ANOTHER: INTEGER; for ANOTHER USE AT stupid(x); -- I guess we can use x as a pointer -- but is it only evaluated at package elaboration? end DYNAMIC_ADDR;
firth@sei.cmu.edu (Robert Firth) (06/02/88)
In article <8806011944.AA06549@ti.com> LINNIG@eg.csc.ti.COM (Mike Linnig) writes: >Folks, > >The following package was compiled with two compilers (DEC Ada and >Tartan 1750a Ada). Both allowed the declaration of X. DEC ada >complained about the type conversion used for the rep clause >in ANOTHER. >Assuming one or both is legal, what do they mean??? Wow! Yes, both address clauses are legal according to the RM [13.5], which requires a "simple expression" yielding a value of type ADDRESS. Note particularly that the RM does NOT require a static expression! However, the second simple expression - stupid(x) - is not portable. It assumes that INTEGER and ADDRESS are interconvertible, which will be so only if ADDRESS is a numeric type. Evidently it is on the one machine and not on the other. Finally, there is a problem here - there is a reference to the value in X when X in fact has no value. The program is therefore "erroneous", by RM [3.2.1 (17,18)] And what does it "mean"? I've commented the code to show what I think it means. ------------------------------------------------------------ with SYSTEM; use SYSTEM; package DYNAMIC_ADDR is subtype STUPID is SYSTEM.ADDRESS; function DYNAMIC return STUPID; -- just some function X: INTEGER; for X use at DYNAMIC; -- just what does this mean?? -- [RF] call the function DYNAMIC. The return value -- is the address of X. The implementation will -- probably declare a hidden pointer and then -- reference X indirectly through it ANOTHER: INTEGER; for ANOTHER USE AT stupid(x); -- [RF] similarly, fetch the value of X (NOT its address) -- convert that value to an address, and put ANOTHER -- there. Again, this probably means building a -- hidden pointer -- I guess we can use x as a pointer -- but is it only evaluated at package elaboration? -- [RF] the code I'd expect to see: -- declare space for 2 pointers (REFX and REFANOTHER) -- call DYNAMIC -- store return value in REFX -- fetch value of X (ie load indirect through REFX) -- store that value in REFANOTHER end DYNAMIC_ADDR;
rfg@nsc.nsc.com (Ron Guilmette) (06/03/88)
In article <8806011944.AA06549@ti.com> LINNIG@eg.csc.ti.COM (Mike Linnig) writes: >The following package was compiled with two compilers (DEC Ada and >Tartan 1750a Ada). Both allowed the declaration of X. DEC ada >complained about the type conversion used for the rep clause >in ANOTHER. >Assuming one or both is legal, what do they mean??? > > X: INTEGER; > for X use at DYNAMIC; -- just what does this mean?? I have at least a fuzzy (but not warm) feeling as to the meaning of the code shown above, however a very similar construction has disturbed me deeply, to wit: procedure P; for P use at DYNAMIC; For a true embedded system, I can understand that one may want to fix certain routines at certain places via: procedure P; for P use at STATIC; However I cannot envision any case in which dynamic relocation of routines WHILE THE PROGRAM IS RUNNING would be of any benefit. I can however predict that such a capability might be an implementor's nightmare. Note that 13.5(5) seem to allow (and now perhaps require?) such a capability in all implementations! Wow! -- // Ron Guilmette // C++ is nice, -- National SemiConductor -- Ada keeps my wallet happy, ?? rfg@nsc.nsc.com ?? but there has got to be something better...
markb@sdcrdcf.UUCP (06/03/88)
In article <5140@nsc.nsc.com> rfg@nsc.UUCP (Ron Guilmette) writes:
<... however a very similar construction has disturbed me deeply,
<to wit:
< procedure P;
< for P use at DYNAMIC;
<For a true embedded system, I can understand that one may want to fix certain
<routines at certain places via:
< procedure P;
< for P use at STATIC;
<However I cannot envision any case in which dynamic relocation of routines
<WHILE THE PROGRAM IS RUNNING would be of any benefit. I can however
<predict that such a capability might be an implementor's nightmare.
<Note that 13.5(5) seem to allow (and now perhaps require?) such a
<capability in all implementations! Wow!
A good reason to allow this is multic-like dymanic procedure linking.
A side effect of the routine DYMANIC may be to load the code you wish
to run via the name P into memory and then return its address.
Mark Biggar
{allegra,burdvax,cbosgd,hplabs,ihnp4,akgua,sdcsvax}!sdcrdcf!markb
markb@rdcf.sm.unisys.com
daveb@geac.UUCP (David Collier-Brown) (06/06/88)
| In article <8806011944.AA06549@ti.com> LINNIG@eg.csc.ti.COM (Mike Linnig) writes: | ... | X: INTEGER; | for X use at DYNAMIC; -- just what does this mean?? In article <5140@nsc.nsc.com> rfg@nsc.UUCP (Ron Guilmette) writes: | I have at least a fuzzy (but not warm) feeling as to the meaning of the code | shown above, however a very similar construction has disturbed me deeply, | to wit: | | procedure P; | for P use at DYNAMIC; | | For a true embedded system, I can understand that one may want to fix certain | routines at certain places via: | | procedure P; | for P use at STATIC; | | However I cannot envision any case in which dynamic relocation of routines | WHILE THE PROGRAM IS RUNNING would be of any benefit. I can however | predict that such a capability might be an implementor's nightmare. Well, I can suggest two cases where relocation of routines which is transparent to the program may be of use: 1) shared libraries 2) replacement chipsets Both are really variants of the same thing, a piece of code which may be replaced at run-time, either because its at a different address than it was at link-time, or because it had to be replaced due to an error. I'm personally attracted to the replacement-of-chips argument, since one might want to replace one of a large number of ROM chips in the field. And not replace the whole set or board. In a non-embedded system, dynamic replacement is a long-term maintenance win, as the Multicians found many moons ago. --dave (Ichbiah was a Multician) c-b ps: This is notably better than the procedure-pointer quasi-kludge of PL/1, B and C. -- David Collier-Brown. {mnetor yunexus utgpu}!geac!daveb Geac Computers Ltd., | "His Majesty made you a major 350 Steelcase Road, | because he believed you would Markham, Ontario. | know when not to obey his orders"
rfg@nsc.nsc.com (Ron Guilmette) (06/09/88)
Regarding the use of: procedure P; for P use at DYNAMIC; In article <2817@geac.UUCP> daveb@geac.UUCP (David Collier-Brown) writes: > > Well, I can suggest two cases where relocation of routines which >is transparent to the program may be of use: > 1) shared libraries > 2) replacement chipsets > Both are really variants of the same thing, a piece of code which >may be replaced at run-time, either because its at a different >address than it was at link-time, or because it had to be replaced >due to an error. I'm sorry, but I have to say that the above statements don't really address my initial concerns. First, note that the EXPLICIT use of the address clause implies very clearly that whatever is happening is not "transparent" to the user's program, but rather that the program must actively participate in defining (or using) the "effects" which are to occur. Second, I believe that my original posting asked why it would ever be of any value to use a dynamic address clause for a procedure. Just saying that the procedure is at a different address than it was at link time begs the question. Why is it at a different address? Under what circum- stances whould it be useful for the procedure to be "at" a different (program-specified) address? I don't think that shared-libraries are a case worth considering because any reasonable linker should know about such things and should, in fact, make their usage truly transparent to the program. The possibility of using dynamic procedure address clauses to simply route calls around defective and or outdated RAM/ROM versions of the procedures involved sounds like a plausable use for this language "feature", however such usage conflicts directly with my initial assumptions regarding the intended semantics of dynamic address clauses for procedures. The question I would now like to pose to the comp.lang.ada readers is this: "Should a dynamic address clause for a procedure be considered to be simply a DECLARATIVE statement (i.e. the procedure ALREADY resides here) or should it be considered to be an EXECUTABLE statement (i.e. PUT the procedure code at this location, regardless of where it currently resides)?" I have been assuming the latter interpretation. What do y'all think?
stt@ada-uts (06/10/88)
I have always presumed address clauses were directives to the compiler or the linker, but certainly not to the run-time system. The interpretation of the specified address is implementation-dependent, including whether it is accepted. The fact that simple_expression is allowed rather than simply a literal is simply to allow some freedom to the implementation, but in no way requires that dynamic address clauses be supported. As a compiler implementor one certainly has the freedom to define address clauses as one sees fit, but if this discussion is aimed at gaining a consensus as to the "normal" or "standard" interpretation of address clauses, I would expect them to be limited to expressions which can be evaluated at or before link-time. For example, one might allow the sum of the address of one unit and an offset for the address of a second unit. To me it seems kind of pointless to try and figure out a meaning for an address expression which will probably never be accepted by an Ada compiler. S. Tucker Taft Intermetrics, Inc. Cambridge, MA 02138
jmoody@DCA-EMS.ARPA (Jim Moody, DCA C342) (06/10/88)
Ron Guilmette writes:
'Regarding the use of:
procedure P;
for P use at DYNAMIC;
First, note that the EXPLICIT use of the address clause implies very clearly
that whatever is happening is not "transparent" to the user's program, but
rather that the program must actively participate in defining (or using)
the "effects" which are to occur.
. . .
The question I would now like to pose to the comp.lang.ada readers is this:
"Should a dynamic address clause for a procedure be considered to be simply
a DECLARATIVE statement (i.e. the procedure ALREADY resides here) or should
it be considered to be an EXECUTABLE statement (i.e. PUT the procedure code
at this location, regardless of where it currently resides)?"
I have been assuming the latter interpretation. What do y'all think?'
We have to distinguish two cases. The first is what, I think, everyone else
who has been writing about this problem is assuming. Let me put the code
fragment in a full setting.
With System;
Package ExternalRelocatedProcedure is
Procedure P(A: in out ArgumentType);
Private
Function Dynamic return System.Address;
Pragma Interface (Assembler, Dynamic);
Pragma Interface (Assembler, P);
For P use at Dynamic;
End ExternalRelocatedProcedure;
In this case, the rep spec is purely declarative. It tells the compiler that
there is some procedure which can be called, how to call it and how to find out
where it will be at run time. This is presumably how replacement chip sets
would be handled. Note that the user of P does not explicitly use the rep
spec, the implementer of P does.
The second and more problematical case is the one that Ron Guilmette is
concerned about. This is the case where a subprogram body is given together
with an address clause, thus:
Procedure P is
X,Y : SomeVariableType;
begin
DoSomething;
DoSomethingMore;
end P;
For P use at Dynamic;
It is not at all clear to me what this case requires of the implementation. I
cannot envisage how such a declaration might be used, but that may simply be my
failure. My best guess is the following. 13.5(5) requires that Dynamic be
"the address required for the machine code associated with the body of" P,
which begs a lot of questions. There is nothing in the LRM which requires
implementations to generate compact code for a subprogram body. An
implementation is, I assume, free to disperse a subprogram body all over
memory, an instruction followed by a jump to an instruction followed by a jump
to an instruction . . . . That this is an unlikely implementation is agreed,
but what its possibility implies is that the address clause does not require
relocation of the machine code associated with the body of P. It is enough, I
think, that the implementation place, at the address returned by Dynamic, a
jump to the beginning of the machine code associated with the body of P. This
makes it an executable statement (not a purely declarative one), but its
execution asks a lot less of the implementation than Ron Guilmette assumed.
hyland@esosun.UUCP (Steve Hyland) (06/11/88)
In article <5151@nsc.nsc.com> rfg@nsc.UUCP (Ron Guilmette) writes: >Regarding the use of: > > for P use at DYNAMIC; > >any value to use a dynamic address clause for a procedure. Just saying >that the procedure is at a different address than it was at link time >begs the question. Why is it at a different address? Under what circum- >stances whould it be useful for the procedure to be "at" a different >(program-specified) address? > Actually, I can think of an additional usage for this. In my X Toolkit, I will allow the programmer the flexibility of associating specific procedures, "Call Backs", to be executed whenever a toolkit widget such as a scroll bar is moved. The compiler will handle the association between the call back and the widget. However, there are situations where application USERS may wish to change these association dynamically, say by causing a different call back to be executed when the scroll bar is moved. Dynamic address clauses would allow me to associate a different call back in this way. I won't argue whether this is considered good or bad programming. Something this flexible should be used, albeit carefully. Steve Hyland
daveb@geac.UUCP (David Collier-Brown) (06/15/88)
Regarding the use of: procedure P; for P use at DYNAMIC; In article <2817@geac.UUCP> daveb@geac.UUCP (David Collier-Brown) writes: || || Well, I can suggest two cases where relocation of procedures which || is transparent to the program may be of use: ^^^^^^^^^^^ In article <5151@nsc.nsc.com> rfg@nsc.UUCP (Ron Guilmette) writes: | First, note that the EXPLICIT use of the address clause implies very clearly | that whatever is happening is not "transparent" to the user's program, but | rather that the program must actively participate in defining (or using) | the "effects" which are to occur. OOPS! I used "transparent" ambiguously. What I really meant was that the the address to use is marked as unusual only at one place, and that the **programmer** can regard its relocation as occurring transparently at runtime. This is in contrast to "C", where relocation is done explicitly and obviously at every reference to or call to the procedure: int (*the_fcn_pointer)(); ... the_fcn_pointer = dynamic(); ... i = (*the_fcn_pointer)(is,somewhat,visible); What I should have said is that it meets modern maintainability standards, not that it was transparent (save in a trivial sense). | The question I would now like to pose to the comp.lang.ada readers is this: | "Should a dynamic address clause for a procedure be considered to be simply | a DECLARATIVE statement (i.e. the procedure ALREADY resides here) or should | it be considered to be an EXECUTABLE statement (i.e. PUT the procedure code | at this location, regardless of where it currently resides)?" | I have been assuming the latter interpretation. What do y'all think? If it was a simple variable, what would the "use at" clause mean? Should this be the same for a procedure? I **think** its declarative... --dave -- David Collier-Brown. {mnetor yunexus utgpu}!geac!daveb Geac Computers Ltd., | "His Majesty made you a major 350 Steelcase Road, | because he believed you would Markham, Ontario. | know when not to obey his orders"
bseymour@potpourri.UUCP (Burch Seymour) (06/15/88)
in article <8806011944.AA06549@ti.com>, LINNIG@eg.csc.ti.COM (Mike Linnig) says: > with SYSTEM; > use SYSTEM; > package DYNAMIC_ADDR is > subtype STUPID is SYSTEM.ADDRESS; > > function DYNAMIC return STUPID; -- just some function > > X: INTEGER; > for X use at DYNAMIC; -- just what does this mean?? What this does on our compiler (Telesoft Telegen II - Gould version) is call function DYNAMIC and store the returned value into X. This is done during the elaboration of the specification of package DYNAMIC_ADDR. Later references to X do not call the function, just use the current value of X. > ANOTHER: INTEGER; > for ANOTHER USE AT stupid(x); > -- this compiles on one compiler and gets illegal conversion type > -- on another one. Why? According to type conversion rules (see LRM section 4.6.8), the operand and target types must be related. The type system.address is implementation specific (LRM 13.7). Some compilers just derive system.address from integer. In this case you can convert integer to address without using unchecked conversion since they have the same base type. On others this is not true and the conversion is illegal. That's why this works on some compilers and not on others. -Burch Seymour- Gould CSD Ft Lauderdale, Fla =====================================================================
rfg@nsc.nsc.com (Ron Guilmette) (06/16/88)
In article <57900075@ada-uts> stt@ada-uts writes: > >To me it seems kind of pointless to try and figure out a meaning >for an address expression which will probably never be accepted by >an Ada compiler. Granted, but it is my understanding that the new rules of the Ada implementa- tion game require the implementation of all of Chapter 13, unless the implementor can show (I guess to the AVF) that certain parts are not realistic for a given hardware/OS configuration. (The traditional example is, I believe, that it is OK not to supply TEXT_IO for a SBC which has only 8 segment led's for output devices.) I have seen the LMC ruling which states this. I can't think of any hardware feature (or lack thereof) which would make the implementation of dynamic address clauses for subprograms unrealistic, so I guess that EVERYBODY will have to start implementing them SOMEHOW! This is exactly the point I really started out to make; i.e. that ALL Ada implementors should be scared s---less that ACVC 1.11... 1.12... or whatever will actually TEST for this! I hope that we can get 13.5(5) nixed before it comes to that. -- Ron Guilmette National SemiConductor Internet: rfg@nsc.nsc.com Uucp: ...{pyramid,sun,amdahl,apple}!nsc!rfg
dee%linus@MITRE-BEDFORD.ARPA (David E. Emery) (06/16/88)
Here's a very legitimate use for a dynamic address clause: C often returns addresses of objects (becaues C functions cannot return structures). The following should be perfectly legal AND ACCEPTABLE (i.e. compilers should support this): Ada C type rec is record struct rec { foo : integer; int foo; bar : integer; int bar; end record; }; rec *getstuff(); function getstuff return system.address; pragma interface (C, getstuff); declare myrec : rec; for myrec use at getstuff; -- function call returns system.address. fooval, barval : integer; begin fooval := myrec.foo; barval := myrec.bar; end; Obviously, if address clauses were restricted to be static, this wouldn't work. They're not, so this should be just fine. I've tried this technique on Verdix/Sun, and it works just fine. dave emery emery@mitre-bedford.arpa
ok@quintus.uucp (Richard A. O'Keefe) (06/17/88)
In article <8806161353.AA17815@linus.MENET> dee%linus@MITRE-BEDFORD.ARPA (David E. Emery) writes: >Here's a very legitimate use for a dynamic address clause: C often >returns addresses of objects (becaues C functions cannot return >structures). (a) That isn't true; since the days of V7 UNIX C has been able to return records. (There are known problems with the implementation used by some compilers, but the facility is present in the language.) struct results and struct assignment are in the draft ANSI standard. (b) In any case, why not simply return an access value? Are ADA access values required to carry around more information than C pointers?