[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