[m-rev.] for review: implement det exceptions on the .NET backend.
Peter Ross
peter.ross at miscrit.be
Fri Aug 24 22:40:05 AEST 2001
On Thu, Aug 23, 2001 at 06:42:03PM +0200, Tyson Dowd wrote:
> Hi,
>
>
> ===================================================================
>
>
> Estimated hours taken: 16
> Branches: main
>
> Implement exceptions in the .NET backend.
> (sorry, model_det exceptions only at the moment).
>
> compiler/mlds_to_il.m:
> Wrap two exception handlers around the Mercury code -- one that
> prints out any uncaught user exceptions using
> ML_report_uncaught_exception, and one that catches any system
> exceptions and prints them using the system exception printing
> mechanism.
>
I think it would be nice to make clearer that a user exception is an
exception that the Mercury runtime system understands and a system
exception is any other exception.
> library/exception.m:
> Implement exceptions in C#.
> try and catch call try_impl and catch_impl, which by default
> call builtin_trd and builtin_catch, but we provide a
> foreign_proc definition that implements them in C# on the .NET
> backend.
> We also implement ML_call_goal in Mercury, renaming the
> hand-coded versions appropriately.
>
> library/math.m:
> Throw mercury.runtime.SystemException for domain errors.
>
Why?
> runtime/mercury_mcpp.cpp:
> Fix the implementation of mercury.runtime.Exception -- now we
> store the Mercury exception so you can retrieve it later.
>
> Create a new class for Mercury runtime system exceptions, which
> are generated by SORRY and fatal_error. We can't expect to
> print these exceptions using ML_report_uncaught_exception (at
> the moment ML_report_uncaught_exception generates such
> exceptions!) so we print them as normal .NET exceptions instead.
>
>
> Index: compiler/mlds_to_il.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
> retrieving revision 1.77
> diff -u -r1.77 mlds_to_il.m
> --- compiler/mlds_to_il.m 23 Aug 2001 09:28:03 -0000 1.77
> +++ compiler/mlds_to_il.m 23 Aug 2001 16:37:50 -0000
> @@ -990,7 +990,10 @@
> il_info_add_init_instructions(runtime_initialization_instrs),
> ^ has_main := yes,
>
> - il_info_get_next_block_id(TryBlockId),
> + il_info_get_next_block_id(InnerTryBlockId),
> + il_info_get_next_block_id(OuterTryBlockId),
> + il_info_get_next_block_id(InnerCatchBlockId),
> + il_info_get_next_block_id(OuterCatchBlockId),
> il_info_make_next_label(DoneLabel),
>
> % Replace all the returns with leave instructions;
> @@ -1006,43 +1009,123 @@
> I
> )
> )},
> +
> + { UnivMercuryType = term__functor(term__atom("univ"), [],
> + context("", 0)) },
> + { UnivMLDSType = mercury_type(UnivMercuryType, user_type) },
> + { UnivType = mlds_type_to_ilds_type(DataRep, UnivMLDSType) },
> +
> { RenameNode = (func(N) = list__map(RenameRets, N)) },
>
> - { ExceptionClassName = structured_name(assembly("mscorlib"),
> + { MercuryExceptionClassName = structured_name(
> + assembly("mercury"),
> + ["mercury", "runtime", "Exception"], []) },
> +
You should add a il_mercury_library_assembly_name function, and use that
instead.
> + { ExceptionClassName = structured_name(il_system_assembly_name,
> ["System", "Exception"], []) },
>
> + { FieldRef = make_fieldref(UnivType, MercuryExceptionClassName,
> + "mercury_exception") },
> +
> { ConsoleWriteName = class_member_name(
> structured_name(il_system_assembly_name,
> ["System", "Console"], []),
> id("Write")) },
> +
> + { UncaughtExceptionName = class_member_name(
> + structured_name(assembly("mercury"),
> + ["mercury", "exception",
> + "mercury_code"], []),
> + id("ML_report_uncaught_exception")) },
> +
> { WriteString = methoddef(call_conv(no, default),
> void, ConsoleWriteName,
> [il_string_type]) },
> + { WriteUncaughtException = methoddef(call_conv(no, default),
> + void, UncaughtExceptionName,
> + [UnivType]) },
> { WriteObject = methoddef(call_conv(no, default),
> void, ConsoleWriteName,
> [il_generic_type]) },
>
> +
> + % A code block to catch any exception at all.
> +
> + { CatchAnyException = tree__list([
> + instr_node(start_block(
> + catch(ExceptionClassName),
> + OuterCatchBlockId)),
> + instr_node(ldstr("\nUncaught system exception: \n")),
> + instr_node(call(WriteString)),
> + instr_node(call(WriteObject)),
> + instr_node(leave(label_target(DoneLabel))),
> + instr_node(end_block(catch(ExceptionClassName),
> + OuterCatchBlockId))
> + ])
> + },
> +
> + % Code to catch Mercury exceptions.
> + { CatchUserException = tree__list([
> + instr_node(start_block(
> + catch(MercuryExceptionClassName),
> + InnerCatchBlockId)),
> + instr_node(ldfld(FieldRef)),
> +
> + instr_node(call(WriteUncaughtException)),
> +
> + instr_node(leave(label_target(DoneLabel))),
> + instr_node(end_block(
> + catch(MercuryExceptionClassName),
> + InnerCatchBlockId))
> + ])
> + },
> +
> % Wrap an exception handler around the main
> % code. This allows us to debug programs
> % remotely without a window popping up asking
> % how you wish to debug. Pressing the cancel
> % button on this window is a bit difficult
> % remotely.
> + %
> + % Inside this exception handler, we catch any user
> + % exceptions and pass them
> + %
s/user/mercury/
pass them where?
> + % We nest the Mercury exception handler so that any
> + % exceptions thrown in ML_report_uncaught_exception
> + % will be caught by the outer (more general) exception
> + % handler.
> + %
> + % try {
> + % try {
> + % ... main instructions ...
> + % }
> + % catch (mercury.runtime.Exception me) {
> + % ML_report_uncaught_exception(me);
> + % }
> + % }
> + % catch (System.Exception e) {
> + % System.Console.Write(e);
> + % }
> +
> { InstrsTree = tree__list([
> - instr_node(start_block(try, TryBlockId)),
> +
> + % outer try block
> + instr_node(start_block(try, OuterTryBlockId)),
> +
> + % inner try block
> + instr_node(start_block(try, InnerTryBlockId)),
> tree__map(RenameNode, InstrsTree2),
> instr_node(leave(label_target(DoneLabel))),
> - instr_node(end_block(try, TryBlockId)),
> + instr_node(end_block(try, InnerTryBlockId)),
> +
> + % inner catch block
> + CatchUserException,
>
> - instr_node(start_block(
> - catch(ExceptionClassName),
> - TryBlockId)),
> - instr_node(ldstr("\nException Caught: \n")),
> - instr_node(call(WriteString)),
> - instr_node(call(WriteObject)),
> instr_node(leave(label_target(DoneLabel))),
> - instr_node(end_block(catch(ExceptionClassName),
> - TryBlockId)),
> + instr_node(end_block(try, OuterTryBlockId)),
> +
> + % outer catch block
> + CatchAnyException,
>
> instr_node(label(DoneLabel)),
> instr_node(ret)
> Index: runtime/mercury_mcpp.cpp
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/runtime/mercury_mcpp.cpp,v
> retrieving revision 1.8
> diff -u -r1.8 mercury_mcpp.cpp
> --- runtime/mercury_mcpp.cpp 16 Aug 2001 15:04:14 -0000 1.8
> +++ runtime/mercury_mcpp.cpp 23 Aug 2001 16:37:53 -0000
> @@ -25,17 +25,29 @@
>
> namespace runtime {
>
> - // XXX Exception support is utterly incomplete.
> + // A user exception -- really just a wrapper for the exception
> + // data.
> +
> __gc public class Exception : public System::Exception
> {
> public:
> - // XXX there should be a Mercury object here.
> - Exception(MR_String Msg) : System::Exception(Msg)
> - {
> - // XXX this should set the exception message
> - }
> + Exception(MR_Word data)
> + {
> + mercury_exception = data;
> + }
> + MR_Word mercury_exception;
> };
>
> +__gc public class SystemException : public System::Exception
> +{
> +public:
> + SystemException(MR_String Msg) : System::Exception(Msg)
> + {
> + // XXX this should set the exception message
> + }
> +};
What happens now if you call SORRY or fatal_error,
do you still get the message? If not I think you should fix this.
> +
> +
> __gc public class LowLevelData
> {
>
> @@ -75,14 +87,14 @@
> {
> MR_String msg;
> msg = System::String::Concat("Sorry, unimplemented: ", s);
> - throw new mercury::runtime::Exception(msg);
> + throw new mercury::runtime::SystemException(msg);
> }
>
> static void fatal_error(MR_String s)
> {
> MR_String msg;
> msg = System::String::Concat("Fatal error: ", s);
> - throw new mercury::runtime::Exception(msg);
> + throw new mercury::runtime::SystemException(msg);
> }
> };
>
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list