PreviousUpNext

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

## unsafe-chunk.pkg

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

### This file's epigram is at the bottom. :-)


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
             make_single_slot_tuple
                =
                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
                :
                Chunk -> Chunk;

            concatenate_two_tuples                                                      # 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
                :
                (Chunk, Chunk) -> Chunk;

            ###############################################################=======
            # NB: The above two fns are not actual syscalls to the kernel, and are
            # nowhere near as slow as true syscalls, so there's no point in switching
            # over from using find_c_function() to using find_c_function'().
            #                                           -- 2012-04-21 CrT
        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 DIE "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 DIE "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 DIE "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 DIE "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::from_fn (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::from_fn (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;



###       In the Days Of the Big Computers
###   (Computerfilk to the tune of John Henry)
###    
###    
###    In the days of the big computers,
###     before the minis came
###    if you couldn't lay out a hundred $K
###     then you couldn't get in the game, lord, lord,
###    you couldn't get in the game.
###    
###    Then along came the first few minis
###     and along came the next few more
###    and before you knew you could buy a CPU
###     in a big department store, lord, lorg
###    in a big department store.
###    
###    With a mini the average hacker
###     could afford a computer onsite
###    He could take control of his own console,
###     punch binary in all night, lord, lord,
###     punch binary in all night.
###    
###    Well, the mini could gather data,
###    and transmit to the big mainframe.
###    It could print out graphs, it was good for laughs,
###    and it played the Spacewar game, lord lord,  [2]
###    
###    Then out of the Silicon Valley
###     came news of a better buy
###    CPU chips in twenty-four pin DIPS [3]
###     could be made with LSI [4] lord lord,
###     could be made with LSI.
###    
###    The folks who used the minis
###     began to dream of the day
###    the computer would crash, they'd draw some petty cash
###     and throw the computer away, lord lord,
###     and throw the computer away.
###    
###    But the guys who make the micros
###     didn't wait long to drop the bomb:
###    though the CPU is a buck or two
###     it's a grand to program the PROM, lord lord,
###     it's a grand to program the PROM.
###    
###    So the folks who used the minis
###     took time to work out the cost
###    and they found it close when by the gross,
###    but in lots of one they lost, lord lord,
###     in lots of one they lost.
###    
###    Well some folks like big computers,
###     and some folks like them small
###    and some have fun -- and still get work done --
###     with no computers at all, lord lord
###     with no computers at all.
###    
###    
###    
###    Here is some background which might help contemporary audiences
###    appreciate this filk:
###    
###    I attended Mercer Island High School in Seattle from 1971-74.  At the time
###    Bill Gates was attending high school on the other side of Lake Washington;
###    the first microcomputer -- the Altair 8800 -- was not to come out until
###    1975.  (The first retail computer outlet in Seattle did not appear until
###    about 1980.  It was called "The Retail Computer Store".  Geeks would come
###    in and stare wistfully at the kits on sale, and then buy a copy of one
###    of the magazines on sale like Kilobaud, which all looked as though they
###    had been prepared on a mechanical typewriter and then photocopied.  But
###    that was much later.)
###    
###    Now, Mercer Island is one of the richest school districts in the nation.
###    The Democratic Party caucuses there can meet in a small living room.
###    Seventy percent of Mercer Island High School graduates go on to college.
###    It is one of the best-funded, best-equipped school districts in the nation.
###    
###    I say this so that you can appreciate it when I say that at the time
###    the entire Mercer Island school district possessed a grand total of
###    ONE computers, shared between the high school, two junior highs, and
###    half a dozen elementary schools.  That computer's name was The Red
###    Baron.  It was leased from IBM for thousands of dollars a month.  It
###    fit in a small office.  It had a keypunch, a card reader, a card puncher,
###    and about 4K of memory.  Compiling was done by reading in a stack of
###    cards from one hopper and punching out another stack in the second hopper.
###    
###    Students were NOT welcome on the Red Baron.  A special handful of advanced
###    high school students were allowed to work with a programmable calculator
###    made by Singer (of sewing machine fame) which had 384 bytes of memory.
###    There was also an Olivetti of similar capabilities.
###    
###    When I arrived at the Univerity of Washington, I wangled a job in the
###    Visual Technical Laboratory in Physics Hall, so that I could play with
###    their computer.  It was a PDP-10 minicomputer. [1]  In this case "mini"
###    meant that it occupied a large room with a raised floor for air conditioning
###    and cables.  The entire room was constantly kept at shivering temperatures
###    by dedicated airconditioning equipment, roared with the sound of fans, and
###    was lit by fluorescent ceiling lights.
###    
###    The CPU was the size of a piano.  The seven memory banks were the size
###    of refrigerators, holding 16K each of 36-bit words in the form of
###    ferrite-core memory.  There were no monitors or terminals in the
###    modern sense; the system console was a DECWriter IV, essentially a
###    dot-matrix printer with a keyboard.  Blinking lights on every box in
###    the room displayed memory addresses and data.  (Little incandescent
###    lights; LEDs were far too exotic and expensive.  Thousands of little
###    incandescent bulbs, each with a lifetime of a few thousand hours,
###    meant that I got to replace them pretty much continually, until
###    funding fell to the point that I had to start choosing which bits I
###    wanted to see and leaving dead bulbs in the rest.)
###    
###    In general, every time we had to turn this computer off (seldom), it
###    would take several days of work by skilled technicians to get it
###    working again.  The CPU logic was all on palm-sized plug-in circuit
###    boards called "Flip Chips", some of which held several(!) transistors
###    along with various other discrete components.
###    
###    Like most such computer rooms, this one had some old bits of humor posted
###    about, in particular on the frosted glass entryway doors.  One such sheet
###    related that it was gathered from old SIGPLAN notices and purged of sexist
###    jokes no longer in vogue.  Which is to say, it came from an era (1950s/60s)
###    when the computer in the room would have been regarded as an impossible
###    dream of technological perfection.
###    
###    I recite this background so that you might possibly be able to imagine
###    a time and place in which it would have been considered hilarious to
###    imagine the idea of (say) being able to buy a CPU in a department store.
###    Or of simply throwing a computer away when it crashed.  (As I write this,
###    the backyard of our house is cluttered with dead computers...)
###    
###    The above is something casually memorized thirty-five years ago,
###    so some lines may not be exactly correct;  the reader will have to
###    forgive me.
###    
###    
###    
###    Notes
###    =====
###    [1] KA-10 Serial 7, for history buffs.  Possibly the first PDP-10 shipped
###        to civilian customers.  At the time it was traditional for the first
###        few computers of each new line to mysteriously officially never have
###        existed, only much later to surface from the NSA.  The PDP-10 architecture
###        also had an instruction known informally as "the NSA instruction" --
###        Jump If Find First One.  Searching for the first '1' bit in a word is
###        useful for codebreaking but not much use in business or physics, as
###        a rule.  Our lab inherited it from Bonneville Power, if memory serves.
###    
###    [2] Spacewar was perhaps the first interactive computer game of consequence.
###        A sun in the center of the screen exerted a gravity field, nasty
###        little target/opponent ships would zoom around, and the player would
###        fire streams of slow torpedos at them.  Unix was originally written
###        to support the game.  It was commercialized as SolarQuest early on.
###        The PDP-10 I was using could play it, on a calligraphic display.
###        (Calligraphic displays work by steering the electron beam around
###        to draw a small number of items, as opposed to the fixed raster scan
###        of classical TVs.)
###    
###    [3] Early computer chips were sold in "Dual Inline Packages" with two
###        rows, one down each side, familiar nowadays mainly from cartoons.
###        Even early Z80s and such usually had 80 pins or so;  gods alone know
###        what sort of CPU could be fit in a 24 pin DIP.
###    
###    [4] LSI stood for "Large Scale Integration" -- huge chips with TENS OF
###        THOUSANDS of transistors on them.  After that came VLSI, "Very Large
###        Scale Integration".  After that the industry pretty much gave up
###        trying to come up with a new name for every year's wave of even
###        denser chips, otherwise today's billion-transitor chips would be
###        called something like Super Duper Hyper Extraordinary Scale Integration.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext