Example #1
0
*/  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;
}
Example #2
0
*/  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;
}
Example #3
0
*/	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;
}
Example #4
0
*/  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);
	}
}