poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[COMMITTED] pkl: gen: fix handling of type closures


From: Jose E. Marchesi
Subject: [COMMITTED] pkl: gen: fix handling of type closures
Date: Wed, 05 Jan 2022 15:15:01 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

This patch fixes a series of very annoying crashes that were related
to the fact some closures stored in AST nodes were missing a proper
environment when invoked.

2022-01-05  Jose E. Marchesi  <jemarch@gnu.org>

        * libpoke/pkl-gen.c (pkl_gen_pr_decl): Compile type closures
        conditionally but install environment unconditionally.
        (LMAP): Likewise.
        (pkl_gen_pr_array): Likewise.
        (pkl_gen_pr_struct): Likewise.
        * testsuite/poke.map/maps-structs-19.pk: Likewise.
        * testsuite/poke.map/nsmap-6.pk: Likewise.
        * testsuite/poke.pkl/scons-65.pk: New test.
        * testsuite/poke.pkl/scons-66.pk: Likewise.
        * testsuite/poke.pkl/scons-67.pk: Likewise.
        * testsuite/poke.map/write-structs-1.pk: Likewise.
        * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
---
 ChangeLog                             |  15 ++
 libpoke/pkl-gen.c                     | 473 ++++++++++++++--------------------
 testsuite/Makefile.am                 |   6 +
 testsuite/poke.map/maps-structs-19.pk |  12 +
 testsuite/poke.map/nsmap-6.pk         |  10 +
 testsuite/poke.map/write-structs-1.pk |  10 +
 testsuite/poke.pkl/scons-65.pk        |  16 ++
 testsuite/poke.pkl/scons-66.pk        |  12 +
 testsuite/poke.pkl/scons-67.pk        |  12 +
 9 files changed, 293 insertions(+), 273 deletions(-)
 create mode 100644 testsuite/poke.map/maps-structs-19.pk
 create mode 100644 testsuite/poke.map/nsmap-6.pk
 create mode 100644 testsuite/poke.map/write-structs-1.pk
 create mode 100644 testsuite/poke.pkl/scons-65.pk
 create mode 100644 testsuite/poke.pkl/scons-66.pk
 create mode 100644 testsuite/poke.pkl/scons-67.pk

diff --git a/ChangeLog b/ChangeLog
index 1e0f25c9..457d87b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2022-01-05  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * libpoke/pkl-gen.c (pkl_gen_pr_decl): Compile type closures
+       conditionally but install environment unconditionally.
+       (LMAP): Likewise.
+       (pkl_gen_pr_array): Likewise.
+       (pkl_gen_pr_struct): Likewise.
+       * testsuite/poke.map/maps-structs-19.pk: Likewise.
+       * testsuite/poke.map/nsmap-6.pk: Likewise.
+       * testsuite/poke.pkl/scons-65.pk: New test.
+       * testsuite/poke.pkl/scons-66.pk: Likewise.
+       * testsuite/poke.pkl/scons-67.pk: Likewise.
+       * testsuite/poke.map/write-structs-1.pk: Likewise.
+       * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
+
 2022-01-04  David Faust  <david.faust@oracle.com>
 
        * testsuite/poke.pickles/btf-test.pk: New test.
diff --git a/libpoke/pkl-gen.c b/libpoke/pkl-gen.c
index 1c9e3aef..5d3c1a65 100644
--- a/libpoke/pkl-gen.c
+++ b/libpoke/pkl-gen.c
@@ -194,118 +194,118 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_decl)
         {
         case PKL_TYPE_STRUCT:
           {
-            pvm_val mapper_closure;
-            pvm_val writer_closure;
-            pvm_val constructor_closure;
-            pvm_val comparator_closure;
-            pvm_val integrator_closure;
-            pvm_val deintegrator_closure;
-
             pkl_ast_node type_struct = initial;
 
-            /* Compile the struct closures, complete them using the
-               current environment and install them in the AST node.
-               But only if they haven't been compiled already.  */
+            /* Compile the struct closures and complete them using the
+               current environment.  */
 
             if (PKL_AST_TYPE_S_WRITER (type_struct) == PVM_NULL)
               {
+                pvm_val writer_closure;
+
                 PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
                 {
                   if (PKL_AST_TYPE_S_UNION_P (type_struct))
                     RAS_FUNCTION_UNION_WRITER (writer_closure, type_struct);
                   else
                     RAS_FUNCTION_STRUCT_WRITER (writer_closure, type_struct);
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, writer_closure); 
/* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                  
/* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                 
/* _ */
                 }
                 PKL_GEN_POP_CONTEXT;
-
                 PKL_AST_TYPE_S_WRITER (type_struct) = writer_closure;
               }
 
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                          PKL_AST_TYPE_S_WRITER (type_struct)); /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);           /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);          /* _ */
+
             if (PKL_AST_TYPE_S_MAPPER (type_struct) == PVM_NULL)
               {
+                pvm_val mapper_closure;
+
                 PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_MAPPER);
-                {
-                  RAS_FUNCTION_STRUCT_MAPPER (mapper_closure, type_struct);
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, mapper_closure); 
/* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                  
/* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                 
/* _ */
-                }
+                RAS_FUNCTION_STRUCT_MAPPER (mapper_closure, type_struct);
                 PKL_GEN_POP_CONTEXT;
-
                 PKL_AST_TYPE_S_MAPPER (type_struct) = mapper_closure;
               }
 
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                          PKL_AST_TYPE_S_MAPPER (type_struct)); /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);           /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);          /* _ */
+
             if (PKL_AST_TYPE_S_CONSTRUCTOR (type_struct) == PVM_NULL)
               {
+                pvm_val constructor_closure;
+
                 PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_CONSTRUCTOR);
-                {
-                  RAS_FUNCTION_STRUCT_CONSTRUCTOR (constructor_closure,
-                                                   type_struct);          /* 
CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, 
constructor_closure); /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                    
   /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                   
   /* _ */
-                }
+                RAS_FUNCTION_STRUCT_CONSTRUCTOR (constructor_closure,
+                                                 type_struct);
                 PKL_GEN_POP_CONTEXT;
-
                 PKL_AST_TYPE_S_CONSTRUCTOR (type_struct) = constructor_closure;
               }
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                          PKL_AST_TYPE_S_CONSTRUCTOR (type_struct)); /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);               /* _ */
 
             if (PKL_AST_TYPE_S_COMPARATOR (type_struct) == PVM_NULL)
               {
+                pvm_val comparator_closure;
+
                 PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_COMPARATOR);
-                {
-                  RAS_FUNCTION_STRUCT_COMPARATOR (comparator_closure,
-                                                  type_struct);           /* 
CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, 
comparator_closure); /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                    
  /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                   
  /* _ */
-                }
+                RAS_FUNCTION_STRUCT_COMPARATOR (comparator_closure,
+                                                type_struct);
                 PKL_GEN_POP_CONTEXT;
-
                 PKL_AST_TYPE_S_COMPARATOR (type_struct) = comparator_closure;
               }
 
-            if (PKL_AST_TYPE_S_ITYPE (type_struct)
-                && PKL_AST_TYPE_S_INTEGRATOR (type_struct) == PVM_NULL)
-              {
-                /* Yes, the in_writer context is also used for
-                   integrators, since integrators do not call writers
-                   nor the other way around.  This eases sharing of
-                   code in the pks.  */
-                PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
-                {
-                  RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure,
-                                                  type_struct);           /* 
CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, 
integrator_closure); /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                    
  /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                   
  /* _ */
-                }
-                PKL_GEN_POP_CONTEXT;
-
-                PKL_AST_TYPE_S_INTEGRATOR (type_struct) = integrator_closure;
-              }
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                          PKL_AST_TYPE_S_COMPARATOR (type_struct)); /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);               /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);              /* _ */
 
