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

Peter Ross pro at missioncriticalit.com
Tue Nov 26 23:57:14 AEDT 2002


Hi,

For trd or fjh to review.

===================================================================


Estimated hours taken: 6
Branches: main

Implement copy/2 for the il backend.

library/builtin.m:
	Deep copy .NET classes.  This relies on two assumptions, that
	the objects contain no init-only fields and that the type
	resides in an assembly that is fully trusted.
	Fix some bugs where some MC++ code was incorrectly being
	declared as instance members.


Index: library/builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/builtin.m,v
retrieving revision 1.82
diff -u -r1.82 builtin.m
--- library/builtin.m	8 Nov 2002 00:44:20 -0000	1.82
+++ 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""
+").
 :- pragma foreign_code("MC++", "
 
 static void compare_3(MR_TypeInfo TypeInfo_for_T,
@@ -425,36 +428,34 @@
 			TypeInfo_for_T, Res, X, Y);
 }
 
-void compare_3_m1(MR_TypeInfo TypeInfo_for_T,
+static void compare_3_m1(MR_TypeInfo TypeInfo_for_T,
 		MR_Ref(MR_ComparisonResult) Res, 
 		MR_Box X, MR_Box Y) 
 {
 	compare_3(TypeInfo_for_T, Res, X, Y);
 }
 
-void compare_3_m2(MR_TypeInfo TypeInfo_for_T,
+static void compare_3_m2(MR_TypeInfo TypeInfo_for_T,
 		MR_Ref(MR_ComparisonResult) Res, 
 		MR_Box X, MR_Box Y) 
 {
 	compare_3(TypeInfo_for_T, Res, X, Y);
 }
 
-void compare_3_m3(MR_TypeInfo TypeInfo_for_T,
+static void compare_3_m3(MR_TypeInfo TypeInfo_for_T,
 		MR_Ref(MR_ComparisonResult) Res, 
 		MR_Box X, MR_Box Y) 
 {
 	compare_3(TypeInfo_for_T, Res, X, Y);
 }
 
-void copy_2(MR_TypeInfo TypeInfo_for_T,
+static void copy_2(MR_TypeInfo TypeInfo_for_T,
 		MR_Box X, MR_Ref(MR_Box) Y) 
 {
-	// XXX this needs to be implemented -- just using Clone() won't work
-	// because it often does shallow copies.
-	mercury::runtime::Errors::SORRY(""foreign code for this function"");
+        *Y = mercury::builtin__csharp_code::mercury_code::deep_copy(X);
 }
 
-void copy_2_m1(MR_TypeInfo TypeInfo_for_T,
+static void copy_2_m1(MR_TypeInfo TypeInfo_for_T,
 		MR_Box X, MR_Ref(MR_Box) Y) 
 {
 	copy_2(TypeInfo_for_T, X, Y);
@@ -462,6 +463,56 @@
 
 ").
 
+:- pragma foreign_decl("C#", "
+using System;
+using System.Reflection;
+").
+:- 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);
+
+		return n;
+	}
+}
+
+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)));
+        }
+}
+
+").
 
 :- pragma foreign_code("MC++", "
 

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