[m-rev.] for review: Fix deep copying of subtype terms.

Peter Wang novalazy at gmail.com
Wed Apr 7 16:27:45 AEST 2021


runtime/mercury_deep_copy.c:
    Include mercury_deconstruct_macros.h for
    MR_index_or_search_ptag_layout and
    MR_index_or_search_sectag_functor.

runtime/mercury_deep_copy_body.h:
    Use the macros to search a du type layout by primary tag or a
    sectag_alternatives array by secondary tag, which is necessary
    for subtypes.

runtime/mercury_deconstruct.c:
runtime/mercury_ml_expand_body.h:
runtime/mercury_term_size.c:
runtime/mercury_unify_compare_body.h:
    Add comments where we can and can't directly index a du type layout
    or sectag alternatives array.

tests/hard_coded/subtype_rtti.m:
tests/hard_coded/subtype_rtti.exp:
tests/hard_coded/subtype_rtti.exp2:
    Test deep copying of subtype terms.
---
 runtime/mercury_deconstruct.c        |  7 +++++++
 runtime/mercury_deep_copy.c          |  3 ++-
 runtime/mercury_deep_copy_body.h     | 11 ++++++-----
 runtime/mercury_ml_expand_body.h     |  3 +++
 runtime/mercury_term_size.c          |  4 ++++
 runtime/mercury_unify_compare_body.h |  4 ++++
 tests/hard_coded/subtype_rtti.exp    |  8 ++++++++
 tests/hard_coded/subtype_rtti.exp2   |  8 ++++++++
 tests/hard_coded/subtype_rtti.m      |  9 +++++++++
 9 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/runtime/mercury_deconstruct.c b/runtime/mercury_deconstruct.c
