This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: CLEANUP_POINT_EXPR/WITH_CLEANUP_EXPR vs TRY_CATCH_EXPR


> 
> 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.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]