[m-rev.] for review: copy/2 implementation for il backend

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Nov 27 18:56:55 AEDT 2002


In general I think it is not a good idea to implement copy/2 in
a foreign language -- it should be implemented in Mercury,
using construct and deconstruct from std_util.m.

However, if you really want to...

On 26-Nov-2002, Peter Ross <pro at missioncriticalit.com> wrote:
> +++ library/builtin.m	26 Nov 2002 12:53:52 -0000
> @@ -415,6 +415,9 @@
>  call_rtti_generic_compare(Res, X, Y) :-
>  	rtti_implementation__generic_compare(Res, X, Y).
>  
> +:- pragma foreign_decl("MC++", "
> +#using ""builtin__csharp_code.dll""
> +").

Doesn't that add a dependency which needs to be reflected
in the Mmakefile somewhere?

> @@ -462,6 +463,56 @@
> +:- pragma foreign_decl("C#", "
> +using System;
> +using System.Reflection;
> +").

Please don't use "using" declarations in the Mercury implementation.
Just fully-qualify any references you need.  That makes it easier
for other Mercury maintainers (who are unlikely to be familiar with
the .NET library) to figure out which entity each name refers to and
where to find its documentation.

(We can reconsider this policy if/when Visual Mercury becomes fully
open-source, runs on Linux, and supports automatic tool-tips that
fully-expand such references in inline C# code in Mercury source files
when you hover the mouse cursor over them ;-)

> +:- pragma foreign_code("C#", "
> +public static object deep_copy(object o)
> +{
> +	Type t = o.GetType();
> +
> +	if (t.IsValueType) {
> +		return o;
> +	} else if (t == typeof(string)) {
> +		// XXX For some reason we need to handle strings specially.
> +		// It is probably something to do with the fact that they
> +		// are a builtin type.
> +		string s;
> +		s = (string) o;
> +		return s;
> +	} else {
> +		object n;
> +
> +		// This will do a bitwise shallow copy of the object.
> +		n = t.InvokeMember(""MemberwiseClone"",
> +			BindingFlags.Instance | BindingFlags.NonPublic |
> +			BindingFlags.InvokeMethod, null, o, new object[] {});
> +
> +		// Set each of the fields to point to a deep copy of the
> +		// field.
> +		deep_copy_fields(t.GetFields(BindingFlags.Public |
> +				BindingFlags.Instance), n, o);
> +
> +		// XXX We can only access the non-public fields of a fully
> +		// trusted assembly.
> +		deep_copy_fields(t.GetFields(BindingFlags.NonPublic |
> +				BindingFlags.Instance), n, o);

I don't understand the XXX here.  You should be able to access the
non-public fields of an object defined in any assembly (trusted or not)
iff the assembly in which this code resides, i.e. the Mercury standard
library assembly, is fully trusted.

> +public static void deep_copy_fields(FieldInfo[] fields, object dest, object src)
> +{
> +        // XXX We don't handle init-only fields, but I can't think of a way.
> +        foreach (FieldInfo f in fields)
> +        {
> +            f.SetValue(dest, deep_copy(f.GetValue(src)));
> +        }
> +}

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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