index ae233e3d8..7888cefa7 100644
--- a/runtime/mercury_deconstruct.c
+++ b/runtime/mercury_deconstruct.c
@@ -149,29 +149,36 @@ MR_named_arg_num(MR_TypeInfo type_info, MR_Word *term_ptr,
             data = *term_ptr;
             du_type_layout = MR_type_ctor_layout(type_ctor_info).MR_layout_du;
             ptag = MR_tag(data);
+            // XXX SUBTYPE cannot index du_type_layout for subtypes
             ptag_layout = &du_type_layout[ptag];
 
             switch (ptag_layout->MR_sectag_locn) {
                 case MR_SECTAG_NONE:
                 case MR_SECTAG_NONE_DIRECT_ARG:
+                    // We can index MR_sectag_alternatives for
+                    // MR_SECTAG_NONE_*.
                     functor_desc = ptag_layout->MR_sectag_alternatives[0];
                     break;
                 case MR_SECTAG_LOCAL_REST_OF_WORD:
                     sectag = MR_unmkbody(data);
+                    // XXX SUBTYPE cannot index MR_sectag_alternatives
                     functor_desc = ptag_layout->MR_sectag_alternatives[sectag];
                     break;
                 case MR_SECTAG_LOCAL_BITS:
                     sectag = MR_unmkbody(data) &
                         ((1 << ptag_layout->MR_sectag_numbits) - 1);
+                    // XXX SUBTYPE cannot index MR_sectag_alternatives
                     functor_desc = ptag_layout->MR_sectag_alternatives[sectag];
                     break;
                 case MR_SECTAG_REMOTE_FULL_WORD:
                     sectag = MR_field(ptag, data, 0);
+                    // XXX SUBTYPE cannot index MR_sectag_alternatives
                     functor_desc = ptag_layout->MR_sectag_alternatives[sectag];
                     break;
                 case MR_SECTAG_REMOTE_BITS:
                     sectag = MR_field(ptag, data, 0) &
                         ((1 << ptag_layout->MR_sectag_numbits) - 1);
+                    // XXX SUBTYPE cannot index MR_sectag_alternatives
                     functor_desc = ptag_layout->MR_sectag_alternatives[sectag];
                     break;
                 case MR_SECTAG_VARIABLE:
diff --git a/runtime/mercury_deep_copy.c b/runtime/mercury_deep_copy.c
index b7b91b64e..c86d58f4a 100644
--- a/runtime/mercury_deep_copy.c
+++ b/runtime/mercury_deep_copy.c
@@ -1,7 +1,7 @@
 // vim: ts=4 sw=4 expandtab ft=c
 
 // Copyright (C) 1997-2006 The University of Melbourne.
-// Copyright (C) 2016, 2018 The Mercury team.
+// Copyright (C) 2016, 2018, 2021 The Mercury team.
 // This file is distributed under the terms specified in COPYING.LIB.
 
 // This module defines the MR_deep_copy() functions.
@@ -18,6 +18,7 @@
 #include "mercury_layout_util.h"
 #include "mercury_memory.h"
 #include "mercury_accurate_gc.h"
+#include "mercury_deconstruct_macros.h"
 
 // MR_deep_copy(): see mercury_deep_copy.h for documentation.
 
diff --git a/runtime/mercury_deep_copy_body.h b/runtime/mercury_deep_copy_body.h
index cb2cc2d1d..debc91c0f 100644
--- a/runtime/mercury_deep_copy_body.h
+++ b/runtime/mercury_deep_copy_body.h
@@ -1,7 +1,7 @@
 // vim: ts=4 sw=4 expandtab ft=c
 
 // Copyright (C) 1997-2005, 2007, 2012 The University of Melbourne.
-// Copyright (C) 2014-2018 The Mercury team.
+// Copyright (C) 2014-2018, 2021 The Mercury team.
 // This file is distributed under the terms specified in COPYING.LIB.
 
 // The internals of deep copy.
@@ -84,7 +84,6 @@ copy(MR_Word data, MR_TypeInfo type_info,
 {
     MR_Word             new_data;
     MR_TypeCtorInfo     type_ctor_info;
-    MR_DuTypeLayout     du_type_layout;
 
 try_again:
     type_ctor_info = MR_TYPEINFO_GET_TYPE_CTOR_INFO(type_info);
@@ -115,9 +114,8 @@ try_again:
         int                   sectag_word;
         int                   sectag;
 
-        du_type_layout = MR_type_ctor_layout(type_ctor_info).MR_layout_du;
         ptag = MR_tag(data);
-        ptag_layout = &du_type_layout[ptag];
+        MR_index_or_search_ptag_layout(ptag, ptag_layout);
 
         switch (ptag_layout->MR_sectag_locn) {
 
@@ -189,7 +187,8 @@ try_again:
             cell_size = 0;                                                  \
         }                                                                   \
                                                                             \
-        functor_desc = ptag_layout->MR_sectag_alternatives[sectag];         \
+        MR_index_or_search_sectag_functor(ptag_layout, sectag,              \
+            functor_desc);                                                  \
         arity = functor_desc->MR_du_functor_orig_arity;                     \
         arg_locns = functor_desc->MR_du_functor_arg_locns;                  \
         exist_info = functor_desc->MR_du_functor_exist_info;                \
@@ -362,6 +361,8 @@ try_again:
                 const MR_DuExistInfo    *exist_info;
                 int                     arity;
 
+                // We can index MR_sectag_alternatives for
+                // MR_SECTAG_NONE_DIRECT_ARG.
                 functor_desc = ptag_layout->MR_sectag_alternatives[0];
                 arity = functor_desc->MR_du_functor_orig_arity;
                 arg_locns = functor_desc->MR_du_functor_arg_locns;
diff --git a/runtime/mercury_ml_expand_body.h b/runtime/mercury_ml_expand_body.h
index c766319b1..87674fddd 100644
--- a/runtime/mercury_ml_expand_body.h
+++ b/runtime/mercury_ml_expand_body.h
@@ -648,6 +648,7 @@ EXPAND_FUNCTION_NAME(MR_TypeInfo type_info, MR_Word *data_word_ptr,
         switch (ptag_layout->MR_sectag_locn) {
 
         case MR_SECTAG_NONE:
+            // We can index MR_sectag_alternatives for MR_SECTAG_NONE.
             functor_desc = ptag_layout->MR_sectag_alternatives[0];
             handle_functor_name_number_arity(expand_info, type_ctor_info,
                 functor_desc);
@@ -657,6 +658,8 @@ EXPAND_FUNCTION_NAME(MR_TypeInfo type_info, MR_Word *data_word_ptr,
             break;
 
         case MR_SECTAG_NONE_DIRECT_ARG:
+            // We can index MR_sectag_alternatives for
+            // MR_SECTAG_NONE_DIRECT_ARG.
             functor_desc = ptag_layout->MR_sectag_alternatives[0];
             handle_functor_name_number_arity(expand_info, type_ctor_info,
                 functor_desc);
diff --git a/runtime/mercury_term_size.c b/runtime/mercury_term_size.c
index 32fa08333..4284d3796 100644
--- a/runtime/mercury_term_size.c
+++ b/runtime/mercury_term_size.c
@@ -55,6 +55,7 @@ try_again:
 
         case MR_TYPECTOR_REP_DU:
         case MR_TYPECTOR_REP_DU_USEREQ:
+            // XXX SUBTYPE cannot index MR_layout_du for subtypes
             du_type_layout = MR_type_ctor_layout(type_ctor_info).MR_layout_du;
             ptag = MR_tag(term);
             ptag_layout = &du_type_layout[ptag];
@@ -62,6 +63,7 @@ try_again:
             switch (ptag_layout->MR_sectag_locn) {
                 case MR_SECTAG_NONE:
 #ifdef MR_DEBUG_TERM_SIZES
+                    // We can index MR_sectag_alternatives for MR_SECTAG_NONE.
                     if (ptag_layout->MR_sectag_alternatives[0]->
                         MR_du_functor_orig_arity <= 0)
                     {
@@ -102,6 +104,8 @@ try_again:
 #ifdef MR_DEBUG_TERM_SIZES
                     sectag = MR_field(MR_mktag(ptag), term, 0);
 
+                    // XXX SUBTYPE cannot index MR_sectag_alternatives
+                    // for subtypes
                     if (ptag_layout->MR_sectag_alternatives[sectag]->
                         MR_du_functor_orig_arity <= 0)
                     {
diff --git a/runtime/mercury_unify_compare_body.h b/runtime/mercury_unify_compare_body.h
index 44add46fc..4c3139620 100644
--- a/runtime/mercury_unify_compare_body.h
+++ b/runtime/mercury_unify_compare_body.h
@@ -207,6 +207,7 @@ start_label:
                     int                     ptag;                             \
                     int                     sectag;                           \
                                                                               \
+                    /* XXX SUBTYPE cannot index MR_layout_du for subtypes */  \
                     ptag = MR_tag(data);                                      \
                     ptag_layout = &MR_type_ctor_layout(type_ctor_info).       \
                         MR_layout_du[ptag];                                   \
@@ -241,6 +242,8 @@ start_label:
                                 "unrecognised sectag locn");                  \
                     }                                                         \
                                                                               \
+                    /* XXX SUBTYPE cannot index MR_sectag_alternatives */     \
+                    /* for subtypes */                                        \
                     functor_desc =                                            \
                         ptag_layout->MR_sectag_alternatives[sectag];          \
                 } while (0)
@@ -345,6 +348,7 @@ start_label:
                             "attempt get functor desc of variable");
                 }
 
+                /* XXX SUBTYPE cannot index MR_sectag_alternatives */
                 functor_desc = ptag_layout->MR_sectag_alternatives[x_sectag];
   #endif // select_compare_code
 
diff --git a/tests/hard_coded/subtype_rtti.exp b/tests/hard_coded/subtype_rtti.exp
index d5f9a2813..df4d19465 100644
--- a/tests/hard_coded/subtype_rtti.exp
+++ b/tests/hard_coded/subtype_rtti.exp
@@ -30,6 +30,7 @@ construct.find_functor
 construct.construct
 	dummy
 unify ok
+copy ok
 
 --------------------
 term
@@ -63,6 +64,7 @@ construct.find_functor
 construct.construct
 	notag(notag0(orange))
 unify ok
+copy ok
 
 --------------------
 term
@@ -96,6 +98,7 @@ construct.find_functor
 construct.construct
 	f1(42)
 unify ok
+copy ok
 
 --------------------
 term
@@ -129,6 +132,7 @@ construct.find_functor
 construct.construct
 	blue
 unify ok
+copy ok
 
 --------------------
 term
@@ -162,6 +166,7 @@ construct.find_functor
 construct.construct
 	f0_a
 unify ok
+copy ok
 
 --------------------
 term
@@ -195,6 +200,7 @@ construct.find_functor
 construct.construct
 	f0_b(flag_set, blue, banana)
 unify ok
+copy ok
 
 --------------------
 term
@@ -228,6 +234,7 @@ construct.find_functor
 construct.construct
 	f2(42)
 unify ok
+copy ok
 
 --------------------
 term
@@ -261,4 +268,5 @@ construct.find_functor
 construct.construct
 	f7_b(flag_set, blue, banana, 3.14)
 unify ok
+copy ok
 
diff --git a/tests/hard_coded/subtype_rtti.exp2 b/tests/hard_coded/subtype_rtti.exp2
index 28eafa865..3f9cb42fd 100644
--- a/tests/hard_coded/subtype_rtti.exp2
+++ b/tests/hard_coded/subtype_rtti.exp2
@@ -30,6 +30,7 @@ construct.find_functor
 construct.construct
 	dummy
 unify ok
+copy ok
 
 --------------------
 term
@@ -63,6 +64,7 @@ construct.find_functor
 construct.construct
 	notag(notag0(orange))
 unify ok
+copy ok
 
 --------------------
 term
@@ -96,6 +98,7 @@ construct.find_functor
 construct.construct
 	f1(42)
 unify ok
+copy ok
 
 --------------------
 term
@@ -129,6 +132,7 @@ construct.find_functor
 construct.construct
 	blue
 unify ok
+copy ok
 
 --------------------
 term
@@ -162,6 +166,7 @@ construct.find_functor
 construct.construct
 	f0_a
 unify ok
+copy ok
 
 --------------------
 term
@@ -195,6 +200,7 @@ construct.find_functor
 construct.construct
 	f0_b(flag_set, blue, banana)
 unify ok
+copy ok
 
 --------------------
 term
@@ -228,6 +234,7 @@ construct.find_functor
 construct.construct
 	f2(42)
 unify ok
+copy ok
 
 --------------------
 term
@@ -261,4 +268,5 @@ construct.find_functor
 construct.construct
 	f7_b(flag_set, blue, banana, 3.14)
 unify ok
+copy ok
 
diff --git a/tests/hard_coded/subtype_rtti.m b/tests/hard_coded/subtype_rtti.m
index 520973e48..fc2e6804b 100644
--- a/tests/hard_coded/subtype_rtti.m
+++ b/tests/hard_coded/subtype_rtti.m
@@ -249,6 +249,15 @@ test(Term, !IO) :-
     else
         io.write_string("deconstruct_du failed\n", !IO)
     ),
+
+    % Deep copy.
+    copy(Term, TermCopy),
+    ( if Term = TermCopy then
+        io.write_string("copy ok\n", !IO)
+    else
+        io.write_string("copied term does not unify\n", !IO)
+    ),
+
     io.nl(!IO).
 
 :- pred print_value(string::in, T::in, io::di, io::uo) is det.
-- 
2.30.0



More information about the reviews mailing list