Ignore:
Timestamp:
Sep 29, 2021, 10:46:52 PM (3 years ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
4b3b352
Parents:
218096f
Message:

Refactoring of string internals. Existing tests pass.

Adding tracking for multiple string heaps, or "scratchpads."
Cases of allocating across different pad contexts aren't implemented yet.
Adding basic controls to manage these contexts, which lead to expected assertion failures
at unimplemented cases.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/containers/string_res.cfa

    r218096f r0f781fb8  
    1515
    1616#include "string_res.hfa"
     17#include "string_sharectx.hfa"
     18
    1719#include <stdlib.hfa>  // e.g. malloc
    1820#include <string.h>    // e.g. strlen
     
    2022
    2123//######################### VbyteHeap "header" #########################
    22 
    23 
    24 
    25 
    26 
    27 
    28 
    29 
    30 // DON'T COMMIT:
    31 // #define VbyteDebug
    32 
    33 
    34 
    35 
    3624
    3725#ifdef VbyteDebug
     
    6250static inline void ?{}( VbyteHeap &, int = 1000 );
    6351static inline void ^?{}( VbyteHeap & );
    64 static inline void ByteCopy( VbyteHeap &, char *, int, int, char *, int, int ); // copy a block of bytes from one location in the heap to another
    65 static inline int ByteCmp( VbyteHeap &, char *, int, int, char *, int, int );   // compare 2 blocks of bytes
     52static inline void ByteCopy( char *, int, int, char *, int, int ); // copy a block of bytes from one location in the heap to another
     53static inline int ByteCmp( char *, int, int, char *, int, int );        // compare 2 blocks of bytes
    6654static inline char *VbyteAlloc( VbyteHeap &, int );                     // allocate a block bytes in the heap
    6755
     
    8371    ExtVbyte = (void *)( StartVbyte + CurrSize );
    8472    Header.flink = Header.blink = &Header;
     73    Header.ulink = & this;
    8574#ifdef VbyteDebug
    8675    HeaderPtr = &Header;
     
    124113    s = 0;
    125114    lnth = 0;
     115    ulink = &vh;
    126116    AddThisAfter( this, *vh.Header.blink );
    127117#ifdef VbyteDebug
     
    150140} // ~HandleNode
    151141
     142
     143//######################### String Sharing Context #########################
     144
     145static string_sharectx * ambient_string_sharectx;               // fickle top of stack
     146static string_sharectx default_string_sharectx = {NEW_SHARING}; // stable bottom of stack
     147
     148void ?{}( string_sharectx & this, StringSharectx_Mode mode ) with( this ) {
     149    (older){ ambient_string_sharectx };
     150    if ( mode == NEW_SHARING ) {
     151        (activeHeap){ new( 1000 ) };
     152    } else {
     153        verify( mode == NO_SHARING );
     154        (activeHeap){ 0p };
     155    }
     156    ambient_string_sharectx = & this;
     157}
     158
     159void ^?{}( string_sharectx & this ) with( this ) {
     160    if ( activeHeap ) delete( activeHeap );
     161
     162    // unlink this from older-list starting from ambient_string_sharectx
     163    // usually, this==ambient_string_sharectx and the loop runs zero times
     164    string_sharectx *& c = ambient_string_sharectx;
     165    while ( c != &this ) &c = &c->older;              // find this
     166    c = this.older;                                   // unlink
     167}
     168
    152169//######################### String Resource #########################
    153170
    154171
    155 VbyteHeap HeapArea;
    156 
    157 VbyteHeap * DEBUG_string_heap = & HeapArea;
     172VbyteHeap * DEBUG_string_heap() {
     173    assert( ambient_string_sharectx->activeHeap && "No sharing context is active" );
     174    return ambient_string_sharectx->activeHeap;
     175}
    158176
    159177size_t DEBUG_string_bytes_avail_until_gc( VbyteHeap * heap ) {
     
    199217// Empty constructor
    200218void ?{}(string_res &s) with(s) {
    201     (Handle){ HeapArea };
     219    assert( ambient_string_sharectx->activeHeap && "Need to implement private contexts" );
     220    (Handle){ * ambient_string_sharectx->activeHeap };
    202221    s.shareEditSet_prev = &s;
    203222    s.shareEditSet_next = &s;
     
    206225// Constructor from a raw buffer and size
    207226void ?{}(string_res &s, const char* rhs, size_t rhslnth) with(s) {
    208     (Handle){ HeapArea };
    209     Handle.s = VbyteAlloc(HeapArea, rhslnth);
     227    assert( ambient_string_sharectx->activeHeap && "Need to implement private contexts" );
     228    (Handle){ * ambient_string_sharectx->activeHeap };
     229    Handle.s = VbyteAlloc(*Handle.ulink, rhslnth);
    210230    Handle.lnth = rhslnth;
    211231    for ( int i = 0; i < rhslnth; i += 1 ) {            // copy characters
     
    224244void ?{}(string_res &s, const string_res & s2, StrResInitMode mode, size_t start, size_t end ) {
    225245
     246    assert( ambient_string_sharectx->activeHeap && "Need to implement private contexts" );
     247    assert( s2.Handle.ulink == ambient_string_sharectx->activeHeap && "need to implement context crossing");
     248
    226249    verify( start <= end && end <= s2.Handle.lnth );
    227250
     
    229252    s.Handle.s = s2.Handle.s + start;
    230253    s.Handle.lnth = end - start;
     254    s.Handle.ulink = ambient_string_sharectx->activeHeap;
    231255    AddThisAfter(s.Handle, s2.Handle );                 // insert this handle after rhs handle
    232256    // ^ bug?  skip others at early point in string
     
    404428        // no-op
    405429    } else {                                            // must copy some text
    406         if ( str1.Handle.s + size(str1) == VbyteAlloc(HeapArea, 0) ) { // str1 at end of string area ?
    407             VbyteAlloc(HeapArea, bsize); // create room for 2nd part at the end of string area
     430        if ( str1.Handle.s + size(str1) == VbyteAlloc(*str1.Handle.ulink, 0) ) { // str1 at end of string area ?
     431            VbyteAlloc( *str1.Handle.ulink, bsize ); // create room for 2nd part at the end of string area
    408432        } else {                                        // copy the two parts
    409433            char * str1oldBuf = str1.Handle.s;
    410             str1.Handle.s = VbyteAlloc( HeapArea, clnth );
    411             ByteCopy( HeapArea, str1.Handle.s, 0, str1.Handle.lnth, str1oldBuf, 0, str1.Handle.lnth);
     434            str1.Handle.s = VbyteAlloc( *str1.Handle.ulink, clnth );
     435            ByteCopy( str1.Handle.s, 0, str1.Handle.lnth, str1oldBuf, 0, str1.Handle.lnth);
    412436        } // if
    413         ByteCopy( HeapArea, str1.Handle.s, str1.Handle.lnth, bsize, (char*)buffer, 0, (int)bsize);
     437        ByteCopy( str1.Handle.s, str1.Handle.lnth, bsize, (char*)buffer, 0, (int)bsize);
    414438        //       VbyteHeap & this, char *Dst, int DstStart, int DstLnth, char *Src, int SrcStart, int SrcLnth
    415439    } // if
     
    437461
    438462bool ?==?(const string_res &s1, const string_res &s2) {
    439     return ByteCmp( HeapArea, s1.Handle.s, 0, s1.Handle.lnth, s2.Handle.s, 0, s2.Handle.lnth) == 0;
     463    return ByteCmp( s1.Handle.s, 0, s1.Handle.lnth, s2.Handle.s, 0, s2.Handle.lnth) == 0;
    440464}
    441465
     
    608632    serr | "enter:AddThisAfter, this:" | &this | " n:" | &n;
    609633#endif // VbyteDebug
     634    verify( n.ulink != 0p );
     635    verify( this.ulink == n.ulink );
    610636    flink = n.flink;
    611637    blink = &n;
     
    682708    serr | "enter:MoveThisAfter, this:" | & this | " h:" | & h;
    683709#endif // VbyteDebug
     710    verify( h.ulink != 0p );
     711    verify( this.ulink == h.ulink );
    684712    if ( s < h.s ) {                                    // check argument values
    685713                // serr | "VbyteSM: Error - Cannot move byte string starting at:" | s | " after byte string starting at:"
     
    723751// if the |Dst| > |Src| => pad Dst with blanks
    724752
    725 void ByteCopy( VbyteHeap & this, char *Dst, int DstStart, int DstLnth, char *Src, int SrcStart, int SrcLnth ) {
     753void ByteCopy( char *Dst, int DstStart, int DstLnth, char *Src, int SrcStart, int SrcLnth ) {
    726754    for ( int i = 0; i < DstLnth; i += 1 ) {
    727755      if ( i == SrcLnth ) {                             // |Dst| > |Src|
     
    741769// -1 => Src1-byte-string < Src2-byte-string
    742770
    743 int ByteCmp( VbyteHeap & this, char *Src1, int Src1Start, int Src1Lnth, char *Src2, int Src2Start, int Src2Lnth )  with(this) {
     771int ByteCmp( char *Src1, int Src1Start, int Src1Lnth, char *Src2, int Src2Start, int Src2Lnth ) {
    744772#ifdef VbyteDebug
    745773    serr | "enter:ByteCmp, Src1Start:" | Src1Start | " Src1Lnth:" | Src1Lnth | " Src2Start:" | Src2Start | " Src2Lnth:" | Src2Lnth;
     
    798826    h = Header.flink;                                   // ignore header node
    799827    for (;;) {
    800                 ByteCopy( this, EndVbyte, 0, h->lnth, h->s, 0, h->lnth );
     828                ByteCopy( EndVbyte, 0, h->lnth, h->s, 0, h->lnth );
    801829                obase = h->s;
    802830                h->s = EndVbyte;
Note: See TracChangeset for help on using the changeset viewer.