poke-devel
[Top][All Lists]
Advanced

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

[PATCH v2 0/2] Add support for integral unions


From: Mohammad-Reza Nabipoor
Subject: [PATCH v2 0/2] Add support for integral unions
Date: Mon, 26 Sep 2022 02:49:23 +0330

Hi Jose.

I fixed the bug in struct_constructor and struct_deintegrator.
And also fixed your comments.

This is the changes from the previous version:


diff --git a/ChangeLog b/ChangeLog
index 7fd4baa4..a8fd753a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,9 @@
-2022-09-24  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
+2022-09-26  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
 
        * libpoke/pkl-tab.y (tokens): s/token/%token/.
-       * libpoke/pkl-typify.c (pkl_typify1_ps_type_struct): Handle integral 
unions.
+       * libpoke/pkl-typify.c (pkl_typify1_ps_cast): Handle integral
+       unions.
+       (pkl_typify1_ps_type_struct): Likewise.
        * libpoke/pkl-gen.c (pkl_gen_pr_type_struct): Likewise.
        (pkl_gen_pr_decl): Likewise.
        (pkl_gen_pr_cast): In cast from an integral type to struct type,
@@ -68,6 +70,13 @@
        * testsuite/poke.map/maps-int-union-5.pk: Likewise
        * testsuite/Makefile.am (EXTRA_DIST): Update.
 
