poke-devel
[Top][All Lists]
Advanced

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

[COMMITTED] pkl: support nested integral structs


From: Jose E. Marchesi
Subject: [COMMITTED] pkl: support nested integral structs
Date: Thu, 06 Jan 2022 14:09:32 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

This commit expands the support for integral structs to support
nesting them.  This is now supported:

type Foo =
  struct int<32>
  {
    struct int<16> { byte a; byte b; } la;
    uint<16> le;
  };

Mappers, writers, integrators and deintegrators have been adapted
accordingly.

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

        * libpoke/pkl-ast.h: Prototype for pkl_ast_sizeof_integral_type.
        * libpoke/pkl-ast.c (pkl_ast_sizeof_integral_type): New function.
        * libpoke/pkl-typify.c (pkl_typify1_ps_type_struct): Allow
        integral structs nested in other integral structs.
        * libpoke/pkl-gen.h (PKL_GEN_CTX_IN_INTEGRATOR): Define.
        (PKL_GEN_CTX_IN_DEINTEGRATOR): Likewise.
        * libpoke/pkl-gen.c (pkl_gen_pr_decl): Use a dedicated context
        when compiling struct type integrators.
        (pkl_gen_pr_cast): Likewise.
        (pkl_gen_pr_type_struct): Add in_integrator and in_deintegrator
        cases.
        * libpoke/pkl-gen.pks (struct_field_extractor): Support nested
        integral structs.
        (struct_field_inserter): Likewise.
        (struct_writer): Likewise.
        (struct_integrator): Likewise.
        (deint_extract_field_value): Likewise.
        (struct_deintegrator): Likewise.
        * testsuite/poke.pkl/int-struct-type-diag-9.pk: Rewrite test.
        * testsuite/poke.pkl/int-struct-type-diag-15.pk: New test.
        * testsuite/poke.pkl/int-struct-3.pk: Likewise.
        * testsuite/poke.pkl/int-struct-4.pk: Likewise.
        * testsuite/poke.map/maps-int-structs-29.pk: Likewise.
        * testsuite/poke.pkl/scons-int-struct-5.pk: Likewise.
        * testsuite/poke.pkl/deint-struct-10.pk: Likewise.
        * testsuite/poke.pkl/deint-struct-11.pk: Likewise.
        * testsuite/poke.map/ass-map-24.pk: Likewise.
        * testsuite/poke.map/asss-map-25.pk: Likewise.
        * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
---
 ChangeLog                                     | 32 ++++++++++
 libpoke/pkl-ast.c                             | 23 +++++++
 libpoke/pkl-ast.h                             |  2 +
 libpoke/pkl-gen.c                             | 92 +++++++++++----------------
 libpoke/pkl-gen.h                             |  2 +
 libpoke/pkl-gen.pks                           | 56 ++++++++++++++--
 libpoke/pkl-typify.c                          | 16 ++---
 testsuite/Makefile.am                         |  9 +++
 testsuite/poke.map/ass-map-24.pk              | 14 ++++
 testsuite/poke.map/ass-map-25.pk              | 12 ++++
 testsuite/poke.map/maps-int-structs-29.pk     | 24 +++++++
 testsuite/poke.pkl/deint-struct-10.pk         |  7 ++
 testsuite/poke.pkl/deint-struct-11.pk         |  7 ++
 testsuite/poke.pkl/int-struct-3.pk            |  4 ++
 testsuite/poke.pkl/int-struct-4.pk            |  9 +++
 testsuite/poke.pkl/int-struct-type-diag-15.pk | 13 ++++
 testsuite/poke.pkl/int-struct-type-diag-9.pk  | 13 ++--
 testsuite/poke.pkl/scons-int-struct-5.pk      | 11 ++++
 18 files changed, 268 insertions(+), 78 deletions(-)
 create mode 100644 testsuite/poke.map/ass-map-24.pk
 create mode 100644 testsuite/poke.map/ass-map-25.pk
 create mode 100644 testsuite/poke.map/maps-int-structs-29.pk
 create mode 100644 testsuite/poke.pkl/deint-struct-10.pk
 create mode 100644 testsuite/poke.pkl/deint-struct-11.pk
 create mode 100644 testsuite/poke.pkl/int-struct-3.pk
 create mode 100644 testsuite/poke.pkl/int-struct-4.pk
 create mode 100644 testsuite/poke.pkl/int-struct-type-diag-15.pk
 create mode 100644 testsuite/poke.pkl/scons-int-struct-5.pk

