[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