+2022-09-26  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
+
+       * libpoke/pkl-gen.pks (function struct_constructor): Do not alter
+       items that are already on the stack because `raise' will restore
+       the height of stack and the caller will see garbage on the stack.
+       (function struct_deintegrator): Likewise.
+
 2022-09-24  Jose E. Marchesi  <jemarch@gnu.org>
 
        BZ 27481
diff --git a/libpoke/pkl-gen.pks b/libpoke/pkl-gen.pks
index ccb8694f..f1e0c8a0 100644
--- a/libpoke/pkl-gen.pks
+++ b/libpoke/pkl-gen.pks
@@ -1436,6 +1436,7 @@
         .function struct_constructor @type_struct
         prolog
         pushf 5
+        dup                     ; SCT SCT
         regvar $sct             ; SCT
         ;; Initialize $nfield to 0UL
         push ulong<64>0
@@ -1452,8 +1453,10 @@
         push ulong<64>1
         mko
         regvar $OFFSET
-        ;; The struct is not mapped, so set its bit-offset to 0UL.
-        push ulong<64>0          ; 0UL
+        ;; This is the offset of struct (used in mksct instruction at
+        ;; the end of this function), and because the struct is
+        ;; not mapped, set its bit-offset to 0UL.
+        push ulong<64>0         ; SCT 0UL
         ;; Iterate over the fields of the struct type.
  .c size_t vars_registered = 0;
         .let @field
@@ -1737,8 +1740,9 @@
         .c PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_TYPE);
         .c PKL_PASS_SUBPASS (@type_struct);
         .c PKL_GEN_POP_CONTEXT;
-                                ; null [OFF STR VAL]... NMETHOD NFIELD TYP
-        mksct                   ; SCT
+                                ; SCT 0UL [OFF STR VAL]... NMETHOD NFIELD TYP
+        mksct                   ; SCT SCT
+        nip                     ; SCT
         popf 1
         return
         .end
@@ -2060,7 +2064,6 @@
 ;;; passed in the stack.
 
         .function struct_integrator @type_struct
-  .c    assert (!PKL_AST_TYPE_S_UNION_P (@type_struct));
         prolog
         pushf 2
         regvar $sct             ; Argument
@@ -2117,7 +2120,6 @@
 ;;; passed in the stack.
 
         .function union_integrator @type_struct
-  .c    assert (PKL_AST_TYPE_S_UNION_P (@type_struct));
         prolog
         pushf 0
         .let @itype = PKL_AST_TYPE_S_ITYPE (@type_struct)
@@ -2140,6 +2142,11 @@
         pope
         nip2                     ; VAL
         .let @field_type = PKL_AST_STRUCT_TYPE_FIELD_TYPE (@field)
+        ;; Create the integral value based on the type of field.
+        ;; Due to simplicity of integration of unions (there's only one
+        ;; active field, no anonymous/absent field, etc.), I'm not
+        ;; re-using any code from struct_integrator to keep things
+        ;; simpler and more efficient.
   .c  if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_INTEGRAL)
   .c  {
         nton @field_type, @itype ; NUM IVAL
@@ -2158,10 +2165,6 @@
   .c    PKL_GEN_POP_CONTEXT;
         .let @field_itype = PKL_AST_TYPE_S_ITYPE (@field_type)
         nton @field_itype, @itype ; SCT IVAL
-  .c  }
-  .c  else
-  .c  {
-  .c    assert (0 && "unreachable reached!");
   .c  }
                                 ; VAL IVAL
         nip                     ; IVAL
@@ -2239,7 +2242,6 @@
 ;;; which convert the integer.
 
         .function struct_deintegrator @type_struct
-  .c    assert (!PKL_AST_TYPE_S_UNION_P (@type_struct));
         prolog
         pushf 2
         ;; Convert the value to deintegrate to an ulong<64> to ease
@@ -2247,9 +2249,15 @@
         .let @itype = PKL_AST_TYPE_S_ITYPE (@type_struct)
         .let @uint64_type = pkl_ast_make_integral_type (PKL_PASS_AST, 64, 0)
         .e zero_extend_64 @itype
-        regvar $ival
+        ;; If constraint violation exception happens during the
+        ;; construction of deintegrated struct, this is the right
+        ;; place to restore the stack.
+        push PVM_E_CONSTRAINT
+        pushe .constraint_failed
+        dup                     ; IVAL IVAL
+        regvar $ival            ; IVAL
         ;; This is the offset argument to the mksct instruction below.
-        push ulong<64>0         ; OFF
+        push ulong<64>0         ; IVAL OFF
         ;; Iterate over the struct named fields creating triplets for the
         ;; fields, whose value is extracted from IVAL.  We know that
         ;; IVAL has the same width than the struct fields all combined.
@@ -2280,30 +2288,32 @@
  .c     }
         .let #bit_offset = pvm_make_int (bit_offset, 32)
         ;; Extract the value for this field from IVAL
-        pushvar $ival           ; IVAL
+        pushvar $ival           ; IVAL IVAL
         .e deint_extract_field_value @uint64_type, @itype, @field_type, 
#bit_offset
         ;; Create the triplet with the converted value.
         .let #field_name = pvm_make_string (PKL_AST_IDENTIFIER_POINTER 
(@type_field_name))
         .let #field_offset = pvm_make_ulong (bit_offset, 64)
-        push #field_offset      ; CVAL OFFSET
-        push #field_name        ; CVAL OFFSET NAME
-        rot                     ; OFFSET NAME CVAL
+        push #field_offset      ; IVAL CVAL OFFSET
+        push #field_name        ; IVAL CVAL OFFSET NAME
+        rot                     ; IVAL OFFSET NAME CVAL
  .c     bit_offset += field_type_size;
  .c     i++;
  .c }
-                                ; OFF [TRIPLETS...]
+                                ; IVAL OFF [TRIPLETS...]
         .let #nfields = pvm_make_ulong (i, 64)
-        push ulong<64>0         ; OFF [TRIPLETS...] NMETHODS
-        push #nfields           ; OFF [TRIPLETS...] NMETHODS NFIELDS
+        push ulong<64>0         ; IVAL OFF [TRIPLETS...] NMETHODS
+        push #nfields           ; IVAL OFF [TRIPLETS...] NMETHODS NFIELDS
   .c    PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_TYPE);
   .c    PKL_PASS_SUBPASS (@type_struct);
   .c    PKL_GEN_POP_CONTEXT;
-                                ; OFF [TRIPLETS...] NMETHODS NFIELDS TYPE
+                                ; IVAL OFF [TRIPLETS...] NMETHODS NFIELDS TYPE
         mksct
   .c    PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_CONSTRUCTOR);
   .c    PKL_PASS_SUBPASS (@type_struct);
   .c    PKL_GEN_POP_CONTEXT;
-                                ; SCT
+                                ; IVAL SCT
+        pope
+        nip                     ; SCT
         ;; At this point the anonymous fields in the struct created above are
         ;; all zero.  This is because we coudln't include them in the argument
         ;; to the struct constructor.  So now we have to iterate over the
@@ -2342,6 +2352,8 @@
  .c }
         popf 1
         return
+.constraint_failed:
+        raise
         .end
 
 ;;; RAS_FUNCTION_UNION_DEINTEGRATOR @type_struct
@@ -2358,7 +2370,6 @@
 ;;; which convert the integer.
 
         .function union_deintegrator @type_struct
-  .c    assert (PKL_AST_TYPE_S_UNION_P (@type_struct));
         prolog
         pushf 0
         .let @itype = PKL_AST_TYPE_S_ITYPE (@type_struct)
@@ -2368,14 +2379,13 @@
   .c       @field = PKL_AST_CHAIN (@field))
   .c  {
         .label .alternative_failed
-        .label .construction_failed
-        .label .deintegration_failed
+        .label .constraint_failed
   .c  if (PKL_AST_CODE (@field) != PKL_AST_STRUCT_TYPE_FIELD)
   .c  {
   .c    continue;
   .c  }
         .let @field_type = PKL_AST_STRUCT_TYPE_FIELD_TYPE (@field)
-        dup                       ; IVAL IVAL
+        dup                     ; IVAL IVAL
   .c  if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_INTEGRAL)
   .c  {
                                 ; IVAL NUM
@@ -2395,8 +2405,9 @@
   .c  }
   .c  else if (PKL_AST_TYPE_CODE (@field_type) == PKL_TYPE_STRUCT)
   .c  {
-        push PVM_E_GENERIC
-        pushe .deintegration_failed
+                                ; IVAL IVAL
+        push PVM_E_CONSTRAINT
+        pushe .constraint_failed
   .c    PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_DEINTEGRATOR);
   .c    PKL_PASS_SUBPASS (@field_type);
   .c    PKL_GEN_POP_CONTEXT;
@@ -2427,26 +2438,16 @@
         push null              ; ... OFF OFF STR VAL NMETH NFIELD STR TYP 
NFIELD SNAME
         mktysct                ; ... OFF OFF STR VAL NMETH NFIELD TYP
         mksct                  ; IVAL SCT
-        push PVM_E_GENERIC
-        pushe .construction_failed
+        push PVM_E_CONSTRAINT
+        pushe .constraint_failed
   .c    PKL_GEN_PUSH_SET_CONTEXT (PKL_GEN_CTX_IN_CONSTRUCTOR);
   .c    PKL_PASS_SUBPASS (@type_struct);
   .c    PKL_GEN_POP_CONTEXT;
         pope
         ba .done
-.deintegration_failed:
-        ;; HACK
-        ;; struct_deintegrator leaves two items on stack (0UL and EXC),
-        ;; instead of one item (EXC).
-        drop
-        ba .alternative_failed
-.construction_failed:
-        ;; HACK
-        ;; struct_constructor leaves two items on stack (0UL and EXC),
-        ;; instead of one item (EXC).
-        drop
+.constraint_failed:
+        nip                     ; IVAL EXC
 .alternative_failed:
-                                ; IVAL EXC
         drop                    ; IVAL
   .c  }
                                 ; IVAL
diff --git a/libpoke/pkl-typify.c b/libpoke/pkl-typify.c
index 6fe8bfa6..516255d2 100644
--- a/libpoke/pkl-typify.c
+++ b/libpoke/pkl-typify.c
@@ -1,4 +1,4 @@
-/* pkl-typify.c - Type handling phases for the poke compiler.  */
+/* Pkl-typify.c - Type handling phases for the poke compiler.  */
 
 /* Copyright (C) 2019, 2020, 2021, 2022 Jose E. Marchesi */
 
@@ -477,8 +477,9 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_cast)
         INVALID_CAST ("invalid cast to string");
       break;
     case PKL_TYPE_STRUCT:
-      /* We are not supporting casts to unions yet.  */
-      if (PKL_AST_TYPE_S_UNION_P (to_type))
+      /* We are not supporting casts to non-integral unions yet.  */
+      if (PKL_AST_TYPE_S_UNION_P (to_type)
+          && !PKL_AST_TYPE_S_ITYPE (to_type))
         INVALID_CAST ("invalid cast to union");
 
       /* Only structs can be casted to regular structs.  Integral
@@ -1688,19 +1689,19 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_type_integral)
 }
 PKL_PHASE_END_HANDLER
 
-/* The type associated with an integral struct shall be integral.
+/* The type associated with an integral struct/union shall be integral.
 
-   The fields in an integral struct type shall be all of integral or
+   The fields in an integral struct/union type shall be all of integral or
    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 total size declared in the integral struct/union should exactly match
    the size of all the contained fields.
 
    Pinned unions are not allowed.
 
-   Labels are not allowed in integral structs, pinned structs and unions.
-   Optional fields are not allowed in integral structs.
+   Labels are not allowed in integral structs/unions, pinned structs and
+   unions.  Optional fields are not allowed in integral structs/unions.
 
    Computed fields should have getter and setter methods defined for
    them, and they should handle values of the right type.  */


Regards,
Mohammad-Reza



reply via email to

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