diff --git a/ChangeLog b/ChangeLog
index c54519cb..f4f1db1a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2022-01-06  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * libpoke/pkl-ast.h: Prototype for pkl_ast_sizeof_integral_type.
+       * libpoke/pkl-ast.c (pkl_ast_sizeof_integral_type): New function.
+       * libpoke/pkl-typify.c (pkl_typify1_ps_type_struct): Allow
+       integral structs nested in other integral structs.
+       * libpoke/pkl-gen.h (PKL_GEN_CTX_IN_INTEGRATOR): Define.
+       (PKL_GEN_CTX_IN_DEINTEGRATOR): Likewise.
+       * libpoke/pkl-gen.c (pkl_gen_pr_decl): Use a dedicated context
+       when compiling struct type integrators.
+       (pkl_gen_pr_cast): Likewise.
+       (pkl_gen_pr_type_struct): Add in_integrator and in_deintegrator
+       cases.
+       * libpoke/pkl-gen.pks (struct_field_extractor): Support nested
+       integral structs.
+       (struct_field_inserter): Likewise.
+       (struct_writer): Likewise.
+       (struct_integrator): Likewise.
+       (deint_extract_field_value): Likewise.
+       (struct_deintegrator): Likewise.
+       * testsuite/poke.pkl/int-struct-type-diag-9.pk: Rewrite test.
+       * testsuite/poke.pkl/int-struct-type-diag-15.pk: New test.
+       * testsuite/poke.pkl/int-struct-3.pk: Likewise.
+       * testsuite/poke.pkl/int-struct-4.pk: Likewise.
+       * testsuite/poke.map/maps-int-structs-29.pk: Likewise.
+       * testsuite/poke.pkl/scons-int-struct-5.pk: Likewise.
+       * testsuite/poke.pkl/deint-struct-10.pk: Likewise.
+       * testsuite/poke.pkl/deint-struct-11.pk: Likewise.
+       * testsuite/poke.map/ass-map-24.pk: Likewise.
+       * testsuite/poke.map/asss-map-25.pk: Likewise.
+       * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
+
 2022-01-05  Jose E. Marchesi  <jemarch@gnu.org>
 
        * testsuite/Makefile.am (EXTRA_DIST): Add missing test.
diff --git a/libpoke/pkl-ast.c b/libpoke/pkl-ast.c
index 7212b06a..86944065 100644
--- a/libpoke/pkl-ast.c
+++ b/libpoke/pkl-ast.c
@@ -1060,6 +1060,29 @@ pkl_ast_sizeof_type (pkl_ast ast, pkl_ast_node type)
   return res;
 }
 
+/* Return the size (in bits) of values of the given type, which must
+   be an integral, offset or integral struct type.  */
+
+size_t
+pkl_ast_sizeof_integral_type (pkl_ast_node type)
+{
+  if (PKL_AST_TYPE_CODE (type) == PKL_TYPE_INTEGRAL)
+    return PKL_AST_TYPE_I_SIZE (type);
+  else if (PKL_AST_TYPE_CODE (type) == PKL_TYPE_OFFSET)
+    {
+      pkl_ast_node base_type = PKL_AST_TYPE_O_BASE_TYPE (type);
+      return PKL_AST_TYPE_I_SIZE (base_type);
+    }
+  else if (PKL_AST_TYPE_CODE (type) == PKL_TYPE_STRUCT
+           && PKL_AST_TYPE_S_ITYPE (type) != NULL)
+    {
+      pkl_ast_node itype = PKL_AST_TYPE_S_ITYPE (type);
+      return PKL_AST_TYPE_I_SIZE (itype);
+    }
+  else
+    assert (0);
+}
+
 /* Return 1 if the given TYPE can be mapped in IO.  0 otherwise.  */
 
 int