-            if (PKL_AST_TYPE_S_ITYPE (type_struct)
-                && PKL_AST_TYPE_S_DEINTEGRATOR (type_struct) == PVM_NULL)
+            if (PKL_AST_TYPE_S_ITYPE (type_struct))
               {
-                /* Yes, the in_writer context is also used for
-                   deintegrators, since deintegrators do not call
-                   writers nor the other way around.  This eases
-                   sharing of code in the pks.  */
-                PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
-                {
-                  RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure,
-                                                    type_struct);           /* 
CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, 
deintegrator_closure); /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                    
    /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                   
    /* _ */
-                }
-                PKL_GEN_POP_CONTEXT;
+                if (PKL_AST_TYPE_S_INTEGRATOR (type_struct) == PVM_NULL)
+                  {
+                    pvm_val integrator_closure;
+
+                    /* Yes, the in_writer context is also used for
+                       integrators, since integrators do not call
+                       writers nor the other way around.  This eases
+                       sharing of code in the pks.  */
+                    PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
+                    RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure,
+                                                    type_struct);
+                    PKL_GEN_POP_CONTEXT;
+                    PKL_AST_TYPE_S_INTEGRATOR (type_struct) = 
integrator_closure;
+                  }
+
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                              PKL_AST_TYPE_S_INTEGRATOR (type_struct)); /* CLS 
*/
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);               /* CLS 
*/
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);              /* _ */
+
+                if (PKL_AST_TYPE_S_DEINTEGRATOR (type_struct) == PVM_NULL)
+                  {
+                    pvm_val deintegrator_closure;
+
+                    /* Yes, the in_writer context is also used for
+                       deintegrators, since deintegrators do not call
+                       writers nor the other way around.  This eases
+                       sharing of code in the pks.  */
+                    PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
+                    RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure,
+                                                      type_struct);
+                    PKL_GEN_POP_CONTEXT;
+                    PKL_AST_TYPE_S_DEINTEGRATOR (type_struct) = 
deintegrator_closure;
+                  }
 
-                PKL_AST_TYPE_S_DEINTEGRATOR (type_struct) = 
deintegrator_closure;
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                              PKL_AST_TYPE_S_DEINTEGRATOR (type_struct)); /* 
CLS */
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                 /* 
CLS */
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                /* _ 
*/
               }
 
             PKL_PASS_BREAK;
@@ -313,10 +313,6 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_decl)
           }
         case PKL_TYPE_ARRAY:
           {
-            pvm_val mapper_closure;
-            pvm_val writer_closure;
-            pvm_val constructor_closure;
-
             pkl_ast_node array_type = initial;
 
             /* Compile the arrays closures and complete them using the
@@ -337,49 +333,57 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_decl)
                 PKL_GEN_POP_CONTEXT;
               }
 
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                          PKL_AST_TYPE_A_BOUNDER (array_type)); /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);           /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);          /* _ */
+
             if (PKL_AST_TYPE_A_WRITER (array_type) == PVM_NULL)
               {
+                pvm_val writer_closure;
+
                 PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
-                {
-                  RAS_FUNCTION_ARRAY_WRITER (writer_closure, array_type);
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, writer_closure); 
/* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                  
/* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                 
/* _ */
-                }
+                RAS_FUNCTION_ARRAY_WRITER (writer_closure, array_type);
                 PKL_GEN_POP_CONTEXT;
-
                 PKL_AST_TYPE_A_WRITER (array_type) = writer_closure;
               }
 
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                          PKL_AST_TYPE_A_WRITER (array_type)); /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);          /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);         /* _ */
+
             if (PKL_AST_TYPE_A_MAPPER (array_type) == PVM_NULL)
               {
+                pvm_val mapper_closure;
+
                 PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_MAPPER);
-                {
-                  RAS_FUNCTION_ARRAY_MAPPER (mapper_closure, array_type);
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, mapper_closure); 
/* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                  
/* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                 
/* _ */
-                }
+                RAS_FUNCTION_ARRAY_MAPPER (mapper_closure, array_type);
                 PKL_GEN_POP_CONTEXT;
-
                 PKL_AST_TYPE_A_MAPPER (array_type) = mapper_closure;
               }
 
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                          PKL_AST_TYPE_A_MAPPER (array_type)); /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);          /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);         /* _ */
+
             if (PKL_AST_TYPE_A_CONSTRUCTOR (array_type) == PVM_NULL)
               {
+                pvm_val constructor_closure;
+
                 PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_CONSTRUCTOR);
-                {
-                  RAS_FUNCTION_ARRAY_CONSTRUCTOR (constructor_closure,
-                                                  array_type);           /* 
CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, 
constructor_closure); /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                    
   /* CLS */
-                  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                   
   /* _ */
-                }
+                RAS_FUNCTION_ARRAY_CONSTRUCTOR (constructor_closure,
+                                                array_type);
                 PKL_GEN_POP_CONTEXT;
-
                 PKL_AST_TYPE_A_CONSTRUCTOR (array_type) = constructor_closure;
               }
 
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
+                          PKL_AST_TYPE_A_CONSTRUCTOR (array_type)); /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);               /* CLS */
+            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);              /* _ */
+
             PKL_PASS_BREAK;
             break;
           }
@@ -813,30 +817,25 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_ass_stmt)
                ? PKL_AST_TYPE_A_WRITER ((TYPE))                         \
                : PKL_AST_TYPE_S_WRITER ((TYPE)));                       \
                                                                         \
