From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,1888e8caa20a2f2d X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!news4.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newscon06.news.prodigy.com!prodigy.net!newsfeed-00.mathworks.com!nntp.TheWorld.com!not-for-mail From: Robert A Duff Newsgroups: comp.lang.ada Subject: Re: Controlled types and exception safety Date: 02 Dec 2005 18:51:41 -0500 Organization: The World Public Access UNIX, Brookline, MA Message-ID: References: <4opjf.151627$dP1.509433@newsc.telia.net> <6Qvjf.3059$Hk1.2021@newsread1.news.pas.earthlink.net> NNTP-Posting-Host: shell01.theworld.com Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Trace: pcls4.std.com 1133567501 6638 192.74.137.71 (2 Dec 2005 23:51:41 GMT) X-Complaints-To: abuse@TheWorld.com NNTP-Posting-Date: Fri, 2 Dec 2005 23:51:41 +0000 (UTC) User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 Xref: g2news1.google.com comp.lang.ada:6727 Date: 2005-12-02T18:51:41-05:00 List-Id: "Jeffrey R. Carter" writes: > Bj�rn Persson wrote: > > > Can't Maciej's concerns be applied to step 6? What to do about > > exceptions that happen while the new X is being adjusted, after the > > old X has been finalized? > > You can get Storage_Error if Adjust allocates storage. Other sorts of > exceptions should have occurred during the adjustment of the > intermediate object, and so corrected before the assignment to X. > > Storage_Error is a strange beast; there's no guarantee that you can do > anything about it. There may not even be enough storage available to > execute an exception handler. Right. In practise, you can get away with handling Storage_Error, but it's annoying that it is pretty-much impossible to write a handler for Storage_Error in Ada that is guaranteed (portably) correct by the RM. Ada is better than some languages, where a stack overflow can go entirely undetected, and the program just starts overwriting who-knows-what data. But I think I've got a better way, which I would use in my own language design. My idea is that stack overflow is like an abort or a hardware interrupt. An abort is asynchronous with the running code -- it can happen anywhere, even in the middle of "X := Y". If X:=Y can is aborted in the middle, we say that X becomes abnormal -- perhaps its discriminants are nonsensical, so later code can't even determine the size of X. The solution is to have abort-deferred regions -- regions of code where abort can't happen. Inside such a region, you can say X:=Y, and be sure that X is unchanged, or Y is fully copied into it. If somebody attempts to abort in the middle of X:=Y, the abort will take effect at the end, and all is well. Same thing for hardware interrupts -- the solution is to allow (hopefully short) regions of code where interrupts can't interrupt. Stack overflow is asynchronous in the sense that it can happen pretty much anywhere. So in my fictitious language, you can have regions of code where stack overflow can't happen. The compiler is required to calculate (at link time!) a static quantity that is the max stack usage for each procedure, task, and other relevant construct. This quantity is an integer ranging from 0 up to the max size of the address space (System.Memory_Size, in Ada). Calculations use saturating arithmetic. When you enter a no-stack-overflow region, we allocate the max size for that region, and raise Storage_Error if that's not possible. So it's like an abort-deferred or interrupt-deferred region, except that the deferral goes backward in time -- if Storage_Error _might_ be raised in that region, we instead raise it before entering the region. Of course, the code in a no-stack-overflow region can't do stuff that allocates unknown amounts of stack space. If a procedure has a local variable of subtype String, with no compile-time-known bounds, the max size is perhaps 2**31 bytes or so. If a procedure is recursive, the max size is System.Memory_Size. If a procedure makes an indirect call (so it _might_ be recursive), the max size is System.Memory_Size. So you write no-stack-overflow regions with small numbers of known-size locals. But that's OK -- all you want to do is log the error, clean up some things, and return to a more-global point in the program. If the max size for such a region is System.Memory_Size, or close to it, the compiler should at least issue a warning, because at run time, every execution of that thing will raise S_E. Storage_Error also applies to "new", but that seems like an easier problem. The allocator can be "blamed", so heap overflow is not asynchronous like stack overflow. At least, for _explicit_ use of the heap. If the compiler is allocating activation records on the heap or some such, then that's still an issue. - Bob