diff --git a/libpoke/pkl-ast.h b/libpoke/pkl-ast.h
index 96a4cb8c..31066b9e 100644
--- a/libpoke/pkl-ast.h
+++ b/libpoke/pkl-ast.h
@@ -1023,6 +1023,8 @@ int pkl_ast_type_promoteable_p (pkl_ast_node ft, 
pkl_ast_node tt,
 
 pkl_ast_node pkl_ast_sizeof_type (pkl_ast ast, pkl_ast_node type);
 
+size_t pkl_ast_sizeof_integral_type (pkl_ast_node type);
+
 int pkl_ast_type_is_complete (pkl_ast_node type);
 
 void pkl_ast_array_type_remove_bounders (pkl_ast_node type);
diff --git a/libpoke/pkl-gen.c b/libpoke/pkl-gen.c
index 1a3fb31c..846155ad 100644
--- a/libpoke/pkl-gen.c
+++ b/libpoke/pkl-gen.c
@@ -271,11 +271,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_decl)
                   {
                     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);
+                    PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_INTEGRATOR);
                     RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure,
                                                     type_struct);
                     PKL_GEN_POP_CONTEXT;
@@ -291,11 +287,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_decl)
                   {
                     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);
+                    PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
                     RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure,
                                                       type_struct);
                     PKL_GEN_POP_CONTEXT;
@@ -2234,32 +2226,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_cast)
   else if (PKL_AST_TYPE_CODE (to_type) == PKL_TYPE_STRUCT
            && PKL_AST_TYPE_CODE (from_type) == PKL_TYPE_INTEGRAL)
     {
-      pkl_ast_node itype = PKL_AST_TYPE_S_ITYPE (to_type);
-
-      /* This is guaranteed as per typify.  */
-      assert (itype);
-
-      /* Make sure the struct type has a deintegrator.  */
-      if (PKL_AST_TYPE_S_DEINTEGRATOR (to_type) == PVM_NULL)
-        {
-          pvm_val deintegrator_closure;
-
-          /* See note about in_writer in pkl_gen_pr_decl.  */
-          PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
-          RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure,
-                                            to_type);           /* 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;
-
-          PKL_AST_TYPE_S_DEINTEGRATOR (to_type) = deintegrator_closure;
-        }
-
-      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                    PKL_AST_TYPE_S_DEINTEGRATOR (to_type));
-      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);
+      PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
+      PKL_PASS_SUBPASS (to_type);
+      PKL_GEN_POP_CONTEXT;
     }
   else if (PKL_AST_TYPE_CODE (to_type) == PKL_TYPE_INTEGRAL
            && PKL_AST_TYPE_CODE (from_type) == PKL_TYPE_STRUCT)
@@ -2269,27 +2238,10 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_cast)
       /* This is guaranteed as per typify.  */
       assert (itype);
 
-      /* Make sure the struct type has an integrator.  */
-      if (PKL_AST_TYPE_S_INTEGRATOR (from_type) == PVM_NULL)
-        {
-          pvm_val integrator_closure;
-
-          /* See note about in_writer in pkl_gen_pr_decl.  */
-          PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_WRITER);
-          RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure,
-                                          from_type);           /* 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 (from_type) = integrator_closure;
-        }
+      PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_INTEGRATOR);
+      PKL_PASS_SUBPASS (from_type);
+      PKL_GEN_POP_CONTEXT;
 
-      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH,
-                    PKL_AST_TYPE_S_INTEGRATOR (from_type));
-      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);
       pkl_asm_insn (pasm, PKL_INSN_NTON, itype, to_type);
       pkl_asm_insn (pasm, PKL_INSN_NIP);
     }
@@ -3582,6 +3534,34 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_type_struct)
       pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL); /* _ */
       PKL_PASS_BREAK;
     }