-            /* Make sure the type has a writer.  */                     \
-            /* Note how anonymous types from within structs */          \
-            /* need the writer to be re-compiled.  This sucks :/ */     \
-            if (writer == PVM_NULL                                      \
-                || !PKL_AST_TYPE_NAME ((TYPE)))                         \
-            {                                                           \
-              PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);         \
+            /* If the type is anonymous it wont' have a compiled */     \
+            /* writer.  */                                              \
+            if (!PKL_AST_TYPE_NAME ((TYPE)))                            \
               {                                                         \
-                if (lvalue_type_code == PKL_TYPE_ARRAY)                 \
-                  RAS_FUNCTION_ARRAY_WRITER (writer, (TYPE));           \
-                else if (PKL_AST_TYPE_S_UNION_P ((TYPE)))               \
-                  RAS_FUNCTION_UNION_WRITER (writer, (TYPE));           \
-                else                                                    \
-                  RAS_FUNCTION_STRUCT_WRITER (writer, (TYPE));          \
-                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, writer); /* CLS */ \
-                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);          /* CLS */ \
-                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);         /* _ */ \
-              }                                                         \
-              PKL_GEN_POP_CONTEXT;                                      \
+                assert (writer == PVM_NULL);                            \
+                PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);       \
+                {                                                       \
+                  if (lvalue_type_code == PKL_TYPE_ARRAY)               \
+                    RAS_FUNCTION_ARRAY_WRITER (writer, (TYPE));         \
+                  else if (PKL_AST_TYPE_S_UNION_P ((TYPE)))             \
+                    RAS_FUNCTION_UNION_WRITER (writer, (TYPE));         \
+                  else                                                  \
+                    RAS_FUNCTION_STRUCT_WRITER (writer, (TYPE));        \
+                }                                                       \
+                PKL_GEN_POP_CONTEXT;                                    \
                                                                         \
-              if (lvalue_type_code == PKL_TYPE_ARRAY)                   \
-                PKL_AST_TYPE_A_WRITER ((TYPE)) = writer;                \
-              else                                                      \
-                PKL_AST_TYPE_S_WRITER ((TYPE)) = writer;                \
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, writer);      \
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);               \
+                pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);              \
             }                                                           \
                                                                         \
             /* VAL IOS BOFF */                                          \
@@ -1013,7 +1012,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_ass_stmt)
         pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_NIP);  /* VAL SCT ID STRICT_P */
         pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_BZI, label1);
 
-        /* Strict value: set with integriy.  */
+        /* Strict value: set with integrity.  */
         pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);
         pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_ROT);
         pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SSETC, struct_type);
@@ -2480,14 +2479,11 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_array)
 
   /* Install a writer in the array.  */
   PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
-  {
-    RAS_FUNCTION_ARRAY_WRITER (array_type_writer, array_type);
-    PKL_AST_TYPE_A_WRITER (array_type) = array_type_writer;
-  }
+  RAS_FUNCTION_ARRAY_WRITER (array_type_writer, array_type);
   PKL_GEN_POP_CONTEXT;
   pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, array_type_writer); /* CLS */
   pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                     /* CLS */
-  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MSETW); /* ARR */
+  pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MSETW);                   /* ARR */
 }
 PKL_PHASE_END_HANDLER
 
@@ -3074,31 +3070,17 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_array)
              pkl_gen_pr_decl.  */
           bounder_created = 1;
 
+          assert (!PKL_AST_TYPE_NAME (array_type));
           PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_ARRAY_BOUNDER);
           PKL_PASS_SUBPASS (array_type);
           PKL_GEN_POP_CONTEXT;
         }
 
-      if (array_type_mapper != PVM_NULL)
-        {
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                        array_type_mapper); /* ... STRICT IOS OFF CLS */
-        }
-      else
-        {
-          /* Compile a mapper function and complete it using the
-             current environment.  */
-          pvm_val mapper_closure;
-
-          RAS_FUNCTION_ARRAY_MAPPER (mapper_closure, array_type);
-
-          /* Complete the mapper closure with the current
-             environment.  */
-          /* OFF */
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, mapper_closure);
-                                                      /* ... STRICT IOS OFF 
CLS */
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);   /* ... STRICT IOS OFF 
CLS */
-        }
+      if (array_type_mapper == PVM_NULL)
+        RAS_FUNCTION_ARRAY_MAPPER (array_type_mapper, array_type);
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, array_type_mapper);
+      if (!PKL_AST_TYPE_NAME (array_type))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);     /* ... STRICT IOS OFF 
CLS */
 
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_TOR);       /* ... STRICT IOS OFF 
[CLS] */
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_ATR);       /* ... STRICT IOS OFF 
CLS [CLS] */
@@ -3159,25 +3141,15 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_array)
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SWAP);  /* VAL STRICT */
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MSETS); /* VAL */
 
