This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: CLEANUP_POINT_EXPR/WITH_CLEANUP_EXPR vs TRY_CATCH_EXPR
- To: bothner at cygnus dot com (Per Bothner)
- Subject: Re: CLEANUP_POINT_EXPR/WITH_CLEANUP_EXPR vs TRY_CATCH_EXPR
- From: Joe Buck <jbuck at Synopsys dot COM>
- Date: Fri, 18 Dec 98 13:13:04 PST
- Cc: gcc2 at cygnus dot com, egcs at cygnus dot com
>
> I am working on a try-finally type construct. Specifically,
> I am trying to implement the Java synchronized statement.
> This has the form:
> synchronized (OBJ) { BODY }
> It is equivalent to ...
> tmp = OBJ;
> _Jv_MonitorEnter(tmp);
> try {
> BODY
> _Jv_MonitorExit(tmp);
> } catch (...) {
> _Jv_MonitorExit(tmp);
> throw;
> }
In C++ I would write simply
{
Jv_CriticalRegion monitor(OBJ);
BODY;
}
The idea is that Jv_CriticalRegion is a class with a constructor and a
destructor and one member, tmp. The constructor does _Jv_MonitorEnter and
the destructor does _Jv_MonitorExit.
e.g.
class Jv_CriticalRegion {
public:
JvCriticalRegion(Object OBJ) : tmp(OBJ) {
_Jv_MonitorEnter(tmp);
}
~JvCriticalRegion() {
_Jv_MonitorExit(tmp);
private:
Object tmp;
};
The key is that the destructor is always called, whether BODY
exits successfully or it throws an exception.
> So I'm trying to express this using existing gcc tree node types,
> and having no luck. The complications are that the finalization
> expression (this this case _Jv_MonitorExit(tmp)) need to be done
> after any of:
> (a) BODY completes normally.
> (b) there is a return, break, or continue that exits BODY.
> (c) there is an unhandled exception thrown by BODY.
It would seem that the thing to do is to look at how the C++ front
end sets up destructors, and set up your call to _Jv_MonitorExit
in the same way.