+  else if (PKL_GEN_IN_CTX_P (PKL_GEN_CTX_IN_INTEGRATOR))
+    {
+      pkl_ast_node type_struct = PKL_PASS_NODE;
+      pvm_val integrator_closure = PKL_AST_TYPE_S_INTEGRATOR (type_struct);
+
+      if (integrator_closure == PVM_NULL)
+        RAS_FUNCTION_STRUCT_INTEGRATOR (integrator_closure, type_struct);
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, integrator_closure);
+      if (!PKL_AST_TYPE_NAME (type_struct))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
+
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);
+      PKL_PASS_BREAK;
+    }
+  else if (PKL_GEN_IN_CTX_P (PKL_GEN_CTX_IN_DEINTEGRATOR))
+    {
+      pkl_ast_node type_struct = PKL_PASS_NODE;
+      pvm_val deintegrator_closure = PKL_AST_TYPE_S_DEINTEGRATOR (type_struct);
+
+      if (deintegrator_closure == PVM_NULL)
+        RAS_FUNCTION_STRUCT_DEINTEGRATOR (deintegrator_closure, type_struct);
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PUSH, deintegrator_closure);
+      if (!PKL_AST_TYPE_NAME (type_struct))
+        pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_PEC);
+
+      pkl_asm_insn (PKL_GEN_ASM, PKL_INSN_CALL);
+      PKL_PASS_BREAK;
+    }
   else if (PKL_GEN_IN_CTX_P (PKL_GEN_CTX_IN_TYPE))
     {
       /* Do nothing.  See PS hook.  */
diff --git a/libpoke/pkl-gen.h b/libpoke/pkl-gen.h
index a2315dec..1853b868 100644
--- a/libpoke/pkl-gen.h
+++ b/libpoke/pkl-gen.h
@@ -112,6 +112,8 @@ typedef struct pkl_gen_payload *pkl_gen_payload;
 #define PKL_GEN_CTX_IN_FUNCALL      0x200
 #define PKL_GEN_CTX_IN_TYPE         0x400
 #define PKL_GEN_CTX_IN_FORMATER     0x800
+#define PKL_GEN_CTX_IN_INTEGRATOR   0x1000
+#define PKL_GEN_CTX_IN_DEINTEGRATOR 0x2000
 
 extern struct pkl_phase pkl_phase_gen;
 
diff --git a/libpoke/pkl-gen.pks b/libpoke/pkl-gen.pks
index e1c198b3..f47dd430 100644
--- a/libpoke/pkl-gen.pks
+++ b/libpoke/pkl-gen.pks
@@ -671,7 +671,8 @@
         nip                             ; STRICT BOFF IVAL SCOUNT(U)
         ;; Using the calculated bit-count, extract the value of the
         ;; field from the struct ival.  The resulting value is converted
-        ;; to the type of the field. (base type if the field is offset.)
+        ;; to the type of the field. (base type if the field is offset,
+        ;; itype if the field is an integral struct.)
         sr @struct_itype
         nip2                            ; STRICT BOFF VAL
    .c if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET)
@@ -679,13 +680,19 @@
         .let @base_type = PKL_AST_TYPE_O_BASE_TYPE (@field_type)
         nton @struct_itype, @base_type
    .c }
+   .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
+   .c {
+        .let @field_itype = PKL_AST_TYPE_S_ITYPE (@field_type)
+        nton @struct_itype, @field_itype
+   .c }
    .c else
    .c {
         nton @struct_itype, @field_type
    .c }
         nip                             ; STRICT BOFF VALC
         ;; At this point the value of the field is in the
-        ;; stack.  If the field is an offset, construct it.
+        ;; stack.  The field may be an integral or an offset
+        ;; or an integral struct.
    .c if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET)
    .c {
         .let @offset_unit = PKL_AST_TYPE_O_UNIT (@field_type)
@@ -693,6 +700,12 @@
         push #unit                      ; STRICT BOFF MVALC UNIT
         mko                             ; STRICT BOFF VALC
    .c }
+   .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
+   .c {
+        .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
+        .c PKL_PASS_SUBPASS (@field_type);
+        .c PKL_GEN_POP_CONTEXT;
+   .c }
         dup                             ; STRICT BOFF VALC VALC
         regvar $val                     ; STRICT BOFF VALC
         .c vars_registered++;
@@ -879,6 +892,8 @@
  .c     size_t field_type_size
  .c        = (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET
  .c           ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_O_BASE_TYPE (@field_type))