-      if (array_type_writer != PVM_NULL)
-        {
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                        array_type_writer); /* VAL CLS */
-        }
-      else
+      if (array_type_writer == PVM_NULL)
         {
-          pvm_val writer_closure;
-
-          /* Compile a writer function to a closure.  */
           PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
-          RAS_FUNCTION_ARRAY_WRITER (writer_closure, array_type);
+          RAS_FUNCTION_ARRAY_WRITER (array_type_writer, array_type);
           PKL_GEN_POP_CONTEXT;
-
-          /* Complete the writer closure with the current
-             environment.  */
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, writer_closure); /* VAL 
CLS */
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                  /* VAL 
CLS */
         }
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, array_type_writer);
+      if (!PKL_AST_TYPE_NAME (array_type))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC); /* VAL CLS */
 
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MSETW);                /* VAL */
       /* Yay!, we are done ;) */
@@ -3199,14 +3171,10 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_array)
 
       /* If the array type doesn't have a printer, compile one.  */
       if (printer_closure == PVM_NULL)
-        {
-          RAS_FUNCTION_ARRAY_PRINTER (printer_closure, array_type);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, printer_closure);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
-          PKL_AST_TYPE_A_PRINTER (array_type) = printer_closure;
-        }
-      else
-        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, printer_closure);
+        RAS_FUNCTION_ARRAY_PRINTER (printer_closure, array_type);
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, printer_closure);
+      if (!PKL_AST_TYPE_NAME (array_type))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
 
       /* Invoke the printer.  */
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL); /* _ */
@@ -3221,14 +3189,10 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_array)
 
       /* If the array type doesn't have a formater, compile one.  */
       if (formater_closure == PVM_NULL)
-        {
-          RAS_FUNCTION_ARRAY_FORMATER (formater_closure, array_type);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, formater_closure);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
-          PKL_AST_TYPE_A_FORMATER (array_type) = formater_closure;
-        }
-      else
-        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, formater_closure);
+        RAS_FUNCTION_ARRAY_FORMATER (formater_closure, array_type);
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, formater_closure);
+      if (!PKL_AST_TYPE_NAME (array_type))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
 
       /* Invoke the formater.  */
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL); /* _ */
@@ -3240,7 +3204,6 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_array)
       pkl_ast_node array_type = PKL_PASS_NODE;
       pkl_ast_node array_type_bound = PKL_AST_TYPE_A_BOUND (array_type);
       pvm_val array_type_constructor = PKL_AST_TYPE_A_CONSTRUCTOR (array_type);
-      pvm_val array_type_writer = PKL_AST_TYPE_A_WRITER (array_type);
       int bounder_created = 0;
 
       PKL_GEN_PAYLOAD->constructor_depth++;
@@ -3256,6 +3219,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_array)
              Named array types have their bounder compiled in
              pkl_gen_pr_decl.  */
           bounder_created = 1;
+          assert (!PKL_AST_TYPE_NAME (array_type));
           PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_ARRAY_BOUNDER);
           PKL_PASS_SUBPASS (array_type);
           PKL_GEN_POP_CONTEXT;
@@ -3292,39 +3256,13 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_array)
         pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, PVM_NULL);
 
       /* Make sure the array type has a constructor, and call it.  */
