home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!ukma!usenet.ins.cwru.edu!agate!ucbvax!lrw.com!leichter
- From: leichter@lrw.com (Jerry Leichter)
- Newsgroups: comp.os.vms
- Subject: Re: VAXC divide problems (V3.2)
- Message-ID: <9301280442.AA02004@uu3.psi.com>
- Date: 28 Jan 93 03:41:13 GMT
- Sender: daemon@ucbvax.BERKELEY.EDU
- Distribution: world
- Organization: The Internet
- Lines: 126
-
-
- >>Gruesome details are available in the CRTL portion of the VMS
- >>listings. This ugly violation of the VMS Procedure Calling Standard
-
- > In what way is this a violation of the Procedure Calling Standard?
- > It is perfectly legitimate for a procedure to reserve space on the
- > stack for data of local interest; nothing says that that space has
- > to correspond to variables visible to the user.
-
- That won't wash. The violation is in VAXC$ESTABLISH, which will
- clobber the top of your stack if you haven't allocated the
- undocumented hidden variable for it. It mungs its _caller's_ stack;
- that's completely different from extra stack space being used by the
- current procedure.
-
- Alternatively, your own code can clobber the saved handler address,
-
- Your own code cannot touch the saved handler address unless it uses and
- invalid pointer. It could just as easily clobber the handler address at
- (FP).
-
- which in turn can result in an ACCVIO inside VAXCRTL for non-longjmp
- conditions. The documentation for VAXC$ESTABLISH states that it is
- only usable from code compiled by VAX C because that particular
- compiler allocates stack space for its use, but it still violates the
- procedure calling standard.
-
- It is perfectly legitimate for a procedure in a language support RTL to make
- assumptions about the environment compiled code will set up for it. Try
- calling one of the routines that implements formatted I/O in FORTRAN without
- setting up the appropriate environment.
-
- LIB$ESTABLISH also modifies its caller's stack frame. In fact, the only
- difference between LIB$ESTABLISH and VAXC$ESTABLISH is in the addressing
- mode of one instruction. Do you also claim that LIB$ESTABLISH is in violation
- of the Standard?
-
- In many languages, you NEVER call language support RTL routines directly;
- the compiler generates all the calls. In C, because of its extreme low level,
- just about all calls have to be visible to the user.
-
- Calling internal FORTRAN support routines is not supported, except in code
- generated by the FORTRAN compiler. (That's not to say it can't be made to
- work.) Calling VAXC$ESTABLISH is not supported outside of code generated by
- the VAX C compiler (although again it can be made to work). I see no signi-
- ficant difference, and I see no violation of the calling standard. Would it
- have made you happier if, instead of a documented VAXC$ESTABLISH routine,
- VAX C had defined a new statement, say establish <handler>, which turned into
- just such a call?
-
- > It is perfectly permissible for a condition
- > handler to make calls to other procedures, basing its choices on
- > locally available data. That's just what this condition handler is
- > doing; it's no different, in principle, from having a local variable
- > that indicates what you were trying to do, and a condition handler
- > that checks that variable to decide what furtheraction to take.
-
- That would be true if such usage didn't interfere with user code.
- Try calling VAXC$ESTABLISH from code compiled by some other compiler
- sometime (recent releases of GCC excepted), then tell me that it isn't
- violating the procedure calling standard.
-
- Try calling the Ada RTL routines that manage tasking from some code written in
- some other language. In fact, I'll bet that if you name any language RTL, I
- can find some routine in it that, if called from another language, will cause
- quick failure. So?
-
- As for GCC: It's really too damn bad for GCC that, when it tries to make use
- of the VAX C RTL, it has to play by the rules. The VAX C RTL was written to
- support the VAX C compiler. It owes absolutely nothing to the writers of
- GCC.
-
- >>is for setjmp/longjmp handling, and is inherited from the Pascal
- >>compiler of all places! ...
-
- > Actually, I think it's the BASIC compiler (which had to pull the
- > same kind of trick to implement its user error handling).
-
- My post was not based on speculation; check the source listings.
- They took the implementation from Pascal's GOTO handler. Perhaps the
- Pascal implementation was derived from BASIC's, but if so, the C code
- doesn't mention it.
-
- What can I tell you; my understanding was that the technique of using stack
- unwinding as it is done in VAX C was first developed for BASIC. Good
- solutions to hard problems get re-used. BASIC's needs are somewhat different,
- so I can't say I'm shocked that the actual code came from Pascal.
-
- Look, let's back off and look at the bigger picture for a moment. The C
- language brings with it two features - well, one is just a common abuse of
- the language - that are in and of themselves incompatible with the VAX
- Procedure Calling standard:
-
- 1. Functions view their arguments as a block of successive values
- which they can step through - and modify. Without the
- overhead of copying values around, this results in generated
- code that modifies the values pointed to by AP, a practice
- once strictly prohibited by the Calling Standard: That data
- belongs exclusively to the caller. A field test version of
- VAX C (I think V3.0) tried to obey the calling standard
- strictly: When the address of any argument was taken, the
- argument was re-bound to a new stack location, and the value
- passed in the argument block was copied on procedure entry.
- Such an implementation is completely consistent with both
- K&R and ANSI C, as well as with the Standard. However, so
- many customers objected that it broke their code that the
- change was backed out before the final version of the compiler
- and never tried again. Instead, VAX C was given a waiver
- from this requirement of the Standard. It causes grief for
- mixed FORTRAN/C programs to this day.
-
- 2. setjmp/longjmp simply cannot be implemented strictly within the
- Calling Standard. The old "just pop the stack pointer back
- to where it was" approach is absolutely a violation.
-
- Rather than bitch about the "horrible" way this is done, would
- you like to suggest an implementation that will (a) conform
- to the ANSI definition; (b) conform to the Procedure Calling
- Standard; (c) behave rationally in a mixed language environ-
- ment, where there may be stack frames for code created by
- several different compilers arbitrarily mixed on the stack
- between the frame where the longjmp takes place and the frame
- it will end up in? If you can, I, for one, would be quite
- interested in seeing it.
- -- Jerry
-
-