+ .c           : PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT
+ .c           ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_S_ITYPE (@field_type))
  .c           : PKL_AST_TYPE_I_SIZE (@field_type));
         .let #fieldw = pvm_make_ulong (field_type_size, 64);
         ;; Note that at this point the field is assured to be
@@ -1540,6 +1555,16 @@
         nip                     ; SCT I (IVALW-REOFF-FIELDW) EVAL [IVAL]
         nton @base_type, @struct_itype
  .c   }
+ .c   else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
+ .c   {
+        ;; EVAL is an integral struct.  Integrate it to get its integral
+        ;; value.
+        .let @field_itype = PKL_AST_TYPE_S_ITYPE (@field_type)
+        .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_INTEGRATOR);
+        .c PKL_PASS_SUBPASS (@field_type);
+        .c PKL_GEN_POP_CONTEXT;
+        nton @field_itype, @struct_itype
+ .c   }
  .c   else
  .c   {
         nton @field_type, @struct_itype
@@ -1651,6 +1676,8 @@
  .c     size_t field_type_size
  .c        = (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET
  .c           ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_O_BASE_TYPE (@field_type))
+ .c           : PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT
+ .c           ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_S_ITYPE (@field_type))
  .c           : PKL_AST_TYPE_I_SIZE (@field_type));
         .let #fieldw = pvm_make_ulong (field_type_size, 64);
         pushvar $ivalue          ; SCT I IVAL
@@ -1804,6 +1831,8 @@
  .c     size_t field_type_size
  .c        = (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET
  .c           ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_O_BASE_TYPE (@field_type))
+ .c           : PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT
+ .c           ? PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_S_ITYPE (@field_type))
  .c           : PKL_AST_TYPE_I_SIZE (@field_type));
         .let #fieldw = pvm_make_ulong (field_type_size, 64);
         pushvar $ivalue          ; SCT I IVAL
@@ -1830,8 +1859,11 @@
 
         .macro deint_extract_field_value @uint64_type @itype @field_type 
#bit_offset
         .let @field_type = PKL_AST_STRUCT_TYPE_FIELD_TYPE (@field)
-        .let @field_int_type = PKL_AST_TYPE_CODE (@field_type) == 
PKL_TYPE_OFFSET ? \
-                               PKL_AST_TYPE_O_BASE_TYPE (@field_type) : 
@field_type
+        .let @field_int_type = (PKL_AST_TYPE_CODE (@field_type) == 
PKL_TYPE_OFFSET \
+                                ? PKL_AST_TYPE_O_BASE_TYPE (@field_type) \
+                                : PKL_AST_TYPE_CODE (@field_type) == 
PKL_TYPE_STRUCT \
+                                ? PKL_AST_TYPE_S_ITYPE (@field_type) \
+                                : @field_type)
  .c     size_t field_type_size = PKL_AST_TYPE_I_SIZE (@field_int_type);
  .c     size_t itype_bits = PKL_AST_TYPE_I_SIZE (@itype);
         ;; Field extraction:
@@ -1845,7 +1877,8 @@
         nip2
         ;; Convert the extracted value to the type of the field. If
         ;; the field is an offset, set an offset with the extracted
-        ;; value as magnitude and same unit.
+        ;; value as magnitude and same unit.  If the field is an
+        ;; integral struct, call its deintegrator.
         nton @uint64_type, @field_int_type
         nip
  .c if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_OFFSET)
@@ -1855,6 +1888,12 @@
         push #unit
         mko
  .c }
+ .c else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
+ .c {
+        .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
+        .c PKL_PASS_SUBPASS (@field_type);
+        .c PKL_GEN_POP_CONTEXT;
+ .c }
         .end
 
 ;;; RAS_FUNCTION_STRUCT_DEINTEGRATOR @type_struct
@@ -1896,8 +1935,11 @@
  .c       continue;
         .let @field_type = PKL_AST_STRUCT_TYPE_FIELD_TYPE (@field)
  .c     size_t field_type_size