-      if (array_type_constructor != PVM_NULL)
-        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                      array_type_constructor); /* EBOUND SBOUND CLS */
-      else
-        {
-          RAS_FUNCTION_ARRAY_CONSTRUCTOR (array_type_constructor, array_type);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, array_type_constructor);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
-        }
+      if (array_type_constructor == PVM_NULL)
+        RAS_FUNCTION_ARRAY_CONSTRUCTOR (array_type_constructor, array_type);
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, array_type_constructor);
+      if (!PKL_AST_TYPE_NAME (array_type))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
 
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);          /* ARR */
-
-      /* Install a writer in the constructed array.  This is needed
-         when the value is used as the right-hand-side to a
-         map-assignment operation.  */
-      if (array_type_writer == PVM_NULL)
-        {
-          PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
-          {
-            RAS_FUNCTION_ARRAY_WRITER (array_type_writer, array_type);
-            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, array_type_writer); /* 
CLS */
-            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                     /* 
CLS */
-            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                    /* _ 
*/
-          }
-          PKL_GEN_POP_CONTEXT;
-
-          PKL_AST_TYPE_A_WRITER (array_type) = array_type_writer;
-        }
-
-      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                    array_type_writer);           /* ARR CLS */
-      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MSETW); /* ARR */
-
       PKL_GEN_PAYLOAD->constructor_depth--;
 
       if (bounder_created)
@@ -3423,6 +3361,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_struct)
 
       pvm_val type_struct_mapper = PKL_AST_TYPE_S_MAPPER (type_struct);
       pvm_val type_struct_writer = PKL_AST_TYPE_S_WRITER (type_struct);
+      pvm_val type_struct_constructor = PKL_AST_TYPE_S_CONSTRUCTOR 
(type_struct);
 
       /* Make a copy of the IOS and STRICT.  We will need to install
          them in the resulting value later.  */
@@ -3432,21 +3371,13 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_struct)
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_OVER);
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_FROMR); /* STRICT IOS STRICT IOS OFF 
*/
 
-      if (type_struct_mapper != PVM_NULL)
-        {
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                        type_struct_mapper);
-        }
-      else
-        {
-          /* Compile a mapper function and complete it using the
-             current environment.  */
-          pvm_val mapper_closure;
-
-          RAS_FUNCTION_STRUCT_MAPPER (mapper_closure, type_struct);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, mapper_closure);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
-        } /* ... STRICT IOS OFF CLS */
+      /* Compile a mapper function and complete it using the current
+         environment.  */
+      if (type_struct_mapper == PVM_NULL)
+        RAS_FUNCTION_STRUCT_MAPPER (type_struct_mapper, type_struct);
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, type_struct_mapper);
+      if (!PKL_AST_TYPE_NAME (type_struct))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC); /* ... STRICT IOS OFF CLS */
 
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_TOR);   /* ... STRICT IOS OFF [CLS] 
*/
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_ATR);   /* ... STRICT IOS OFF CLS 
[CLS] */
@@ -3481,27 +3412,41 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_struct)
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_SWAP);  /* VAL STRICT */
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MSETS); /* VAL */
 
-      if (type_struct_writer != PVM_NULL)
+      /* Compile a constructor function and complete it using the
+         current environment.  */
+      if (type_struct_constructor == PVM_NULL)
         {
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                        type_struct_writer); /* VAL CLS */
+          assert (!PKL_AST_TYPE_NAME (type_struct));
+          PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_CONSTRUCTOR);
+          RAS_FUNCTION_STRUCT_CONSTRUCTOR (type_struct_constructor, 
type_struct);
+          PKL_GEN_POP_CONTEXT;
+          /* We normally do not install closures in anonymous types,
+             but this one is needed by ssetc.  */
+          PKL_AST_TYPE_S_CONSTRUCTOR (type_struct) = type_struct_constructor;
         }
-      else
+      if (!PKL_AST_TYPE_NAME (type_struct))
         {
-          /* Compile a writer function and complete it using the
-             current environment.  */
-          pvm_val writer_closure;
+          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, type_struct_constructor);
+          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
+          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);
+        }
 
+      /* Compile a writer function and complete it using the current
+         environment.  */
+      if (type_struct_writer == PVM_NULL)
+        {
+          assert (!PKL_AST_TYPE_NAME (type_struct));
           PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
           if (PKL_AST_TYPE_S_UNION_P (type_struct))
-            RAS_FUNCTION_UNION_WRITER (writer_closure, type_struct);
+            RAS_FUNCTION_UNION_WRITER (type_struct_writer, type_struct);
           else
-            RAS_FUNCTION_STRUCT_WRITER (writer_closure, type_struct);
+            RAS_FUNCTION_STRUCT_WRITER (type_struct_writer, type_struct);
           PKL_GEN_POP_CONTEXT;
+        }
 
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, writer_closure); /* VAL 
CLS */
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, type_struct_writer); /* VAL 
CLS */
+        if (!PKL_AST_TYPE_NAME (type_struct))
           pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                  /* VAL 
CLS */
-        }
 
       /* Install the writer into the value.  */
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MSETW);                /* VAL */
@@ -3535,53 +3480,40 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_struct)
         s = ASTREF(s); pkl_ast_node_free (s);
       }
 
-      if (type_struct_constructor != PVM_NULL)
+      if (type_struct_constructor == PVM_NULL)
         {
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                        type_struct_constructor); /* SCT CLS */
-        }
-      else
-        {
-          /* Compile a constructor function and complete it using the
-             current environment.  */
-          pvm_val constructor_closure;
-
-          RAS_FUNCTION_STRUCT_CONSTRUCTOR (constructor_closure, type_struct);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, constructor_closure);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC); /* SCT CLS */
-
-          /* Since this is an anonymous struct, install the
-             constructor in it.  This is needed by other operations
-             like sseti.  */
-          PKL_AST_TYPE_S_CONSTRUCTOR (type_struct) = constructor_closure;
+          RAS_FUNCTION_STRUCT_CONSTRUCTOR (type_struct_constructor, 
type_struct);
+          /* We normally do not install closures in anonymous types,
+             but this one is needed by ssetc.  */
+          PKL_AST_TYPE_S_CONSTRUCTOR (type_struct) = type_struct_constructor;
         }
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, type_struct_constructor);
+      if (!PKL_AST_TYPE_NAME (type_struct))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC); /* SCT CLS */
 
       /* Call the constructor to get a new struct.  */
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);    /* NSCT */
 
-      /* Install a writer in the constructed struct.  This is needed
-         when the value is used as the right-hand-side to a
-         map-assignment operation.  */
+      /* Compile a writer function and complete it using the current
+         environment.  */
       if (type_struct_writer == PVM_NULL)
         {
-          /* The struct type is anonymous and doesn't have a writer.
-             Compile one in this environment.  */
-
+          assert (!PKL_AST_TYPE_NAME (type_struct));
           PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
           {
             if (PKL_AST_TYPE_S_UNION_P (type_struct))
               RAS_FUNCTION_UNION_WRITER (type_struct_writer, type_struct);
             else
               RAS_FUNCTION_STRUCT_WRITER (type_struct_writer, type_struct);
-            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, type_struct_writer); /* 
CLS */
-            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);                      /* 
CLS */
-            pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_DROP);                     /* 
_ */
           }
           PKL_GEN_POP_CONTEXT;
         }
 
-      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                    type_struct_writer);          /* NCSCT CLS */
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, type_struct_writer);
+      if (!PKL_AST_TYPE_NAME (type_struct))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC); /* NCSCT CLS */
+
+      /* Install the writer into the value.  */
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_MSETW); /* NCSCT */
 
       /* And we are done.  */
@@ -3599,15 +3531,10 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_struct)
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_OVER);
 
       if (comparator_closure == PVM_NULL)
-        {
-          /* Compile a comparator function and complete it using the
-             current environment.  */
-          RAS_FUNCTION_STRUCT_COMPARATOR (comparator_closure, type_struct);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, comparator_closure);
-          pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
-        }
-      else
-        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, comparator_closure);
+        RAS_FUNCTION_STRUCT_COMPARATOR (comparator_closure, type_struct);
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, comparator_closure);
+      if (!PKL_AST_TYPE_NAME (type_struct))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
 
       /* Call the comparator.  */
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL); /* SCT1 SCT2 INT */
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 049f483d..1fd5f419 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -313,6 +313,7 @@ EXTRA_DIST = \
   poke.map/maps-structs-16.pk \
   poke.map/maps-structs-17.pk \
   poke.map/maps-structs-18.pk \
+  poke.map/maps-structs-19.pk \
   poke.map/maps-structs-anonfield-1.pk \
   poke.map/maps-structs-anonfield-2.pk \
   poke.map/maps-structs-anonfield-3.pk \
@@ -504,6 +505,7 @@ EXTRA_DIST = \
   poke.map/nsmap-3.pk \
   poke.map/nsmap-4.pk \
   poke.map/nsmap-5.pk \
+  poke.map/nsmap-6.pk \
   poke.map/strict-attr-1.pk \
   poke.map/strict-attr-2.pk \
   poke.map/strict-attr-3.pk \
@@ -528,6 +530,7 @@ EXTRA_DIST = \
   poke.map/write-unions-1.pk \
   poke.map/write-unions-2.pk \
   poke.map/write-unions-3.pk \
