*/ REBSER *Collect_End(REBSER *prior) /* ** Finish collecting words, and free the Bind_Table for reuse. ** ***********************************************************************/ { REBVAL *words; REBINT *binds = WORDS_HEAD(Bind_Table); // GC safe to do here // Reset binding table (note BUF_WORDS may have expanded): for (words = BLK_HEAD(BUF_WORDS); NOT_END(words); words++) binds[VAL_WORD_CANON(words)] = 0; // If no new words, prior frame: if (prior && SERIES_TAIL(BUF_WORDS) == SERIES_TAIL(prior)) { RESET_TAIL(BUF_WORDS); // allow reuse return FRM_WORD_SERIES(prior); } prior = Copy_Series(BUF_WORDS); RESET_TAIL(BUF_WORDS); // allow reuse BARE_SERIES(prior); // No GC ever needed for word list CHECK_BIND_TABLE; return prior; }
*/ REBSER *Make_Frame(REBINT len) /* ** Create a frame of a given size, allocating space for both ** words and values. Normally used for global frames. ** ** selfless means do not set SELF word ** ***********************************************************************/ { REBSER *frame; REBSER *words; REBVAL *value; //DISABLE_GC; words = Make_Block(len + 1); // size + room for SELF BARE_SERIES(words); frame = Make_Block(len + 1); //ENABLE_GC; // Note: cannot use Append_Frame for first word. value = Append_Value(frame); SET_FRAME(value, 0, words); value = Append_Value(words); Init_Frame_Word(value, SYM_SELF); // may get unset by selfless frames return frame; }
*/ void Init_Words(REBFLG only) /* ** Only flags BIND_Table creation only (for threads). ** ***********************************************************************/ { REBCNT n = Get_Hash_Prime(WORD_TABLE_SIZE * 4); // extra to reduce rehashing if (!only) { // Create the hash for locating words quickly: // Note that the TAIL is never changed for this series. PG_Word_Table.hashes = Make_Series(n+1, sizeof(REBCNT), FALSE); KEEP_SERIES(PG_Word_Table.hashes, "word hashes"); // pointer array Clear_Series(PG_Word_Table.hashes); PG_Word_Table.hashes->tail = n; // The word (symbol) table itself: PG_Word_Table.series = Make_Block(WORD_TABLE_SIZE); SET_NONE(BLK_HEAD(PG_Word_Table.series)); // Put a NONE at head. KEEP_SERIES(PG_Word_Table.series, "word table"); // words are never GC'd BARE_SERIES(PG_Word_Table.series); // don't bother to GC scan it PG_Word_Table.series->tail = 1; // prevent the zero case // A normal char array to hold symbol names: PG_Word_Names = Make_Binary(6 * WORD_TABLE_SIZE); // average word size KEEP_SERIES(PG_Word_Names, "word names"); } // The bind table. Used to cache context indexes for given symbols. Bind_Table = Make_Series(SERIES_REST(PG_Word_Table.series), 4, FALSE); KEEP_SERIES(Bind_Table, "bind table"); // numeric table CLEAR_SERIES(Bind_Table); Bind_Table->tail = PG_Word_Table.series->tail; }
*/ void Expand_Frame(REBSER *frame, REBCNT delta, REBCNT copy) /* ** Expand a frame. Copy words if flagged. ** ***********************************************************************/ { REBSER *words = FRM_WORD_SERIES(frame); Extend_Series(frame, delta); BLK_TERM(frame); // Expand or copy WORDS block: if (copy) { FRM_WORD_SERIES(frame) = Copy_Expand_Block(words, delta); BARE_SERIES(FRM_WORD_SERIES(frame)); } else { Extend_Series(words, delta); BLK_TERM(words); } }