- .c       = PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_CODE (@field_type) == 
PKL_TYPE_OFFSET
- .c         ? PKL_AST_TYPE_O_BASE_TYPE (@field_type) : @field_type);
+ .c       = (PKL_AST_TYPE_I_SIZE (PKL_AST_TYPE_CODE (@field_type) == 
PKL_TYPE_OFFSET
+ .c                               ? PKL_AST_TYPE_O_BASE_TYPE (@field_type)
+ .c                               : PKL_AST_TYPE_CODE (@field_type) == 
PKL_TYPE_STRUCT
+ .c                               ? PKL_AST_TYPE_S_ITYPE (@field_type)
+ .c                               : @field_type));
         ;; Anonymous fields are not handled in this loop, but we have
         ;; to advance the offset nevertheless.
         .let @type_field_name = PKL_AST_STRUCT_TYPE_FIELD_NAME (@field)
diff --git a/libpoke/pkl-typify.c b/libpoke/pkl-typify.c
index ad8da7fc..25fbff8c 100644
--- a/libpoke/pkl-typify.c
+++ b/libpoke/pkl-typify.c
@@ -1771,8 +1771,8 @@ PKL_PHASE_END_HANDLER
 /* The type associated with an integral struct shall be integral.
 
    The fields in an integral struct type shall be all of integral or
-   offset types (_not_ including other integral structs) and the total
-   int size shall match the sum of the sizes of all the fields.
+   offset types (including other integral structs) and the total int
+   size shall match the sum of the sizes of all the fields.
 
    The total size declared in the integral struct should exactly match
    the size of all the contained fields.
@@ -1820,7 +1820,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
                 = PKL_AST_STRUCT_TYPE_FIELD_TYPE (field);
 
               if (PKL_AST_TYPE_CODE (ftype) != PKL_TYPE_INTEGRAL
-                  && PKL_AST_TYPE_CODE (ftype) != PKL_TYPE_OFFSET)
+                  && PKL_AST_TYPE_CODE (ftype) != PKL_TYPE_OFFSET
+                  && !(PKL_AST_TYPE_CODE (ftype) == PKL_TYPE_STRUCT
+                       && PKL_AST_TYPE_S_ITYPE (ftype) != NULL))
                 {
                   PKL_ERROR (PKL_AST_LOC (field),
                              "invalid field in integral struct");
@@ -1844,13 +1846,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_struct)
                   PKL_PASS_ERROR;
                 }
 
-              if (PKL_AST_TYPE_CODE (ftype) == PKL_TYPE_INTEGRAL)
-                fields_int_size += PKL_AST_TYPE_I_SIZE (ftype);
-              else
-                {
-                  pkl_ast_node base_type = PKL_AST_TYPE_O_BASE_TYPE (ftype);
-                  fields_int_size += PKL_AST_TYPE_I_SIZE (base_type);
-                }
+              fields_int_size += pkl_ast_sizeof_integral_type (ftype);
             }
         }
 
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 31cc7ba5..754c91f5 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -135,6 +135,8 @@ EXTRA_DIST = \
   poke.map/ass-map-21.pk \
   poke.map/ass-map-22.pk \
   poke.map/ass-map-23.pk \
+  poke.map/ass-map-24.pk \
+  poke.map/ass-map-25.pk \
   poke.map/ass-map-struct-int-1.pk \
   poke.map/func-map-1.pk \
   poke.map/func-map-2.pk \
@@ -264,6 +266,7 @@ EXTRA_DIST = \
   poke.map/maps-int-structs-26.pk \
   poke.map/maps-int-structs-27.pk \
   poke.map/maps-int-structs-28.pk \
+  poke.map/maps-int-structs-29.pk \
   poke.map/maps-ios-1.pk \
   poke.map/maps-ios-2.pk \
   poke.map/maps-ios-3.pk \
@@ -930,6 +933,8 @@ EXTRA_DIST = \
   poke.pkl/defvar-5.pk \
   poke.pkl/defvar-6.pk \
   poke.pkl/deint-struct-1.pk \
+  poke.pkl/deint-struct-10.pk \
+  poke.pkl/deint-struct-11.pk \
   poke.pkl/deint-struct-2.pk \
   poke.pkl/deint-struct-3.pk \
   poke.pkl/deint-struct-4.pk \
@@ -1203,6 +1208,8 @@ EXTRA_DIST = \
   poke.pkl/in-diag-3.pk \
   poke.pkl/int-struct-1.pk \
   poke.pkl/int-struct-2.pk \
+  poke.pkl/int-struct-3.pk \
+  poke.pkl/int-struct-4.pk \
   poke.pkl/int-struct-type-diag-1.pk \
   poke.pkl/int-struct-type-diag-2.pk \
   poke.pkl/int-struct-type-diag-3.pk \
@@ -1217,6 +1224,7 @@ EXTRA_DIST = \
   poke.pkl/int-struct-type-diag-12.pk \
   poke.pkl/int-struct-type-diag-13.pk \
   poke.pkl/int-struct-type-diag-14.pk \
+  poke.pkl/int-struct-type-diag-15.pk \
   poke.pkl/int-type-diag-1.pk \
   poke.pkl/int-type-diag-2.pk \
   poke.pkl/int-type.pk \
@@ -1741,6 +1749,7 @@ EXTRA_DIST = \
   poke.pkl/scons-int-struct-2.pk \
   poke.pkl/scons-int-struct-3.pk \
   poke.pkl/scons-int-struct-4.pk \
+  poke.pkl/scons-int-struct-5.pk \
   poke.pkl/scons-label-1.pk \
   poke.pkl/scons-offset-1.pk \
   poke.pkl/scons-offset-2.pk \
diff --git a/testsuite/poke.map/ass-map-24.pk b/testsuite/poke.map/ass-map-24.pk
new file mode 100644
index 00000000..db0e6f64
--- /dev/null
+++ b/testsuite/poke.map/ass-map-24.pk
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x00 0x00 0x00  0x00 0x00 0x00 0x00   0x00 0x00 0x00 
0x00} } */
+
+type Bar = struct int<24> { byte b; byte c; byte d; };
+
+type Foo = struct uint<32> { byte a; Bar e; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command {.set endian little} } */
+/* { dg-command {Foo @ 1#B = Foo { a = 0xde, e = Bar { b = 0xad, c = 0xbe, d = 
0xef }}} } */
+/* { dg-command { int @ 1#B } } */
+/* { dg-output "0xdeadbeef" } */
+/* { dg-command { byte[4] @ 1#B } } */
+/* { dg-output"\n\\\[0xefUB,0xbeUB,0xadUB,0xdeUB\\\]" } */
diff --git a/testsuite/poke.map/ass-map-25.pk b/testsuite/poke.map/ass-map-25.pk
new file mode 100644
index 00000000..d7ddc182
--- /dev/null
+++ b/testsuite/poke.map/ass-map-25.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x00 0x00 0x00 0x00  0x00 0x00 0x00 0x00   0x00 0x00 0x00 
0x00} } */
+
+type Bar = struct int<32> { uint<16> a; byte b; byte c; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command {.set endian little} } */
+/* { dg-command {Bar @ 1#B = Bar { a = 0xdead, b = 0xbe, c = 0xef }} } */
+/* { dg-command { int @ 1#B } } */
+/* { dg-output "0xdeadbeef" } */
+/* { dg-command { byte[4] @ 1#B } } */
+/* { dg-output"\n\\\[0xefUB,0xbeUB,0xadUB,0xdeUB\\\]" } */
diff --git a/testsuite/poke.map/maps-int-structs-29.pk 
b/testsuite/poke.map/maps-int-structs-29.pk
new file mode 100644
index 00000000..0317fa2d
--- /dev/null
+++ b/testsuite/poke.map/maps-int-structs-29.pk
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+type Foo =
+  struct int<32>
+  {
+    struct int<16>
+    {
+      byte a;
+      byte b;
+    } la;
+
+   uint<16> le;
+  };
+
+/* { dg-command { .set obase 16 } } */
+/* { dg-command { .set endian little } } */
+/* { dg-command { var f = Foo @ 0#B } } */
+/* { dg-command { f.la.a } } */
+/* { dg-output "0x40UB" } */
+/* { dg-command { f.la.b } } */
+/* { dg-output "\n0x30UB" } */
+/* { dg-command { f.le } } */
+/* { dg-output "\n0x2010UH" } */
diff --git a/testsuite/poke.pkl/deint-struct-10.pk 
b/testsuite/poke.pkl/deint-struct-10.pk
new file mode 100644
index 00000000..2d253ecc
--- /dev/null
+++ b/testsuite/poke.pkl/deint-struct-10.pk
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+
+type Foo = struct int<32> { struct int<16> { byte a; byte b; } la; uint<16> 
le; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command { 0xdeadbeef as Foo } } */
+/* { dg-output "Foo \{la=struct \{a=0xdeUB,b=0xadUB\},le=0xbeefUH\}" } */
diff --git a/testsuite/poke.pkl/deint-struct-11.pk 
b/testsuite/poke.pkl/deint-struct-11.pk
new file mode 100644
index 00000000..49d8bd00
--- /dev/null
+++ b/testsuite/poke.pkl/deint-struct-11.pk
@@ -0,0 +1,7 @@
+/* { dg-do run } */
+
+type Foo = struct int<32> { struct int<16> { byte a; struct uint<8> { byte x; 
} b; } la; uint<16> le; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command { 0xdeadbeef as Foo } } */
+/* { dg-output "Foo \{la=struct \{a=0xdeUB,b=struct 
\{x=0xadUB\}\},le=0xbeefUH\}" } */
diff --git a/testsuite/poke.pkl/int-struct-3.pk 
b/testsuite/poke.pkl/int-struct-3.pk
new file mode 100644
index 00000000..8c68fb10
--- /dev/null
+++ b/testsuite/poke.pkl/int-struct-3.pk
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+
+type Bar = struct int<16> { int<8> a; int<8> b; };
+type Foo = struct int<32> { Bar la; int<16> c; };
diff --git a/testsuite/poke.pkl/int-struct-4.pk 
b/testsuite/poke.pkl/int-struct-4.pk
new file mode 100644
index 00000000..0de71b17
--- /dev/null
+++ b/testsuite/poke.pkl/int-struct-4.pk
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+
+type Foo =
+  struct int<32>
+  {
+    struct int<16> { int<8> a; int<8> b; } la;
+    int<16> c;
+  };
diff --git a/testsuite/poke.pkl/int-struct-type-diag-15.pk 
b/testsuite/poke.pkl/int-struct-type-diag-15.pk
new file mode 100644
index 00000000..4c61bb4c
--- /dev/null
+++ b/testsuite/poke.pkl/int-struct-type-diag-15.pk
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+type Foo =
+  struct int<32>
+  {
+    struct int<10>  /* { dg-error "invalid total size" } */
+    {
+      byte a;
+      byte b;
+    } la;
+
+   uint<16> le;
+  };
diff --git a/testsuite/poke.pkl/int-struct-type-diag-9.pk 
b/testsuite/poke.pkl/int-struct-type-diag-9.pk
index 4108f6d7..f6075c17 100644
--- a/testsuite/poke.pkl/int-struct-type-diag-9.pk
+++ b/testsuite/poke.pkl/int-struct-type-diag-9.pk
@@ -1,10 +1,13 @@
 /* { dg-do compile } */
 
 type Foo =
-  struct uint<32>
-  { struct int<15> /* { dg-error "invalid field" } */
+  struct int<33> /* { dg-error "invalid total size" } */
+  {
+    struct int<16>
     {
-      int<15> c;
-    } a;
-    int<17> b;
+      byte a;
+      byte b;
+    } la;
+
+   uint<16> le;
   };
diff --git a/testsuite/poke.pkl/scons-int-struct-5.pk 
b/testsuite/poke.pkl/scons-int-struct-5.pk
new file mode 100644
index 00000000..eb5923b8
--- /dev/null
+++ b/testsuite/poke.pkl/scons-int-struct-5.pk
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+
+type Foo = struct int<32> { struct int<16> { byte a; byte b; } la; uint<16> 
le; };
+
+/* { dg-command {.set obase 16} } */
+/* { dg-command { var f = Foo { le = 0xffff } } } */
+/* { dg-command { f.la.b = 0x11 } } */
+/* { dg-command { +f } } */
+/* { dg-output "0x11ffff" } */
+/* { dg-command { f - 1 } } */
+/* { dg-output "\n0x11fffe" } */
-- 
2.11.0




reply via email to

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