+  poke.map/write-structs-1.pk \
   poke.pickles/pickles.exp \
   poke.pickles/argp-test.pk \
   poke.pickles/color-test.pk \
@@ -1717,6 +1720,9 @@ EXTRA_DIST = \
   poke.pkl/scons-62.pk \
   poke.pkl/scons-63.pk \
   poke.pkl/scons-64.pk \
+  poke.pkl/scons-65.pk \
+  poke.pkl/scons-66.pk \
+  poke.pkl/scons-67.pk \
   poke.pkl/scons-anon-field-1.pk \
   poke.pkl/scons-anon-field-2.pk \
   poke.pkl/scons-anon-field-3.pk \
diff --git a/testsuite/poke.map/maps-structs-19.pk 
b/testsuite/poke.map/maps-structs-19.pk
new file mode 100644
index 00000000..bf84d2c8
--- /dev/null
+++ b/testsuite/poke.map/maps-structs-19.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+type Foo =
+  struct
+  {
+    type Record = struct { };
+    Record rec;
+  };
+
+/* { dg-command {Foo @ 2#B} } */
+/* { dg-output "Foo \{rec=Record \{\}\}" } */
diff --git a/testsuite/poke.map/nsmap-6.pk b/testsuite/poke.map/nsmap-6.pk
new file mode 100644
index 00000000..aacf1a32
--- /dev/null
+++ b/testsuite/poke.map/nsmap-6.pk
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x00 0x00 0x00  0x00 0x00 0x00 0x00   0x00 0x00 0x00 
0x00} } */
+
+type S = struct { struct { uint<8> x; } b; };
+
+/* { dg-command { .set obase 16 } } */
+/* { dg-command { var s = S @! 1#B } } */
+/* { dg-command { s.b.x = 3 } } */
+/* { dg-command { byte @ 1#B } } */
+/* { dg-output "0x3UB" } */
diff --git a/testsuite/poke.map/write-structs-1.pk 
b/testsuite/poke.map/write-structs-1.pk
new file mode 100644
index 00000000..99eeb4f0
--- /dev/null
+++ b/testsuite/poke.map/write-structs-1.pk
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x00 0x00 0x00  0x00 0x00 0x00 0x00   0x00 0x00 0x00 
0x00} } */
+
+type S = struct { struct { uint<8> x; } b; };
+
+/* { dg-command { .set obase 16 } } */
+/* { dg-command { var s = S @ 1#B } } */
+/* { dg-command { s.b.x = 3 } } */
+/* { dg-command { byte @ 1#B } } */
+/* { dg-output "0x3UB" } */
diff --git a/testsuite/poke.pkl/scons-65.pk b/testsuite/poke.pkl/scons-65.pk
new file mode 100644
index 00000000..7d230ee2
--- /dev/null
+++ b/testsuite/poke.pkl/scons-65.pk
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+type Foo =
+  struct
+  {
+    offset<uint<32>, B> rec_size;
+    uint<32> num_recs;
+
+    type Record = struct { uint<8> a; };
+
+    Record [rec_size * num_recs] recs;
+  };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command {Foo { rec_size = 1#B, num_recs = 1 } } } */
+/* { dg-output "Foo \{rec_size=0x1U#B,num_recs=0x1U,recs=\\\[Record 
\{a=0x0UB\}\\\]\}" } */
diff --git a/testsuite/poke.pkl/scons-66.pk b/testsuite/poke.pkl/scons-66.pk
new file mode 100644
index 00000000..d1b89740
--- /dev/null
+++ b/testsuite/poke.pkl/scons-66.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+type Foo =
+  struct
+  {
+    byte[2] d;
+    byte c : c == d[0] + d[1];
+  };
+
+/* { dg-command {var f = Foo {}} } */
+/* { dg-command {try f.d = [2UB,3UB]; catch if E_constraint { printf 
"caught\n"; } } } */
+/* { dg-output "caught" } */
diff --git a/testsuite/poke.pkl/scons-67.pk b/testsuite/poke.pkl/scons-67.pk
new file mode 100644
index 00000000..8a20c089
--- /dev/null
+++ b/testsuite/poke.pkl/scons-67.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+type S =
+  struct
+  {
+    int nbytes;
+    type Array = byte[nbytes];
+    Array bytes;
+  };
+
+/* { dg-command {S { nbytes = 2}} } */
+/* { dg-output "S \{nbytes=2,bytes=\\\[0UB,0UB\\\]\}" } */
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]