From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id CAA18789; Sat, 28 Aug 2004 02:20:58 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id CAA18643 for ; Sat, 28 Aug 2004 02:20:57 +0200 (MET DST) Received: from invasion.mail.pas.earthlink.net (invasion.mail.pas.earthlink.net [207.217.120.254]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id i7S0Kuq0007739 for ; Sat, 28 Aug 2004 02:20:57 +0200 Received: from 168-103-58-53.tcsn.qwest.net ([168.103.58.53] helo=dylan) by invasion.mail.pas.earthlink.net with asmtp (Exim 4.34) id 1C0qxk-0002s1-5h; Fri, 27 Aug 2004 17:20:56 -0700 Message-ID: <001901c48c95$25df1850$0201000a@dylan> From: "David McClain" To: "Brian Hurt" Cc: References: Subject: Re: [Caml-list] C++ Throws Date: Fri, 27 Aug 2004 17:22:40 -0700 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0016_01C48C5A.74ABFBF0" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1437 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1441 X-ELNK-Trace: 7a0ab3eafc8cf994b22988ad1c62733440683398e744b8a476619b0acb65782bb139a42063d7a194387f7b89c61deb1d350badd9bab72f9c350badd9bab72f9c X-Originating-IP: 168.103.58.53 X-Miltered: at concorde with ID 412FCFE8.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Loop: caml-list@inria.fr X-Spam: no; 0.00; mcclain:01 dmcclain:01 caml-list:01 generic:01 closures:01 alas:01 camlparam:01 extern:01 blit:01 val:01 val:01 blit:01 mcclain:01 caml-list:01 2004:99 X-Attachments: type="application/octet-stream" name="TClosure.h" name="TClosure.h" Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk This is a multi-part message in MIME format. ------=_NextPart_000_0016_01C48C5A.74ABFBF0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit The main reason I was looking for a higher level generic mechanism for catching C++ throws is the desparate lack of functional closures in C++. If there were such a thing, then it would easy to wrap all the lower level calls in a safe try-catch block which has the closure passed to it... Alas, I sat down and invented a poor-man's functional closure system for C++, along the lines of CAMLparam1, etc.... The world is welcome to this... (attached) It is intended for use in OCaml C++ interface stubs, hence the use of value parameters in the closure classes. An example of its use is here: // ----------------------------------------------------------- extern "C" void foreign_array_blit_ml_to_f(value varr1, value voff1, value varr2, value voff2, value vnel) { VClosure5(clos, varr1,voff1,varr2,voff2,vnel, { long off1 = Long_val(VClArg(voff1)); long nel = Long_val(VClArg(vnel)); foreign_array fsrc(FOREIGN_DOUBLE, 1, &nel, (void*)((double*)VClArg(varr1) + off1), foreign_array::STATIC); long off2 = Long_val(VClArg(voff2)); foreign_array *pdst = pdata(VClArg(varr2)); array_blit(&fsrc, 0, pdst, off2, nel); }, &varr1); safe_call(clos); } // ----------------------------------------------------------- - DM ----- Original Message ----- From: "Brian Hurt" To: "David McClain" Cc: Sent: Friday, August 27, 2004 16:24 Subject: Re: [Caml-list] C++ Throws > On Fri, 27 Aug 2004, David McClain wrote: > > > I now see that OCaml is not converting anything, per se... Apparently > > when the throw handler detects an unhandled condition it decides to > > call abort(), against which there is no defense. > > I don't know what precisely is going on here, but Ocaml interfaces to C, > which doesn't know anything about exceptions. You might try something > like (sorry, I'm no C++ guru): > > extern "C" value foo(value c); > > value foo(value C) { > /* normal Ocaml wrapper code for C */ > try { > /* exception throwing code for C++. */ > } > with (Exception e) { > /* Translate the C++ exception to an Ocaml exception */ > } > } > > The big difference between a C++ function and C function is the name > mangling. I doubt Ocaml could find a C++ function for linking after it > was name mangled. So the extern "C" tells C++ to not namemangle the > function name. > > There is no way I know of to determine what exceptions a function call > might throw. > > > So there appears to be something relatively complex going on across the > > foreign function interface with OCaml and C. This override is what > > frustrates the attempts to create a generic C++ exception handler. > > I think you also have a C/C++ interface problem (and yes, Virginia, they > do exist). > > -- > "Usenet is like a herd of performing elephants with diarrhea -- massive, > difficult to redirect, awe-inspiring, entertaining, and a source of > mind-boggling amounts of excrement when you least expect it." > - Gene Spafford > Brian > > ------------------- > To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr > Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > ------=_NextPart_000_0016_01C48C5A.74ABFBF0 Content-Type: application/octet-stream; name="TClosure.h" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="TClosure.h" // TClosure.h -- Simulation of Functional Closures in C++=0A= // DM/MCFA 08/04=0A= //=0A= #ifndef __TCLOSURE_H__=0A= #define __TCLOSURE_H__=0A= =0A= extern "C" {=0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= #include =0A= };=0A= =0A= class TClosure=0A= {=0A= public:=0A= TClosure() {};=0A= virtual ~TClosure() {};=0A= =0A= virtual void operator()() =3D 0;=0A= };=0A= =0A= #ifdef __TClosure_Instantiate__=0A= void safe_call(TClosure &closure)=0A= {=0A= try {=0A= closure();=0A= } catch(const char* msg) {=0A= failwith((char*)msg);=0A= }=0A= }=0A= #else=0A= extern void safe_call(TClosure &closure);=0A= #endif=0A= =0A= // ------------------------------------------------=0A= // Internal macros=0A= //=0A= #define __VClosureHead() \=0A= struct closure: public TClosure \=0A= { \=0A= value *m_pparm; \=0A= value m_result; \=0A= closure(value *pparm) \=0A= :m_pparm(pparm) \=0A= {} \=0A= =0A= #define __VClosureArgs1(arg) \=0A= enum {arg};=0A= =0A= #define __VClosureArgs2(arg1,arg2) \=0A= enum {arg1,arg2};=0A= =0A= #define __VClosureArgs3(arg1,arg2,arg3) \=0A= enum {arg1,arg2,arg3};=0A= =0A= #define __VClosureArgs4(arg1,arg2,arg3,arg4) \=0A= enum {arg1,arg2,arg3,arg4};=0A= =0A= #define __VClosureArgs5(arg1,arg2,arg3,arg4,arg5) \=0A= enum {arg1,arg2,arg3,arg4,arg5};=0A= =0A= #define __VClosureTail(name,body,env) \=0A= void operator()() \=0A= { body } \=0A= } name(env);=0A= =0A= // ------------------------------------------------------=0A= // API Level Macros=0A= =0A= #define VClosure(name,body,env) \=0A= __VClosureHead() \=0A= __VClosureTail(name,body,env)=0A= =0A= #define VClosure1(name,arg,body,env) \=0A= __VClosureHead() \=0A= __VClosureArgs1(arg) \=0A= __VClosureTail(name,body,env)=0A= =0A= #define VClosure2(name,arg1,arg2,body,env) \=0A= __VClosureHead() \=0A= __VClosureArgs2(arg1,arg2) \=0A= __VClosureTail(name,body,env)=0A= =0A= #define VClosure3(name,arg1,arg2,arg3,body,env) \=0A= __VClosureHead() \=0A= __VClosureArgs3(arg1,arg2,arg3) \=0A= __VClosureTail(name,body,env)=0A= =0A= #define VClosure4(name,arg1,arg2,arg3,arg4,body,env) \=0A= __VClosureHead() \=0A= __VClosureArgs4(arg1,arg2,arg3,arg4) \=0A= __VClosureTail(name,body,env)=0A= =0A= #define VClosure5(name,arg1,arg2,arg3,arg4,arg5,body,env) \=0A= __VClosureHead() \=0A= __VClosureArgs5(arg1,arg2,arg3,arg4,arg5) \=0A= __VClosureTail(name,body,env)=0A= =0A= #define VClArg(name) m_pparm[name]=0A= #define VClReturn(val) m_result =3D val;=0A= #define VClResult(closure_name) closure_name.m_result=0A= =0A= #endif // __TCLOSURE_H__=0A= =0A= // -- end of TClosure.h -- //=0A= ------=_NextPart_000_0016_01C48C5A.74ABFBF0-- ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners