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

Peter Ross pro at missioncriticalit.com
Wed Nov 27 22:33:38 AEDT 2002



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
	mercury.dll assembly has
	System.Security.Permissions.ReflectionPermission.
	Fix some bugs where some MC++ code was incorrectly being
	declared as instance members.

library/Mmakefile:
	Add that the builtin__cpp_code.dll depends on
	builtin__csharp_code.dll.


diff -u library/builtin.m library/builtin.m
--- library/builtin.m
+++ library/builtin.m
@@ -463,14 +463,10 @@
 
 ").
 
-:- pragma foreign_decl("C#", "
-using System;
-using System.Reflection;
-").
 :- pragma foreign_code("C#", "
 public static object deep_copy(object o)
 {
-	Type t = o.GetType();
+	System.Type t = o.GetType();
 
 	if (t.IsValueType) {
 		return o;
@@ -486,27 +482,35 @@
 
 		// This will do a bitwise shallow copy of the object.
 		n = t.InvokeMember(""MemberwiseClone"",
-			BindingFlags.Instance | BindingFlags.NonPublic |
-			BindingFlags.InvokeMethod, null, o, new object[] {});
+			System.Reflection.BindingFlags.Instance |
+			System.Reflection.BindingFlags.NonPublic |
+			System.Reflection.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);
+		deep_copy_fields(t.GetFields(
+				System.Reflection.BindingFlags.Public |
+				System.Reflection.BindingFlags.Instance),
+				n, o);
+
+		// XXX This requires that mercury.dll have
+		// System.Security.Permissions.ReflectionPermission
+		// so that the non-public fields are accessible.
+		deep_copy_fields(t.GetFields(
+				System.Reflection.BindingFlags.NonPublic |
+				System.Reflection.BindingFlags.Instance),
+				n, o);
 
 		return n;
 	}
 }
 
-public static void deep_copy_fields(FieldInfo[] fields, object dest, object src)
+public static void deep_copy_fields(
+		System.Reflection.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)
+        foreach (System.Reflection.FieldInfo f in fields)
         {
             f.SetValue(dest, deep_copy(f.GetValue(src)));
         }

Index: library/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/library/Mmakefile,v
retrieving revision 1.102
diff -u -r1.102 Mmakefile
--- library/Mmakefile	22 Nov 2002 17:23:39 -0000	1.102
+++ library/Mmakefile	27 Nov 2002 11:30:06 -0000
@@ -236,6 +236,7 @@
 mercury_mcpp.dll: ../runtime/mercury_mcpp.dll
 	cp ../runtime/mercury_mcpp.dll .
 
+builtin__cpp_code.dll : builtin__csharp_code.dll
 exception__csharp_code.dll : exception__cpp_code.dll
 CSHARP_ASSEMBLY_REFS-exception__csharp_code += /addmodule:exception__cpp_code.dll
 
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	27 Nov 2002 11:30:06 -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,60 @@
 
 ").
 
+:- pragma foreign_code("C#", "
+public static object deep_copy(object o)
+{
+	System.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"",
+			System.Reflection.BindingFlags.Instance |
+			System.Reflection.BindingFlags.NonPublic |
+			System.Reflection.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(
+				System.Reflection.BindingFlags.Public |
+				System.Reflection.BindingFlags.Instance),
+				n, o);
+
+		// XXX This requires that mercury.dll have
+		// System.Security.Permissions.ReflectionPermission
+		// so that the non-public fields are accessible.
+		deep_copy_fields(t.GetFields(
+				System.Reflection.BindingFlags.NonPublic |
+				System.Reflection.BindingFlags.Instance),
+				n, o);
+
+		return n;
+	}
+}
+
+public static void deep_copy_fields(
+		System.Reflection.FieldInfo[] fields, object dest, object src)
+{
+        // XXX We don't handle init-only fields, but I can't think of a way.
+        foreach (System.Reflection.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