PreviousUpNext

15.4.1188  src/lib/std/src/unsafe/unsafe-chunk.pkg

## unsafe-chunk.pkg

# Compiled by:
#     src/lib/std/src/standard-core.sublib

stipulate
    package ci  =   mythryl_callable_c_library_interface;               # mythryl_callable_c_library_interface  is from   src/lib/std/src/unsafe/mythryl-callable-c-library-interface.pkg
herein

    package   unsafe_chunk
    :         Unsafe_Chunk                                              # Unsafe_Chunk                          is from   src/lib/std/src/unsafe/unsafe-chunk.api
    {
        Chunk =   core::runtime::Chunk;                                 # core                                  is from   src/lib/core/init/core.pkg

        # Information about the memory representation of a heapchunk.
        # NOTE: some of these are not supported yet, but will be once the new
        # rw_vector representation is available.                                        XXX BUGGO FIXME

        Representation
          = UNBOXED                     # Should probably rename TAGGED_INT. XXX BUGGO FIXME
          | UNT1                        # Should this be UNT1...? (But it probably includes INT1 as well.)
          | FLOAT64
          | PAIR
          | RECORD
          | REF
          | TYPEAGNOSTIC_RO_VECTOR
          | TYPEAGNOSTIC_RW_VECTOR      # Includes REF 
          | BYTE_RO_VECTOR              # Includes    vector_of_one_byte_unts::Vector and vector_of_chars::Vector 
          | BYTE_RW_VECTOR              # Includes rw_vector_of_one_byte_unts::Rw_Vector and rw_vector_of_chars::Rw_Vector 
    #     | FLOAT64_RO_VECTOR           # Use TYPEAGNOSTIC_RO_VECTOR for now    XXX BUGGO FIXME
          | FLOAT64_RW_VECTOR
          | LAZY_SUSPENSION
          | WEAK_POINTER
          ;

        my to_chunk:  X -> Chunk = inline_t::cast;

        stipulate
            my make_single_slot_tuple:  Chunk -> Chunk
                =
                ci::find_c_function { lib_name => "heap", fun_name => "make_single_slot_tuple" };               # "make_single_slot_tuple"              def in    src/c/lib/heap/make-single-slot-tuple.c

            my concatenate_two_tuples:  (Chunk, Chunk) -> Chunk                                                 # Concatenate two tuples.
                =
                ci::find_c_function { lib_name => "heap", fun_name => "concatenate_two_tuples" };               # "concatenate_two_tuples"              def in    src/c/lib/heap/concatenate-two-tuples.c
        herein
            fun make_tuple [] => to_chunk();
                make_tuple [a] => make_single_slot_tuple a;
                make_tuple [a, b] => to_chunk (a, b);
                make_tuple [a, b, c] => to_chunk (a, b, c);
                make_tuple [a, b, c, d] => to_chunk (a, b, c, d);
                make_tuple (a ! b ! c ! d ! r) => concatenate_two_tuples (to_chunk (a, b, c, d), make_tuple r);
            end;

        end; #  with

        boxed   =  inline_t::boxed;
        unboxed =  inline_t::unboxed;

        fun rep chunk
            =
            if (unboxed chunk)
                #
                UNBOXED;
            else
                case (inline_t::gettag chunk)           # gettag returns (b-tag << 2 | a-tag) -- a-tag will always be '2' in this context.
                    #
                    0x02 =>                             # b-tag == 0 == pairs_and_records_btag  from    src/lib/compiler/back/low/main/main/heap-tags.pkg
                        #
                        if (inline_t::chunklength chunk == 2)   PAIR;
                        else                                    RECORD;
                        fi;

                    0x06 =>                             # b-tag == 1 == ro_vector_header_btag   from    src/lib/compiler/back/low/main/main/heap-tags.pkg
                        #
                        case (inline_t::chunklength chunk)
                            #
                            0 =>  TYPEAGNOSTIC_RO_VECTOR;
                            1 =>  BYTE_RO_VECTOR;
                            _ =>  raise exception FAIL "unknown vec_hdr";
                        esac;


                    0x0a =>                             # b-tag == 2 == rw_vector_header_btag   from    src/lib/compiler/back/low/main/main/heap-tags.pkg
                        #
                        case (inline_t::chunklength chunk)
                            #
                            0 => TYPEAGNOSTIC_RW_VECTOR;
                            1 => BYTE_RW_VECTOR;
                            6 => FLOAT64_RW_VECTOR;
                            _ => raise exception FAIL "unknown arr_hdr";
                        esac;

                    0x0e =>                             # b-tag == 3 == rw_vector_data_btag / refcell_btag   from       src/lib/compiler/back/low/main/main/heap-tags.pkg
                        #
                        if (inline_t::chunklength chunk == 1)   REF;
                        else                                raise exception FAIL "Unknown arr_data";
                        fi;

                    0x12 => UNT1;                               # four_byte_aligned_nonpointer_data_btag        from    src/lib/compiler/back/low/main/main/heap-tags.pkg

                    0x16 => FLOAT64;                            # eight_byte_aligned_nonpointer_data_btag       from    src/lib/compiler/back/low/main/main/heap-tags.pkg

                    0x1a =>                                     # weak_pointer_or_suspension_btag       from    src/lib/compiler/back/low/main/main/heap-tags.pkg
                        #
                        case (inline_t::getspecial chunk)
                            #
                            (0 | 1) => LAZY_SUSPENSION;
                            (2 | 3) => WEAK_POINTER;
                            _       => raise exception FAIL "unknown special";
                        esac;

                    _  => PAIR;                         # tagless pair
                esac;
            fi;

        exception REPRESENTATION;

        fun length chunk
            =
            case (rep chunk)
                #          
                PAIR    =>  2;
                UNBOXED =>  raise exception REPRESENTATION;
                _       =>  inline_t::chunklength  chunk;
            esac;


        fun nth (chunk, n)
            =
            case (rep chunk)
                #          
                PAIR =>
                     if (0 <= n  and  n < 2)   inline_t::record_get (chunk, n);
                     else                      raise exception REPRESENTATION;
                     fi;

                RECORD
                    =>
                    {   len = inline_t::chunklength chunk;

                        if (0 <= n  and  n < len)   inline_t::record_get (chunk, n);
                        else                        raise exception REPRESENTATION;
                        fi;
                    };

                FLOAT64 =>
                     {   len = inline_t::ti::rshift (inline_t::chunklength chunk, 1);

                         if (n < 0  or  len <= n)   raise exception REPRESENTATION;
                         else
                             if (n == 0)  chunk;        #  flat singleton tuple 
                             else         inline_t::cast (inline_t::raw64get (chunk, n));
                             fi;
                         fi;
                     };

                _ => raise exception REPRESENTATION;
            esac;


        fun to_tuple chunk
            =
            case (rep chunk)
                #          
                UNBOXED => if( ((inline_t::cast chunk) : Int) == 0 )
                               [];
                           else
                               raise exception REPRESENTATION;
                           fi;

                PAIR => [
                     inline_t::record_get (chunk, 0),
                     inline_t::record_get (chunk, 1)
                   ];

                RECORD => {
                     fun f i = inline_t::record_get (chunk, i);

                     list::tabulate (inline_t::chunklength chunk, f);
                   };

                FLOAT64 => {
                     len = inline_t::ti::rshift (inline_t::chunklength chunk, 1);

                     fun f i = (inline_t::cast (inline_t::raw64get (chunk, i)) : Chunk);

                     if   (len == 1   )
                         [chunk];
                     else 
                         list::tabulate (len, f);
                     fi;
                   };
                _ => raise exception REPRESENTATION;
            esac;

        fun to_string chunk
            =
            case (rep chunk)   
                #
                BYTE_RO_VECTOR =>  (inline_t::cast chunk):  String;
                 _             =>  raise exception REPRESENTATION;
            esac;

        fun to_ref chunk
            =
              if (rep chunk == REF)   (inline_t::cast chunk):  Ref(Chunk);
              else                    raise exception REPRESENTATION;
              fi;

        fun to_rw_vector chunk
            =
            case (rep chunk)
                #
                TYPEAGNOSTIC_RW_VECTOR =>  (inline_t::cast chunk): Rw_Vector(Chunk);
                 _                    =>  raise exception REPRESENTATION;
            esac;

        fun to_float64_rw_vector chunk
            =
            case (rep chunk)
                #          
                FLOAT64_RW_VECTOR =>  (inline_t::cast chunk): rw_vector_of_eight_byte_floats::Rw_Vector;
                _                 =>  raise exception REPRESENTATION;
            esac;

        fun to_byte_rw_vector chunk
            =
            case (rep chunk)
                #          
                BYTE_RW_VECTOR =>  (inline_t::cast chunk):  rw_vector_of_one_byte_unts::Rw_Vector;
                _              =>  raise exception REPRESENTATION;
            esac;

        fun to_vector chunk
            =
            case (rep chunk)
                #          
                TYPEAGNOSTIC_RO_VECTOR =>  (inline_t::cast chunk):  Vector(Chunk);
                _                     =>  raise exception REPRESENTATION;
            esac;

        fun to_byte_vector chunk
            =
            case (rep chunk)
                #          
                BYTE_RO_VECTOR =>  (inline_t::cast chunk):  vector_of_one_byte_unts::Vector;
                _              =>  raise exception REPRESENTATION;
            esac;

        fun to_exn chunk
            =
            if  (rep chunk == RECORD
            and  inline_t::chunklength chunk == 3)   (inline_t::cast chunk):  Exception;
            else                                     raise exception REPRESENTATION;
            fi;

        fun to_float chunk
            =
            case (rep chunk)
                #          
                FLOAT64 =>  (inline_t::cast chunk):  Float;
                _       =>  raise exception REPRESENTATION;
            esac;

        fun to_int chunk
            =
            if (unboxed chunk)   (inline_t::cast chunk):  Int;
            else                 raise exception REPRESENTATION;
            fi;

        fun to_int1 chunk
            =
            if (rep chunk == UNT1)   (inline_t::cast chunk): one_word_int::Int;
            else                       raise exception REPRESENTATION;
            fi;

        fun to_unt chunk
            =
            if (unboxed chunk)   (inline_t::cast chunk):  Unt;
            else                 raise exception REPRESENTATION;
            fi;

        fun to_unt8 chunk
            =
            if (unboxed chunk)   (inline_t::cast chunk): one_byte_unt::Unt;
            else                 raise exception REPRESENTATION;
            fi;

        fun to_unt1 chunk
            =
            if (rep chunk == UNT1)   (inline_t::cast chunk):  one_word_unt::Unt;
            else                       raise exception REPRESENTATION;
            fi;

    };
end;



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext