added many lines of code for initial loading
This commit is contained in:
		
							
								
								
									
										166
									
								
								stix/lib/dic.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								stix/lib/dic.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,166 @@ | |||||||
|  | /* | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  |     Copyright (c) 2014-2015 Chung, Hyung-Hwan. All rights reserved. | ||||||
|  |  | ||||||
|  |     Redistribution and use in source and binary forms, with or without | ||||||
|  |     modification, are permitted provided that the following conditions | ||||||
|  |     are met: | ||||||
|  |     1. Redistributions of source code must retain the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer. | ||||||
|  |     2. Redistributions in binary form must reproduce the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer in the | ||||||
|  |        documentation and/or other materials provided with the distribution. | ||||||
|  |  | ||||||
|  |     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||||||
|  |     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||||
|  |     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||||
|  |     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  |     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||||
|  |     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||||
|  |     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||||
|  |     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||||
|  |     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||||
|  |     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "stix-prv.h" | ||||||
|  |  | ||||||
|  | static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t old_bucket) | ||||||
|  | { | ||||||
|  | 	stix_oop_oop_t new_bucket; | ||||||
|  | 	stix_oow_t oldsz, newsz, index; | ||||||
|  | 	stix_oop_association_t ass; | ||||||
|  | 	stix_oop_char_t key; | ||||||
|  |  | ||||||
|  | /* TODO: derive a better growth size */ | ||||||
|  | 	new_bucket = (stix_oop_oop_t)stix_instantiate (stix, stix->_array, STIX_NULL, STIX_OBJ_GET_SIZE(old_bucket) * 2);  | ||||||
|  | 	if (!new_bucket) return STIX_NULL; | ||||||
|  |  | ||||||
|  | 	oldsz = STIX_OBJ_GET_SIZE(old_bucket); | ||||||
|  | 	newsz = STIX_OBJ_GET_SIZE(new_bucket); | ||||||
|  |  | ||||||
|  | 	while (oldsz > 0) | ||||||
|  | 	{ | ||||||
|  | 		ass = (stix_oop_association_t)old_bucket->slot[--oldsz]; | ||||||
|  | 		if ((stix_oop_t)ass != stix->_nil) | ||||||
|  | 		{ | ||||||
|  | 			STIX_ASSERT (STIX_CLASSOF(stix,ass) == stix->_association); | ||||||
|  |  | ||||||
|  | 			key = (stix_oop_char_t)ass->key; | ||||||
|  | 			STIX_ASSERT (STIX_CLASSOF(stix,key) == (stix_oop_t)stix->_symbol); | ||||||
|  |  | ||||||
|  | 			index = stix_hashchars (key->slot, STIX_OBJ_GET_SIZE(key)) % newsz; | ||||||
|  | 			while (new_bucket->slot[index] != stix->_nil)  | ||||||
|  | 				index = (index + 1) % newsz; | ||||||
|  | 			new_bucket->slot[index] = (stix_oop_t)ass; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return new_bucket; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | stix_oop_t find_or_insert (stix_t* stix, stix_oop_char_t key, stix_oop_t value) | ||||||
|  | { | ||||||
|  | 	stix_oow_t index, tally; | ||||||
|  | 	stix_oop_association_t ass; | ||||||
|  | 	stix_oow_t tmp_count = 0; | ||||||
|  |  | ||||||
|  | 	/* the system dictionary is not a generic dictionary. | ||||||
|  | 	 * it accepts only a symbol as a key. */ | ||||||
|  | 	STIX_ASSERT (STIX_CLASSOF(stix,key) == stix->_symbol); | ||||||
|  | 	STIX_ASSERT (STIX_CLASSOF(stix,stix->sysdic->tally) == stix->_small_integer); | ||||||
|  | 	STIX_ASSERT (STIX_CLASSOF(stix,stix->sysdic->bucket) == stix->_array); | ||||||
|  |  | ||||||
|  | 	index = stix_hashchars(key->slot, STIX_OBJ_GET_SIZE(key)) % STIX_OBJ_GET_SIZE(stix->sysdic->bucket); | ||||||
|  |  | ||||||
|  | 	while (stix->sysdic->bucket->slot[index] != stix->_nil)  | ||||||
|  | 	{ | ||||||
|  | 		ass = (stix_oop_association_t)stix->sysdic->bucket->slot[index]; | ||||||
|  |  | ||||||
|  | 		STIX_ASSERT (STIX_CLASSOF(stix,ass) == stix->_association); | ||||||
|  | 		STIX_ASSERT (STIX_CLASSOF(stix,ass->key) == stix->_symbol); | ||||||
|  |  | ||||||
|  | 		if (STIX_OBJ_GET_SIZE(key) == STIX_OBJ_GET_SIZE(ass->key)) | ||||||
|  | 		{ | ||||||
|  | 			stix_oow_t i; | ||||||
|  |  | ||||||
|  | 			for (i = 0; i < STIX_OBJ_GET_SIZE(key); i++) | ||||||
|  | 			{ | ||||||
|  | 				if (key->slot[i] != ((stix_oop_char_t)ass->key)->slot[i]) goto not_equal; | ||||||
|  | 			} | ||||||
|  | 			return (stix_oop_t)ass; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	not_equal: | ||||||
|  | 		index = (index + 1) % STIX_OBJ_GET_SIZE(stix->sysdic->bucket); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (value == STIX_NULL) | ||||||
|  | 	{ | ||||||
|  | 		/* | ||||||
|  | 		stix->errnum = STIX_ENOENT; | ||||||
|  | 		return STIX_NULL; | ||||||
|  | 		*/ | ||||||
|  | 		return stix->_nil; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	stix_pushtmp (stix, (stix_oop_t*)&key); tmp_count++; | ||||||
|  | 	stix_pushtmp (stix, &value); tmp_count++; | ||||||
|  |  | ||||||
|  | 	tally = STIX_OOP_TO_SMINT(stix->sysdic->tally); | ||||||
|  | 	if (tally + 1 >= STIX_OBJ_GET_SIZE(stix->sysdic->bucket)) | ||||||
|  | 	{ | ||||||
|  | 		stix_oop_oop_t bucket; | ||||||
|  |  | ||||||
|  | 		/* TODO: make the growth policy configurable instead of growing | ||||||
|  | 			     it just before it gets full. The polcy can be grow it	 | ||||||
|  | 			     if it's 70% full */ | ||||||
|  |  | ||||||
|  | 		/* Enlarge the symbol table before it gets full to | ||||||
|  | 		 * make sure that it has at least one free slot left | ||||||
|  | 		 * after having added a new symbol. this is to help | ||||||
|  | 		 * traversal end at a _nil slot if no entry is found. */ | ||||||
|  | 		bucket = expand_bucket (stix, stix->sysdic->bucket); | ||||||
|  | 		if (!bucket) goto oops; | ||||||
|  |  | ||||||
|  | 		stix->sysdic->bucket = bucket; | ||||||
|  |  | ||||||
|  | 		/* recalculate the index for the expanded bucket */ | ||||||
|  | 		index = stix_hashchars(key->slot, STIX_OBJ_GET_SIZE(key)) % STIX_OBJ_GET_SIZE(stix->sysdic->bucket); | ||||||
|  |  | ||||||
|  | 		while (stix->sysdic->bucket->slot[index] != stix->_nil)  | ||||||
|  | 			index = (index + 1) % STIX_OBJ_GET_SIZE(stix->sysdic->bucket); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* create a new assocation of a key and a value since  | ||||||
|  | 	 * the key isn't found in the root dictionary */ | ||||||
|  | 	ass = (stix_oop_association_t)stix_instantiate (stix, stix->_association, STIX_NULL, 0); | ||||||
|  | 	if (!ass) | ||||||
|  | 	{ | ||||||
|  | 		ass->key = (stix_oop_t)key; | ||||||
|  | 		ass->value = value; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	stix->sysdic->tally = STIX_OOP_FROM_SMINT(tally + 1); | ||||||
|  | 	stix->sysdic->bucket->slot[index] = (stix_oop_t)ass; | ||||||
|  |  | ||||||
|  | 	stix_poptmps (stix, tmp_count); | ||||||
|  | 	return (stix_oop_t)ass; | ||||||
|  |  | ||||||
|  | oops: | ||||||
|  | 	stix_poptmps (stix, tmp_count); | ||||||
|  | 	return STIX_NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | stix_oop_t stix_putatsysdic (stix_t* stix, stix_oop_t key, stix_oop_t value) | ||||||
|  | { | ||||||
|  | 	STIX_ASSERT (STIX_CLASSOF(stix,key) == stix->_symbol); | ||||||
|  | 	return find_or_insert (stix, (stix_oop_char_t)key, value); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | stix_oop_t stix_getatsysdic (stix_t* stix, stix_oop_t key) | ||||||
|  | { | ||||||
|  | 	STIX_ASSERT (STIX_CLASSOF(stix,key) == stix->_symbol); | ||||||
|  | 	return find_or_insert (stix, (stix_oop_char_t)key, STIX_NULL); | ||||||
|  | } | ||||||
							
								
								
									
										116
									
								
								stix/lib/gc.c
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								stix/lib/gc.c
									
									
									
									
									
								
							| @ -28,63 +28,73 @@ | |||||||
|  |  | ||||||
| static void cleanup_symbols_for_gc (stix_t* stix, stix_oop_t _nil) | static void cleanup_symbols_for_gc (stix_t* stix, stix_oop_t _nil) | ||||||
| { | { | ||||||
| #if 0 | 	stix_oop_char_t symbol; | ||||||
| 	stix_oop_oop_t buc; |  | ||||||
| 	stix_oop_char_t sym; |  | ||||||
| 	stix_oow_t tally, index, i, x, y, z; | 	stix_oow_t tally, index, i, x, y, z; | ||||||
|  | 	stix_oow_t bucket_size; | ||||||
|  |  | ||||||
| 	tally = STIX_OOP_TO_SMINT (stix->symtab->slot[STIX_SYMTAB_TALLY]); | #if defined(STIX_SUPPORT_GC_DURING_IGNITION) | ||||||
|  | 	if (!stix->symtab) return; /* symbol table has not been created */ | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	bucket_size = STIX_OBJ_GET_SIZE(stix->symtab->bucket); | ||||||
|  |  | ||||||
|  | 	tally = STIX_OOP_TO_SMINT(stix->symtab->tally); | ||||||
| 	if (tally <= 0) return; | 	if (tally <= 0) return; | ||||||
|  |  | ||||||
| 	buc = (stix_oop_oop_t) stix->symtab->slot[STIX_SYMTAB_BUCKET]; | 	for (index = 0; index < bucket_size; ) | ||||||
| 	for (index = 0; index < buc->size; ) |  | ||||||
| 	{ | 	{ | ||||||
| 		if (buc->slot[index]->flags & STIX_OBJ_FLAG_MOVED)  | 		if (STIX_OBJ_GET_FLAGS_MOVED(stix->symtab->bucket->slot[index])) | ||||||
| 		{ | 		{ | ||||||
| 			index++; | 			index++; | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		STIX_ASSERT (buc->slot[index] != _nil); | 		STIX_ASSERT (stix->symtab->bucket->slot[index] != _nil); | ||||||
|  |  | ||||||
|  | /* | ||||||
| { | { | ||||||
| sym = (stix_oop_char_t)buc->slot[index]; | sym = (stix_oop_char_t)buc->slot[index]; | ||||||
| wprintf (L">> DISPOSING %d [%S] from the symbol table\n", (int)index, sym->slot); | wprintf (L">> DISPOSING %d [%S] from the symbol table\n", (int)index, sym->slot); | ||||||
| } | } | ||||||
| 		for (i = 0, x = index, y = index; i < buc->size; i++) | */ | ||||||
|  |  | ||||||
|  | 		for (i = 0, x = index, y = index; i < bucket_size; i++) | ||||||
| 		{ | 		{ | ||||||
| 			y = (y + 1) % buc->size; | 			y = (y + 1) % bucket_size; | ||||||
|  |  | ||||||
| 			/* done if the slot at the current hash index is _nil */ | 			/* done if the slot at the current hash index is _nil */ | ||||||
| 			if (buc->slot[y] == _nil) break; | 			if (stix->symtab->bucket->slot[y] == _nil) break; | ||||||
|  |  | ||||||
| 			/* get the natural hash index for the data in the slot  | 			/* get the natural hash index for the data in the slot  | ||||||
| 			 * at the current hash index */ | 			 * at the current hash index */ | ||||||
| 			sym = (stix_oop_char_t)buc->slot[y]; | 			symbol = (stix_oop_char_t)stix->symtab->bucket->slot[y]; | ||||||
|  |  | ||||||
| 			STIX_ASSERT (STIX_CLASSOF(stix,sym) == (stix_oop_t)stix->cc.symbol); | 			STIX_ASSERT (STIX_CLASSOF(stix,symbol) == stix->_symbol); | ||||||
|  |  | ||||||
| 			z = hash_chars (sym->slot, sym->size) % buc->size; | 			z = stix_hashchars(symbol->slot, STIX_OBJ_GET_SIZE(symbol)) % bucket_size; | ||||||
|  |  | ||||||
| 			/* move an element if necessary */ | 			/* move an element if necessary */ | ||||||
| 			if ((y > x && (z <= x || z > y)) || | 			if ((y > x && (z <= x || z > y)) || | ||||||
| 			    (y < x && (z <= x && z > y))) | 			    (y < x && (z <= x && z > y))) | ||||||
| 			{ | 			{ | ||||||
| 				buc->slot[x] = buc->slot[y]; | 				stix->symtab->bucket->slot[x] = stix->symtab->bucket->slot[y]; | ||||||
| 				x = y; | 				x = y; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		buc->slot[x] = _nil; | 		stix->symtab->bucket->slot[x] = _nil; | ||||||
| 		tally--; | 		tally--; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	stix->symtab->slot[STIX_SYMTAB_TALLY] = STIX_OOP_FROM_SMINT(tally); | 	stix->symtab->tally = STIX_OOP_FROM_SMINT(tally); | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static stix_oop_t move_one (stix_t* stix, stix_oop_t oop) | static stix_oop_t move_one (stix_t* stix, stix_oop_t oop) | ||||||
| { | { | ||||||
|  | #if defined(STIX_SUPPORT_GC_DURING_IGNITION) | ||||||
|  | 	if (!oop) return oop; | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	STIX_ASSERT (STIX_OOP_IS_POINTER(oop)); | 	STIX_ASSERT (STIX_OOP_IS_POINTER(oop)); | ||||||
|  |  | ||||||
| 	if (STIX_OBJ_GET_FLAGS_MOVED(oop)) | 	if (STIX_OBJ_GET_FLAGS_MOVED(oop)) | ||||||
| @ -93,7 +103,7 @@ static stix_oop_t move_one (stix_t* stix, stix_oop_t oop) | |||||||
| 		 * the class field has been updated to the new object | 		 * the class field has been updated to the new object | ||||||
| 		 * in the 'else' block below. i can simply return it | 		 * in the 'else' block below. i can simply return it | ||||||
| 		 * without further migration. */ | 		 * without further migration. */ | ||||||
| 		return oop->_class; | 		return STIX_OBJ_GET_CLASS(oop); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @ -125,7 +135,7 @@ static stix_oop_t move_one (stix_t* stix, stix_oop_t oop) | |||||||
| 		/* let the class field of the old object point to the new  | 		/* let the class field of the old object point to the new  | ||||||
| 		 * object allocated in the new heap. it is returned in  | 		 * object allocated in the new heap. it is returned in  | ||||||
| 		 * the 'if' block at the top of this function. */ | 		 * the 'if' block at the top of this function. */ | ||||||
| 		oop->_class = tmp; | 		STIX_OBJ_SET_CLASS (oop, tmp); | ||||||
|  |  | ||||||
| 		/* return the new object */ | 		/* return the new object */ | ||||||
| 		return tmp; | 		return tmp; | ||||||
| @ -141,11 +151,10 @@ static stix_uint8_t* scan_new_heap (stix_t* stix, stix_uint8_t* ptr) | |||||||
| 		stix_oop_t oop; | 		stix_oop_t oop; | ||||||
|  |  | ||||||
| 		oop = (stix_oop_t)ptr; | 		oop = (stix_oop_t)ptr; | ||||||
| 		nbytes = (oop->_size + STIX_OBJ_GET_FLAGS_EXTRA(oop)) * STIX_OBJ_GET_FLAGS_UNIT(oop); | 		nbytes = (STIX_OBJ_GET_SIZE(oop) + STIX_OBJ_GET_FLAGS_EXTRA(oop)) * STIX_OBJ_GET_FLAGS_UNIT(oop); | ||||||
| 		nbytes_aligned = STIX_ALIGN (nbytes, STIX_SIZEOF(stix_oop_t)); | 		nbytes_aligned = STIX_ALIGN (nbytes, STIX_SIZEOF(stix_oop_t)); | ||||||
|  |  | ||||||
| 		oop->_class = move_one (stix, oop->_class); | 		STIX_OBJ_SET_CLASS (oop, move_one(stix, STIX_OBJ_GET_CLASS(oop))); | ||||||
|  |  | ||||||
| 		if (STIX_OBJ_GET_FLAGS_TYPE(oop) == STIX_OBJ_TYPE_OOP) | 		if (STIX_OBJ_GET_FLAGS_TYPE(oop) == STIX_OBJ_TYPE_OOP) | ||||||
| 		{ | 		{ | ||||||
| 			stix_obj_oop_t* xtmp; | 			stix_obj_oop_t* xtmp; | ||||||
| @ -174,30 +183,40 @@ void stix_gc (stix_t* stix) | |||||||
| 	 * move objects pointed to by the fields to the new heap. | 	 * move objects pointed to by the fields to the new heap. | ||||||
| 	 * finally perform some tricky symbol table clean-up. | 	 * finally perform some tricky symbol table clean-up. | ||||||
| 	 */ | 	 */ | ||||||
|  |  | ||||||
| 	stix_uint8_t* ptr; | 	stix_uint8_t* ptr; | ||||||
| 	stix_heap_t* tmp; | 	stix_heap_t* tmp; | ||||||
| 	stix_oop_t old__nil; | 	stix_oop_t old_nil; | ||||||
|  | 	stix_oow_t i; | ||||||
|  |  | ||||||
| 	/* TODO: allocate common objects like _nil and the root dictionary  | 	/* TODO: allocate common objects like _nil and the root dictionary  | ||||||
| 	 *       in the permanant heap.  minimize moving around */ | 	 *       in the permanant heap.  minimize moving around */ | ||||||
|  | 	old_nil = stix->_nil; | ||||||
| 	old__nil = stix->_nil; |  | ||||||
|  |  | ||||||
| 	/* move _nil and the root object table */ | 	/* move _nil and the root object table */ | ||||||
| 	stix->_nil               = move_one (stix, stix->_nil); | 	stix->_nil               = move_one (stix, stix->_nil); | ||||||
| 	stix->root = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->root); |  | ||||||
| 	stix->_true              = move_one (stix, stix->_true); | 	stix->_true              = move_one (stix, stix->_true); | ||||||
| 	stix->_false             = move_one (stix, stix->_false); | 	stix->_false             = move_one (stix, stix->_false); | ||||||
|  |  | ||||||
| 	stix->cc.array = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.array); | /*printf ("BEFORE GC = %p %p %p %p %p %p %p %p %p %p\n", stix->_array, stix->_class, stix->_nil_object, stix->_object, stix->_symbol, stix->_symbol_set, stix->_system_dictionary, stix->_association, stix->_character, stix->_small_integer);*/ | ||||||
| 	stix->cc.association = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.association); | 	stix->_stix              = move_one (stix, stix->_stix); | ||||||
| 	/*stix->cc.metaclass = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.metaclass);*/ | 	stix->_class             = move_one (stix, stix->_class); | ||||||
| 	stix->cc.string = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.string); | 	stix->_nil_object        = move_one (stix, stix->_nil_object); | ||||||
| 	stix->cc.symbol = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.symbol); | 	stix->_object            = move_one (stix, stix->_object); | ||||||
| 	stix->cc.sysdic = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.sysdic); | 	stix->_array             = move_one (stix, stix->_array); | ||||||
| 	stix->cc.numeric[0] = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.numeric[0]); | 	stix->_symbol            = move_one (stix, stix->_symbol); | ||||||
| 	stix->cc.numeric[1] = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->cc.numeric[1]); | 	stix->_symbol_set        = move_one (stix, stix->_symbol_set); | ||||||
|  | 	stix->_system_dictionary = move_one (stix, stix->_system_dictionary); | ||||||
|  | 	stix->_association       = move_one (stix, stix->_association); | ||||||
|  | 	stix->_character         = move_one (stix, stix->_character); | ||||||
|  | 	stix->_small_integer     = move_one (stix, stix->_small_integer); | ||||||
|  |  | ||||||
|  | /*printf ("AFTER GC = %p %p %p %p %p %p %p %p %p %p\n", stix->_array, stix->_class, stix->_nil_object, stix->_object, stix->_symbol, stix->_symbol_set, stix->_system_dictionary, stix->_association, stix->_character, stix->_small_integer);*/ | ||||||
|  | 	stix->sysdic = (stix_oop_set_t) move_one (stix, (stix_oop_t)stix->sysdic); | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < stix->tmp_count; i++) | ||||||
|  | 	{ | ||||||
|  | 		*stix->tmp_stack[i] = move_one (stix, *stix->tmp_stack[i]); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	/* scan the new heap to move referenced objects */ | 	/* scan the new heap to move referenced objects */ | ||||||
| 	ptr = (stix_uint8_t*) STIX_ALIGN ((stix_uintptr_t)stix->newheap->base, STIX_SIZEOF(stix_oop_t)); | 	ptr = (stix_uint8_t*) STIX_ALIGN ((stix_uintptr_t)stix->newheap->base, STIX_SIZEOF(stix_oop_t)); | ||||||
| @ -207,10 +226,10 @@ void stix_gc (stix_t* stix) | |||||||
| 	 * if the symbol has not moved to the new heap, the symbol | 	 * if the symbol has not moved to the new heap, the symbol | ||||||
| 	 * is not referenced by any other objects than the symbol  | 	 * is not referenced by any other objects than the symbol  | ||||||
| 	 * table itself */ | 	 * table itself */ | ||||||
| 	cleanup_symbols_for_gc (stix, old__nil); | 	cleanup_symbols_for_gc (stix, old_nil); | ||||||
|  |  | ||||||
| 	/* move the symbol table itself */ | 	/* move the symbol table itself */ | ||||||
| 	stix->symtab = (stix_oop_oop_t) move_one (stix, (stix_oop_t)stix->symtab); | 	stix->symtab = (stix_oop_set_t)move_one (stix, (stix_oop_t)stix->symtab); | ||||||
|  |  | ||||||
| 	/* scan the new heap again from the end position of | 	/* scan the new heap again from the end position of | ||||||
| 	 * the previous scan to move referenced objects by  | 	 * the previous scan to move referenced objects by  | ||||||
| @ -242,3 +261,24 @@ printf ("===========================\n"); | |||||||
| } | } | ||||||
| */ | */ | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void stix_pushtmp (stix_t* stix, stix_oop_t* oop_ptr) | ||||||
|  | { | ||||||
|  | 	/* if you have too many temporaries pushed, something must be wrong. | ||||||
|  | 	 * change your code not to exceede the stack limit */ | ||||||
|  | 	STIX_ASSERT (stix->tmp_count < STIX_COUNTOF(stix->tmp_stack)); | ||||||
|  | 	stix->tmp_stack[stix->tmp_count++] = oop_ptr; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void stix_poptmp (stix_t* stix) | ||||||
|  | { | ||||||
|  | 	STIX_ASSERT (stix->tmp_count > 0); | ||||||
|  | 	stix->tmp_count--; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void stix_poptmps (stix_t* stix, stix_oow_t count) | ||||||
|  | { | ||||||
|  | 	STIX_ASSERT (stix->tmp_count >= count); | ||||||
|  | 	stix->tmp_count -= count; | ||||||
|  | } | ||||||
|  | |||||||
| @ -27,6 +27,204 @@ | |||||||
| #include "stix-prv.h" | #include "stix-prv.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
|  | stix_oop_t stix_addclass (stix_t* stix, name, spec, ...) | ||||||
|  | { | ||||||
|  | /* convert name to the internal encoding... */ | ||||||
|  |  | ||||||
|  | /* returned value must be also registered in the system dictionary.  | ||||||
|  |  * so it doesn't get GCed. */ | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int stix_delclass (stix_t* stix, stix_oop_t _class) | ||||||
|  | { | ||||||
|  | 	stix_oop_class_t c = (stix_oop_class_t)_class; | ||||||
|  |  | ||||||
|  | 	if (c->name) | ||||||
|  | 	{ | ||||||
|  | 		/* delete c->name from system dictionary. it'll get GCed if it's not referenced */ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | stix_oop_t stix_findclass (stix_t* stix, const char* name) | ||||||
|  | { | ||||||
|  | 	/* find a class object by name */ | ||||||
|  | 	return STIX_NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int stix_addmethod (stix_t* stix, stix_oop_t _class, const char* name, const bytecode) | ||||||
|  | { | ||||||
|  |  | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  *    Stix ..................... | ||||||
|  |  *    ^ ^ ^                    :   ....... | ||||||
|  |  *    | | |                    v   v     : | ||||||
|  |  *    | | +------------------- Class ..... | ||||||
|  |  *    | |                       ^  ^ | ||||||
|  |  *    | +-------- NilObject ......:  : | ||||||
|  |  *    |                 ^........ nil  : | ||||||
|  |  *   Object ...........................: | ||||||
|  |  *    ^   | ||||||
|  |  *    |   | ||||||
|  |  * | ||||||
|  |  * The class hierarchy is roughly as follows: | ||||||
|  |  *  | ||||||
|  |  *   Stix | ||||||
|  |  *      Class | ||||||
|  |  *      NilObject | ||||||
|  |  *      Object | ||||||
|  |  *         Collection | ||||||
|  |  *            IndexedCollection | ||||||
|  |  *               FixedSizedCollection | ||||||
|  |  *                  Array | ||||||
|  |  *                  ByteArray | ||||||
|  |  *                     String | ||||||
|  |  *                        Symbol | ||||||
|  |  *            Set | ||||||
|  |  *               Dictionary | ||||||
|  |  *                  SystemDictionary | ||||||
|  |  *               SymbolSet | ||||||
|  |  *         Magnitude | ||||||
|  |  *            Association | ||||||
|  |  *            Character | ||||||
|  |  *            Number | ||||||
|  |  *               Integer | ||||||
|  |  *                  SmallInteger | ||||||
|  |  *                  LargeInteger | ||||||
|  |  *  | ||||||
|  |  * Stix has no instance variables. | ||||||
|  |  * Stix has 1 class variable: Sysdic | ||||||
|  |  *   | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | static stix_oop_t alloc_kernel_class (stix_t* stix, stix_oow_t indexed, stix_oow_t spec) | ||||||
|  | { | ||||||
|  | 	stix_oop_class_t c; | ||||||
|  |  | ||||||
|  | 	c = (stix_oop_class_t)stix_allocoopobj (stix, STIX_CLASS_NAMED_INSTVARS + indexed); | ||||||
|  | 	if (!c) return STIX_NULL; | ||||||
|  |  | ||||||
|  | 	STIX_OBJ_SET_FLAGS_KERNEL (c, 1); | ||||||
|  | 	STIX_OBJ_SET_CLASS (c, stix->_class); | ||||||
|  | 	c->spec = STIX_OOP_FROM_SMINT(spec); | ||||||
|  |  | ||||||
|  | 	return (stix_oop_t)c; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ignite_1 (stix_t* stix) | ||||||
|  | { | ||||||
|  | 	/* | ||||||
|  | 	 * Create fundamental class objects with some fields mis-initialized yet. | ||||||
|  | 	 * Such fields include 'superclass', 'subclasses', 'name', etc. | ||||||
|  | 	 */ | ||||||
|  | 	STIX_ASSERT (stix->_nil != STIX_NULL); | ||||||
|  | 	STIX_ASSERT (STIX_OBJ_GET_CLASS(stix->_nil) == STIX_NULL); | ||||||
|  |  | ||||||
|  | 	/* -------------------------------------------------------------- | ||||||
|  | 	 * Class | ||||||
|  | 	 * The instance of Class can have indexed instance variables  | ||||||
|  | 	 * which are actually class variables. | ||||||
|  | 	 * -------------------------------------------------------------- */ | ||||||
|  | 	stix->_class = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE (STIX_CLASS_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP)); | ||||||
|  | 	if (!stix->_class) return -1; | ||||||
|  |  | ||||||
|  | 	STIX_ASSERT (STIX_OBJ_GET_CLASS(stix->_class) == STIX_NULL); | ||||||
|  | 	STIX_OBJ_SET_CLASS (stix->_class, stix->_class); | ||||||
|  |  | ||||||
|  | 	/* -------------------------------------------------------------- | ||||||
|  | 	 * Stix      - proto-object with 1 class variable. | ||||||
|  | 	 * NilObject - class for the nil object. | ||||||
|  | 	 * Object    - top of all ordinary objects. | ||||||
|  | 	 * Symbol | ||||||
|  | 	 * Array | ||||||
|  | 	 * SymbolSet | ||||||
|  | 	 * Character | ||||||
|  | 	 * SmallIntger | ||||||
|  | 	 * -------------------------------------------------------------- */ | ||||||
|  | 	stix->_stix              = alloc_kernel_class (stix, 1, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); | ||||||
|  | 	stix->_nil_object        = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); | ||||||
|  | 	stix->_object            = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); | ||||||
|  | 	stix->_array             = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 1, STIX_OBJ_TYPE_OOP)); | ||||||
|  | 	stix->_symbol            = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 1, STIX_OBJ_TYPE_CHAR)); | ||||||
|  | 	stix->_symbol_set        = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_SET_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP)); | ||||||
|  | 	stix->_system_dictionary = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_SET_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP)); | ||||||
|  | 	stix->_association       = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_ASSOCIATION_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP)); | ||||||
|  |  | ||||||
|  | 	/* TOOD: what is a proper spec for Character and SmallInteger? | ||||||
|  |  	 *       If the fixed part is  0, its instance must be an object of 0 payload fields. | ||||||
|  | 	 *       Does this make sense? */ | ||||||
|  | 	stix->_character         = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); | ||||||
|  | 	stix->_small_integer     = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); | ||||||
|  |  | ||||||
|  | 	if (!stix->_stix              || !stix->_nil_object    || !stix->_object || | ||||||
|  | 	    !stix->_array             || !stix->_symbol        || !stix->_symbol_set || | ||||||
|  | 	    !stix->_system_dictionary || !stix->_association   ||  | ||||||
|  | 	    !stix->_character         || !stix->_small_integer) return -1; | ||||||
|  |  | ||||||
|  | 	STIX_OBJ_SET_CLASS (stix->_nil, stix->_nil_object); | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static int ignite_2 (stix_t* stix) | ||||||
|  | { | ||||||
|  | 	stix_oop_oop_t arr; | ||||||
|  |  | ||||||
|  | 	/* Create the symbol table */ | ||||||
|  | 	stix->symtab = (stix_oop_set_t)stix_instantiate (stix, stix->_symbol_set, STIX_NULL, 0); | ||||||
|  | 	if (!stix->symtab) return -1; | ||||||
|  |  | ||||||
|  | 	stix->symtab->tally = STIX_OOP_FROM_SMINT(0); | ||||||
|  | 	arr = (stix_oop_oop_t)stix_instantiate (stix, stix->_array, STIX_NULL, stix->option.default_symtab_size); | ||||||
|  | 	if (!arr) return -1; | ||||||
|  | 	stix->symtab->bucket = arr; | ||||||
|  |  | ||||||
|  | 	/* Create the system dictionary */ | ||||||
|  | 	stix->sysdic = (stix_oop_set_t)stix_instantiate (stix, stix->_system_dictionary, STIX_NULL, 0); | ||||||
|  | 	if (!stix->sysdic) return -1; | ||||||
|  |  | ||||||
|  | 	stix->sysdic->tally = STIX_OOP_FROM_SMINT(0); | ||||||
|  | 	arr = (stix_oop_oop_t)stix_instantiate (stix, stix->_array, STIX_NULL, stix->option.default_sysdic_size); | ||||||
|  | 	if (!arr) return -1; | ||||||
|  | 	stix->sysdic->bucket = arr; | ||||||
|  |  | ||||||
|  | 	/* Export the system dictionary via the first class variable of the Stix class */ | ||||||
|  | 	((stix_oop_class_t)stix->_stix)->classvar[0] = (stix_oop_t)stix->sysdic; | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | 	stix_oop_class_t c; | ||||||
|  |  | ||||||
|  | 	c = (stix_oop_class_t)stix->_stix; | ||||||
|  | 	c->classvar[0] = stix->_nil; | ||||||
|  | */ | ||||||
|  | 	/* Set subclasses */ | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  |   	Set Names. | ||||||
|  | 	stix->_stix_object->name = new_symbol ("ProtoObject"); | ||||||
|  | 	stix->_nil_object->name = new_symbol ("NilObject"); | ||||||
|  | 	stix->_class->name = new_symbol ("Class"); | ||||||
|  | 	*/ | ||||||
|  |  | ||||||
|  | 	/* | ||||||
|  | 	_class->instvars = make_string or make_array('spec instmthds classmthds superclass name instvars'); | ||||||
|  | 	*/ | ||||||
|  |  | ||||||
|  | 	/*register 'Stix', 'NilObject' and 'Class' into the system dictionary.*/ | ||||||
|  | 	 | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |  | ||||||
| int stix_ignite (stix_t* stix) | int stix_ignite (stix_t* stix) | ||||||
| { | { | ||||||
| 	STIX_ASSERT (stix->_nil == STIX_NULL); | 	STIX_ASSERT (stix->_nil == STIX_NULL); | ||||||
| @ -35,11 +233,11 @@ int stix_ignite (stix_t* stix) | |||||||
| 	if (!stix->_nil) return -1; | 	if (!stix->_nil) return -1; | ||||||
|  |  | ||||||
| 	stix->_nil->_flags = STIX_OBJ_MAKE_FLAGS (STIX_OBJ_TYPE_OOP, STIX_SIZEOF(stix_oop_t), 0, 1, 0); | 	stix->_nil->_flags = STIX_OBJ_MAKE_FLAGS (STIX_OBJ_TYPE_OOP, STIX_SIZEOF(stix_oop_t), 0, 1, 0); | ||||||
| 	stix->_nil->_size= 0; | 	stix->_nil->_size = 0; | ||||||
| 	stix->_nil->_class = stix->_nil; |  | ||||||
|  |  | ||||||
|  | 	if (ignite_1(stix) <= -1 || ignite_2(stix) <= -1) return -1; | ||||||
|  |  | ||||||
| printf ("%lu\n", (unsigned long int)stix->_nil->_flags); | /*stix_addclass (stix, "True", spec, "Boolean");*/ | ||||||
| 	/*stix->_true = stix_instantiate (stix, stix->_true_class, STIX_NULL, 0); | 	/*stix->_true = stix_instantiate (stix, stix->_true_class, STIX_NULL, 0); | ||||||
| 	stix->_false = stix_instantiate (stix, stix->_false_class STIX_NULL, 0); | 	stix->_false = stix_instantiate (stix, stix->_false_class STIX_NULL, 0); | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										115
									
								
								stix/lib/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								stix/lib/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,115 @@ | |||||||
|  | #include "stix-prv.h" | ||||||
|  |  | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  |  | ||||||
|  | static void* sys_alloc (stix_mmgr_t* mmgr, stix_size_t size) | ||||||
|  | { | ||||||
|  | 	return malloc (size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void* sys_realloc (stix_mmgr_t* mmgr, void* ptr, stix_size_t size) | ||||||
|  | { | ||||||
|  | 	return realloc (ptr, size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static void sys_free (stix_mmgr_t* mmgr, void* ptr) | ||||||
|  | { | ||||||
|  | 	free (ptr); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static stix_mmgr_t sys_mmgr = | ||||||
|  | { | ||||||
|  | 	sys_alloc, | ||||||
|  | 	sys_realloc, | ||||||
|  | 	sys_free, | ||||||
|  | 	STIX_NULL | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static void dump_symbol_table (stix_t* stix) | ||||||
|  | { | ||||||
|  | 	stix_oow_t i, j; | ||||||
|  | 	stix_oop_char_t symbol; | ||||||
|  |  | ||||||
|  | 	printf ("--------------------------------------------\n"); | ||||||
|  | 	printf ("Stix Symbol Table %lu\n", (unsigned long int)STIX_OBJ_GET_SIZE(stix->symtab->bucket)); | ||||||
|  | 	printf ("--------------------------------------------\n"); | ||||||
|  |  | ||||||
|  | 	for (i = 0; i < STIX_OBJ_GET_SIZE(stix->symtab->bucket); i++) | ||||||
|  | 	{ | ||||||
|  | 		symbol = (stix_oop_char_t)stix->symtab->bucket->slot[i]; | ||||||
|  | 		if ((stix_oop_t)symbol != stix->_nil) | ||||||
|  | 		{ | ||||||
|  | 			printf (" %lu [", (unsigned long int)i); | ||||||
|  | 			for (j = 0; j < STIX_OBJ_GET_SIZE(symbol); j++) | ||||||
|  | 			{ | ||||||
|  | 				printf ("%c", symbol->slot[j]); | ||||||
|  | 			} | ||||||
|  | 			printf ("]\n"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	printf ("--------------------------------------------\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int main (int argc, char* argv[]) | ||||||
|  | { | ||||||
|  | 	stix_t* stix; | ||||||
|  | 	printf ("Stix 1.0.0 - max named %lu max indexed %lu\n",  | ||||||
|  | 		(unsigned long int)STIX_MAX_NAMED_INSTVARS, (unsigned long int)STIX_MAX_INDEXED_INSTVARS(STIX_MAX_NAMED_INSTVARS)); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 	{ | ||||||
|  | 	stix_oow_t x; | ||||||
|  |  | ||||||
|  | 	printf ("%u\n", STIX_BITS_MAX(unsigned int, 5)); | ||||||
|  |  | ||||||
|  | 	x = STIX_CLASS_SPEC_MAKE (10, 1, STIX_OBJ_TYPE_CHAR); | ||||||
|  | 	printf ("%lu %lu %lu %lu\n", (unsigned long int)x, (unsigned long int)STIX_OOP_FROM_SMINT(x), | ||||||
|  | 		(unsigned long int)STIX_CLASS_SPEC_NAMED_INSTVAR(x), | ||||||
|  | 		(unsigned long int)STIX_CLASS_SPEC_INDEXED_TYPE(x)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	stix = stix_open (&sys_mmgr, 0, 1000000lu, STIX_NULL); | ||||||
|  | 	if (!stix) | ||||||
|  | 	{ | ||||||
|  | 		printf ("cannot open stix\n"); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	{ | ||||||
|  | 		stix_oow_t symtab_size = 5000; | ||||||
|  | 		stix_setoption (stix, STIX_DEFAULT_SYMTAB_SIZE, &symtab_size); | ||||||
|  | 		stix_setoption (stix, STIX_DEFAULT_SYSDIC_SIZE, &symtab_size); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (stix_ignite(stix) <= -1) | ||||||
|  | 	{ | ||||||
|  | 		printf ("cannot ignite stix\n"); | ||||||
|  | 		stix_close (stix); | ||||||
|  | 		return -1; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | { | ||||||
|  | stix_char_t x[] = { 'S', 't', 'r', 'i', 'n', 'g', '\0' }; | ||||||
|  | stix_char_t y[] = { 'S', 'y', 'm', 'b', 'o', 'l', '\0' }; | ||||||
|  | stix_oop_t a, b; | ||||||
|  |  | ||||||
|  | a = stix_makesymbol (stix, x, 6); | ||||||
|  | b = stix_makesymbol (stix, y, 6); | ||||||
|  |  | ||||||
|  | printf ("%p %p\n", a, b); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 	dump_symbol_table (stix); | ||||||
|  | stix_gc (stix); | ||||||
|  | 	dump_symbol_table (stix); | ||||||
|  |  | ||||||
|  | 	stix_close (stix); | ||||||
|  |  | ||||||
|  | #if defined(__BORLANDC__) | ||||||
|  | 	printf ("Press the enter key...\n"); | ||||||
|  | 	getchar (); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
| @ -30,6 +30,10 @@ void* stix_allocbytes (stix_t* stix, stix_size_t size) | |||||||
| { | { | ||||||
| 	stix_uint8_t* ptr; | 	stix_uint8_t* ptr; | ||||||
|  |  | ||||||
|  | #if defined(STIX_DEBUG_GC_1) | ||||||
|  | stix_gc (stix); | ||||||
|  | #endif | ||||||
|  |  | ||||||
| 	ptr = stix_allocheapmem (stix, stix->curheap, size); | 	ptr = stix_allocheapmem (stix, stix->curheap, size); | ||||||
| 	if (!ptr && !(stix->option.trait & STIX_NOGC)) | 	if (!ptr && !(stix->option.trait & STIX_NOGC)) | ||||||
| 	{ | 	{ | ||||||
| @ -135,7 +139,7 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, | |||||||
| 	STIX_ASSERT (stix->_nil != STIX_NULL); | 	STIX_ASSERT (stix->_nil != STIX_NULL); | ||||||
|  |  | ||||||
| 	STIX_ASSERT (STIX_OOP_IS_POINTER(_class)); | 	STIX_ASSERT (STIX_OOP_IS_POINTER(_class)); | ||||||
| 	/*STIX_ASSERT (STIX_CLASSOF(_class) == stix->_class); */ | 	STIX_ASSERT (STIX_CLASSOF(stix, _class) == stix->_class);  | ||||||
|  |  | ||||||
| 	STIX_ASSERT (STIX_OOP_IS_SMINT(((stix_oop_class_t)_class)->spec)); | 	STIX_ASSERT (STIX_OOP_IS_SMINT(((stix_oop_class_t)_class)->spec)); | ||||||
| 	spec = STIX_OOP_TO_SMINT(((stix_oop_class_t)_class)->spec); | 	spec = STIX_OOP_TO_SMINT(((stix_oop_class_t)_class)->spec); | ||||||
| @ -170,15 +174,17 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, | |||||||
| 		if (named_instvar > STIX_MAX_NAMED_INSTVARS) goto einval; | 		if (named_instvar > STIX_MAX_NAMED_INSTVARS) goto einval; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	stix_pushtmp (stix, &_class); | ||||||
|  |  | ||||||
| 	switch (indexed_type) | 	switch (indexed_type) | ||||||
| 	{ | 	{ | ||||||
| 		case STIX_OBJ_TYPE_OOP: | 		case STIX_OBJ_TYPE_OOP: | ||||||
| 			/* class for a variable object.  | 			/* both the fixed part(named instance variables) and  | ||||||
| 			 * both the named_instvar-sized part and the variable part are allowed. */ | 			 * the variable part(indexed instance variables) are allowed. */ | ||||||
| 			oop = stix_allocoopobj(stix, named_instvar + vlen); | 			oop = stix_allocoopobj(stix, named_instvar + vlen); | ||||||
| 			if (!oop) return STIX_NULL; | 			if (!oop) return STIX_NULL; | ||||||
|  |  | ||||||
| 			if (vlen > 0) | 			if (vptr && vlen > 0) | ||||||
| 			{ | 			{ | ||||||
| 				stix_oop_oop_t hdr = (stix_oop_oop_t)oop; | 				stix_oop_oop_t hdr = (stix_oop_oop_t)oop; | ||||||
| 				STIX_MEMCPY (&hdr->slot[named_instvar], vptr, vlen * STIX_SIZEOF(stix_oop_t)); | 				STIX_MEMCPY (&hdr->slot[named_instvar], vptr, vlen * STIX_SIZEOF(stix_oop_t)); | ||||||
| @ -186,13 +192,11 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, | |||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 		case STIX_OBJ_TYPE_CHAR: | 		case STIX_OBJ_TYPE_CHAR: | ||||||
| 			/* variable-char class can't have instance variables */ |  | ||||||
| 			oop = stix_alloccharobj(stix, vptr, vlen); | 			oop = stix_alloccharobj(stix, vptr, vlen); | ||||||
| 			if (!oop) return STIX_NULL; | 			if (!oop) return STIX_NULL; | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 		case STIX_OBJ_TYPE_UINT8: | 		case STIX_OBJ_TYPE_UINT8: | ||||||
| 			/* variable-byte class can't have instance variables */ |  | ||||||
| 			oop = stix_allocuint8obj(stix, vptr, vlen); | 			oop = stix_allocuint8obj(stix, vptr, vlen); | ||||||
| 			if (!oop) return STIX_NULL; | 			if (!oop) return STIX_NULL; | ||||||
| 			break; | 			break; | ||||||
| @ -207,7 +211,9 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, | |||||||
| 			return STIX_NULL; | 			return STIX_NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	oop->_class = _class; | 	STIX_OBJ_SET_CLASS (oop, _class); | ||||||
|  | 	stix_poptmp (stix); | ||||||
|  |  | ||||||
| 	return oop; | 	return oop; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
| @ -29,6 +29,12 @@ | |||||||
|  |  | ||||||
| #include "stix.h" | #include "stix.h" | ||||||
|  |  | ||||||
|  | /* this is useful for debugging. stix_gc() can be called  | ||||||
|  |  * while stix has not been fully initialized when this is defined*/ | ||||||
|  | #define STIX_SUPPORT_GC_DURING_IGNITION | ||||||
|  | #define STIX_DEBUG_GC_1 | ||||||
|  |  | ||||||
|  |  | ||||||
| #include <stdio.h> /* TODO: delete these header inclusion lines */ | #include <stdio.h> /* TODO: delete these header inclusion lines */ | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| @ -40,32 +46,10 @@ | |||||||
| #define STIX_ALIGN(x,y) ((((x) + (y) - 1) / (y)) * (y)) | #define STIX_ALIGN(x,y) ((((x) + (y) - 1) / (y)) * (y)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /* ========================================================================= */ | /* ========================================================================= */ | ||||||
| /* CLASS                                                                     */ | /* CLASS SPEC ENCODING                                                       */ | ||||||
| /* ========================================================================= */ | /* ========================================================================= */ | ||||||
|  |  | ||||||
| /* The stix_class_t type defines the internal structure of a class object. */ |  | ||||||
| struct stix_class_t |  | ||||||
| { |  | ||||||
| 	STIX_OBJ_HEADER; |  | ||||||
|  |  | ||||||
| 	stix_oow_t      spec;         /* SmallInteger */ |  | ||||||
| 	stix_oop_oop_t  instmthds;    /* instance methods, MethodDictionary */ |  | ||||||
| 	stix_oop_oop_t  classmthds;   /* class methods, MethodDictionary */ |  | ||||||
| 	stix_oop_oop_t  superclass;   /* Another class */ |  | ||||||
|  |  | ||||||
| 	stix_oop_char_t name;         /* Symbol */ |  | ||||||
| 	stix_oop_char_t instvars;     /* String or Array? */ |  | ||||||
| 	stix_oop_char_t classvars;    /* String or Array? */ |  | ||||||
|  |  | ||||||
| 	/* indexed part afterwards */ |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct stix_class_t stix_class_t; |  | ||||||
| typedef struct stix_class_t* stix_oop_class_t; |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * The spec field of a class object encodes the number of the fixed part |  * The spec field of a class object encodes the number of the fixed part | ||||||
|  * and the type of the indexed part. The fixed part is the number of |  * and the type of the indexed part. The fixed part is the number of | ||||||
| @ -138,20 +122,6 @@ typedef struct stix_class_t* stix_oop_class_t; | |||||||
|  */ |  */ | ||||||
| #define STIX_MAX_INDEXED_INSTVARS(named_instvar) ((~(stix_oow_t)0) - named_instvar) | #define STIX_MAX_INDEXED_INSTVARS(named_instvar) ((~(stix_oow_t)0) - named_instvar) | ||||||
|  |  | ||||||
|  |  | ||||||
| #define STIX_CLASSOF(stix,oop) \ |  | ||||||
| 	(STIX_OOP_IS_NUMERIC(oop)? \ |  | ||||||
| 		((stix_oop_t)(stix)->cc.numeric[((stix_oow_t)oop&3)-1]): \ |  | ||||||
| 		(oop)->_class) |  | ||||||
|  |  | ||||||
| /* |  | ||||||
| #define STIX_BYTESOF(stix,oop) \ |  | ||||||
| 	(STIX_OOP_IS_NUMERIC(oop)? \ |  | ||||||
| 		(STIX_SIZEOF(stix_oow_t)): \ |  | ||||||
| 		(STIX_SIZEOF(stix_obj_t) + STIX_ALIGN(((oop)->size + (oop)->extra) * (oop)->unit), STIX_SIZEOF(stix_oop_t)) \ |  | ||||||
| 	) |  | ||||||
| */ |  | ||||||
|  |  | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| @ -191,6 +161,19 @@ void* stix_allocheapmem ( | |||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* ========================================================================= */ | ||||||
|  | /* stix.c                                                                    */ | ||||||
|  | /* ========================================================================= */ | ||||||
|  | stix_oow_t stix_hashbytes ( | ||||||
|  | 	const stix_uint8_t* ptr, | ||||||
|  | 	stix_oow_t          len | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | stix_oow_t stix_hashchars ( | ||||||
|  | 	const stix_char_t* ptr, | ||||||
|  | 	stix_size_t        len | ||||||
|  | ); | ||||||
|  |  | ||||||
| /* ========================================================================= */ | /* ========================================================================= */ | ||||||
| /* obj.c                                                                     */ | /* obj.c                                                                     */ | ||||||
| /* ========================================================================= */ | /* ========================================================================= */ | ||||||
| @ -199,6 +182,10 @@ void* stix_allocbytes ( | |||||||
| 	stix_size_t size | 	stix_size_t size | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The stix_allocoopobj() function allocates a raw object composed of \a size | ||||||
|  |  * pointer fields excluding the header. | ||||||
|  |  */ | ||||||
| stix_oop_t stix_allocoopobj ( | stix_oop_t stix_allocoopobj ( | ||||||
| 	stix_t*    stix, | 	stix_t*    stix, | ||||||
| 	stix_oow_t size | 	stix_oow_t size | ||||||
| @ -222,6 +209,34 @@ stix_oop_t stix_allocuint16obj ( | |||||||
| 	stix_oow_t           len | 	stix_oow_t           len | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | /* ========================================================================= */ | ||||||
|  | /* sym.c                                                                     */ | ||||||
|  | /* ========================================================================= */ | ||||||
|  | stix_oop_t stix_makesymbol ( | ||||||
|  | 	stix_t*            stix, | ||||||
|  | 	const stix_char_t* ptr, | ||||||
|  | 	stix_oow_t         len | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | stix_oop_t stix_findsymbol ( | ||||||
|  | 	stix_t*            stix, | ||||||
|  | 	const stix_char_t* ptr, | ||||||
|  | 	stix_oow_t         len | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | /* ========================================================================= */ | ||||||
|  | /* dic.c                                                                     */ | ||||||
|  | /* ========================================================================= */ | ||||||
|  | stix_oop_t stix_putatsysdic ( | ||||||
|  | 	stix_t*     stix, | ||||||
|  | 	stix_oop_t  key, | ||||||
|  | 	stix_oop_t  value | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | stix_oop_t stix_getatsysdic ( | ||||||
|  | 	stix_t*     stix, | ||||||
|  | 	stix_oop_t  key | ||||||
|  | ); | ||||||
|  |  | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										142
									
								
								stix/lib/stix.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								stix/lib/stix.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | |||||||
|  | /* | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  |     Copyright (c) 2014-2015 Chung, Hyung-Hwan. All rights reserved. | ||||||
|  |  | ||||||
|  |     Redistribution and use in source and binary forms, with or without | ||||||
|  |     modification, are permitted provided that the following conditions | ||||||
|  |     are met: | ||||||
|  |     1. Redistributions of source code must retain the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer. | ||||||
|  |     2. Redistributions in binary form must reproduce the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer in the | ||||||
|  |        documentation and/or other materials provided with the distribution. | ||||||
|  |  | ||||||
|  |     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||||||
|  |     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||||
|  |     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||||
|  |     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  |     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||||
|  |     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||||
|  |     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||||
|  |     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||||
|  |     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||||
|  |     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "stix-prv.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | stix_t* stix_open (stix_mmgr_t* mmgr, stix_size_t xtnsize, stix_size_t heapsize, stix_errnum_t* errnum) | ||||||
|  | { | ||||||
|  | 	stix_t* stix; | ||||||
|  |  | ||||||
|  | 	stix = STIX_MMGR_ALLOC (mmgr, STIX_SIZEOF(*stix) + xtnsize); | ||||||
|  | 	if (stix) | ||||||
|  | 	{ | ||||||
|  | 		if (stix_init(stix, mmgr, heapsize) <= -1) | ||||||
|  | 		{ | ||||||
|  | 			if (errnum) *errnum = stix->errnum; | ||||||
|  | 			STIX_MMGR_FREE (mmgr, stix); | ||||||
|  | 			stix = STIX_NULL; | ||||||
|  | 		} | ||||||
|  | 		else STIX_MEMSET (stix + 1, 0, xtnsize); | ||||||
|  | 	} | ||||||
|  | 	else if (errnum) | ||||||
|  | 	{ | ||||||
|  | 		*errnum = STIX_ENOMEM; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return stix; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void stix_close (stix_t* stix) | ||||||
|  | { | ||||||
|  | 	stix_fini (stix); | ||||||
|  | 	STIX_MMGR_FREE (stix->mmgr, stix); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int stix_init (stix_t* stix, stix_mmgr_t* mmgr, stix_size_t heapsz) | ||||||
|  | { | ||||||
|  | 	STIX_MEMSET (stix, 0, STIX_SIZEOF(*stix)); | ||||||
|  | 	stix->mmgr = mmgr; | ||||||
|  |  | ||||||
|  | 	/*stix->permheap = stix_makeheap (stix, what is the best size???); | ||||||
|  | 	if (!stix->curheap) goto oops; */ | ||||||
|  | 	stix->curheap = stix_makeheap (stix, heapsz); | ||||||
|  | 	if (!stix->curheap) goto oops; | ||||||
|  | 	stix->newheap = stix_makeheap (stix, heapsz); | ||||||
|  | 	if (!stix->newheap) goto oops; | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  |  | ||||||
|  | oops: | ||||||
|  | 	if (stix->newheap) stix_killheap (stix, stix->newheap); | ||||||
|  | 	if (stix->curheap) stix_killheap (stix, stix->curheap); | ||||||
|  | 	if (stix->permheap) stix_killheap (stix, stix->permheap); | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void stix_fini (stix_t* stix) | ||||||
|  | { | ||||||
|  | 	stix_killheap (stix, stix->newheap); | ||||||
|  | 	stix_killheap (stix, stix->curheap); | ||||||
|  | 	stix_killheap (stix, stix->permheap); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int stix_setoption (stix_t* stix, stix_option_t id, const void* value) | ||||||
|  | { | ||||||
|  | 	switch (id) | ||||||
|  | 	{ | ||||||
|  | 		case STIX_TRAIT: | ||||||
|  | 			stix->option.trait = *(const int*)value; | ||||||
|  | 			return 0; | ||||||
|  |  | ||||||
|  | 		case STIX_DEFAULT_SYMTAB_SIZE: | ||||||
|  | 			stix->option.default_symtab_size = *(stix_oow_t*)value; | ||||||
|  |  | ||||||
|  | 		case STIX_DEFAULT_SYSDIC_SIZE: | ||||||
|  | 			stix->option.default_sysdic_size = *(stix_oow_t*)value; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	stix->errnum = STIX_EINVAL; | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int stix_getoption (stix_t* stix, stix_option_t id, void* value) | ||||||
|  | { | ||||||
|  | 	switch  (id) | ||||||
|  | 	{ | ||||||
|  | 		case STIX_TRAIT: | ||||||
|  | 			*(int*)value = stix->option.trait; | ||||||
|  | 			return 0; | ||||||
|  |  | ||||||
|  | 		case STIX_DEFAULT_SYMTAB_SIZE: | ||||||
|  | 			*(stix_oow_t*)value = stix->option.default_symtab_size; | ||||||
|  |  | ||||||
|  | 		case STIX_DEFAULT_SYSDIC_SIZE: | ||||||
|  | 			*(stix_oow_t*)value = stix->option.default_sysdic_size; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	stix->errnum = STIX_EINVAL; | ||||||
|  | 	return -1; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | stix_oow_t stix_hashbytes (const stix_uint8_t* ptr, stix_oow_t len) | ||||||
|  | { | ||||||
|  | 	stix_oow_t h = 0; | ||||||
|  | 	const stix_uint8_t* bp, * be; | ||||||
|  |  | ||||||
|  | 	bp = ptr; be = bp + len; | ||||||
|  | 	while (bp < be) h = h * 31 + *bp++; | ||||||
|  |  | ||||||
|  | 	return h; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | stix_oow_t stix_hashchars (const stix_char_t* ptr, stix_size_t len) | ||||||
|  | { | ||||||
|  | 	return stix_hashbytes ((const stix_uint8_t *)ptr, len * STIX_SIZEOF(*ptr)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										243
									
								
								stix/lib/stix.h
									
									
									
									
									
								
							
							
						
						
									
										243
									
								
								stix/lib/stix.h
									
									
									
									
									
								
							| @ -188,7 +188,9 @@ typedef enum stix_errnum_t stix_errnum_t; | |||||||
|  |  | ||||||
| enum stix_option_t | enum stix_option_t | ||||||
| { | { | ||||||
| 	STIX_TRAIT | 	STIX_TRAIT, | ||||||
|  | 	STIX_DEFAULT_SYMTAB_SIZE, | ||||||
|  | 	STIX_DEFAULT_SYSDIC_SIZE | ||||||
| }; | }; | ||||||
| typedef enum stix_option_t stix_option_t; | typedef enum stix_option_t stix_option_t; | ||||||
|  |  | ||||||
| @ -383,53 +385,6 @@ enum stix_code_t | |||||||
| typedef enum stix_code_t stix_code_t; | typedef enum stix_code_t stix_code_t; | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct stix_heap_t stix_heap_t; |  | ||||||
|  |  | ||||||
| struct stix_heap_t |  | ||||||
| { |  | ||||||
| 	stix_uint8_t* base;  /* start of a heap */ |  | ||||||
| 	stix_uint8_t* limit; /* end of a heap */ |  | ||||||
| 	stix_uint8_t* ptr;   /* next allocation pointer */ |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| typedef struct stix_t stix_t; |  | ||||||
|  |  | ||||||
| struct stix_t |  | ||||||
| { |  | ||||||
| 	stix_mmgr_t*  mmgr; |  | ||||||
| 	stix_errnum_t errnum; |  | ||||||
|  |  | ||||||
| 	struct |  | ||||||
| 	{ |  | ||||||
| 		int trait; |  | ||||||
| 	} option; |  | ||||||
|  |  | ||||||
| 	/* ========================= */ |  | ||||||
|  |  | ||||||
| 	stix_heap_t* permheap; |  | ||||||
| 	stix_heap_t* curheap; |  | ||||||
| 	stix_heap_t* newheap; |  | ||||||
|  |  | ||||||
| 	/* ========================= */ |  | ||||||
|  |  | ||||||
| 	stix_oop_t _nil;  /* pointer to the nil object */ |  | ||||||
| 	stix_oop_t _true; |  | ||||||
| 	stix_oop_t _false; |  | ||||||
|  |  | ||||||
| 	stix_oop_oop_t root; /* pointer to the system dictionary */ |  | ||||||
| 	stix_oop_oop_t symtab; /* system-wide symbol table */ |  | ||||||
|  |  | ||||||
| 	struct |  | ||||||
| 	{ |  | ||||||
| 		stix_oop_oop_t array; |  | ||||||
| 		stix_oop_oop_t association; |  | ||||||
| 		/*stix_oop_oop_t metaclass;*/ |  | ||||||
| 		stix_oop_oop_t string; |  | ||||||
| 		stix_oop_oop_t symbol; |  | ||||||
| 		stix_oop_oop_t sysdic; |  | ||||||
| 		stix_oop_oop_t numeric[2]; /* [0]: smint [1]: character */ |  | ||||||
| 	} cc; /* common kernel classes */ |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /*  | /*  | ||||||
| @ -453,6 +408,7 @@ struct stix_t | |||||||
|  |  | ||||||
| #define STIX_OOP_IS_NUMERIC(oop) (((stix_oow_t)oop) & (STIX_OOP_TAG_SMINT | STIX_OOP_TAG_CHAR)) | #define STIX_OOP_IS_NUMERIC(oop) (((stix_oow_t)oop) & (STIX_OOP_TAG_SMINT | STIX_OOP_TAG_CHAR)) | ||||||
| #define STIX_OOP_IS_POINTER(oop) (!STIX_OOP_IS_NUMERIC(oop)) | #define STIX_OOP_IS_POINTER(oop) (!STIX_OOP_IS_NUMERIC(oop)) | ||||||
|  | #define STIX_OOP_GET_TAG(oop) (((stix_oow_t)oop) & STIX_LBMASK(stix_oow_t, STIX_OOP_TAG_BITS)) | ||||||
|  |  | ||||||
| #define STIX_OOP_IS_SMINT(oop) (((stix_oow_t)oop) & STIX_OOP_TAG_SMINT) | #define STIX_OOP_IS_SMINT(oop) (((stix_oow_t)oop) & STIX_OOP_TAG_SMINT) | ||||||
| #define STIX_OOP_IS_CHAR(oop) (((stix_oow_t)oop) & STIX_OOP_TAG_CHAR) | #define STIX_OOP_IS_CHAR(oop) (((stix_oow_t)oop) & STIX_OOP_TAG_CHAR) | ||||||
| @ -528,15 +484,19 @@ typedef enum stix_obj_type_t stix_obj_type_t; | |||||||
| #define STIX_OBJ_GET_FLAGS_TYPE(oop)     STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_TYPE_BITS) | #define STIX_OBJ_GET_FLAGS_TYPE(oop)     STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_TYPE_BITS) | ||||||
| #define STIX_OBJ_GET_FLAGS_UNIT(oop)     STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS),                            STIX_OBJ_FLAGS_UNIT_BITS) | #define STIX_OBJ_GET_FLAGS_UNIT(oop)     STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS),                            STIX_OBJ_FLAGS_UNIT_BITS) | ||||||
| #define STIX_OBJ_GET_FLAGS_EXTRA(oop)    STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS),                                                        STIX_OBJ_FLAGS_EXTRA_BITS) | #define STIX_OBJ_GET_FLAGS_EXTRA(oop)    STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS),                                                        STIX_OBJ_FLAGS_EXTRA_BITS) | ||||||
| #define STIX_OBJ_GET_FLAGS_KERNEL(oop)   STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_UNIT_BITS),                                                                                            STIX_OBJ_FLAGS_KERNEL_BITS) | #define STIX_OBJ_GET_FLAGS_KERNEL(oop)   STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_MOVED_BITS),                                                                                     STIX_OBJ_FLAGS_KERNEL_BITS) | ||||||
| #define STIX_OBJ_GET_FLAGS_MOVED(oop)    STIX_GETBITS(stix_oow_t, (oop)->_flags, 0,                                                                                                               STIX_OBJ_FLAGS_MOVED_BITS) | #define STIX_OBJ_GET_FLAGS_MOVED(oop)    STIX_GETBITS(stix_oow_t, (oop)->_flags, 0,                                                                                                               STIX_OBJ_FLAGS_MOVED_BITS) | ||||||
|  |  | ||||||
| #define STIX_OBJ_SET_FLAGS_TYPE(oop,v)   STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_TYPE_BITS,   v) | #define STIX_OBJ_SET_FLAGS_TYPE(oop,v)   STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS), STIX_OBJ_FLAGS_TYPE_BITS,   v) | ||||||
| #define STIX_OBJ_SET_FLAGS_UNIT(oop,v)   STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS),                            STIX_OBJ_FLAGS_UNIT_BITS,   v) | #define STIX_OBJ_SET_FLAGS_UNIT(oop,v)   STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS),                            STIX_OBJ_FLAGS_UNIT_BITS,   v) | ||||||
| #define STIX_OBJ_SET_FLAGS_EXTRA(oop,v)  STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS),                                                        STIX_OBJ_FLAGS_EXTRA_BITS,  v) | #define STIX_OBJ_SET_FLAGS_EXTRA(oop,v)  STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS),                                                        STIX_OBJ_FLAGS_EXTRA_BITS,  v) | ||||||
| #define STIX_OBJ_SET_FLAGS_KERNEL(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_UNIT_BITS),                                                                                            STIX_OBJ_FLAGS_KERNEL_BITS, v) | #define STIX_OBJ_SET_FLAGS_KERNEL(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_MOVED_BITS),                                                                                     STIX_OBJ_FLAGS_KERNEL_BITS, v) | ||||||
| #define STIX_OBJ_SET_FLAGS_MOVED(oop,v)  STIX_SETBITS(stix_oow_t, (oop)->_flags, 0,                                                                                                               STIX_OBJ_FLAGS_MOVED_BITS,  v) | #define STIX_OBJ_SET_FLAGS_MOVED(oop,v)  STIX_SETBITS(stix_oow_t, (oop)->_flags, 0,                                                                                                               STIX_OBJ_FLAGS_MOVED_BITS,  v) | ||||||
|  |  | ||||||
|  | #define STIX_OBJ_GET_SIZE(oop) ((oop)->_size) | ||||||
|  | #define STIX_OBJ_GET_CLASS(oop) ((oop)->_class) | ||||||
|  | #define STIX_OBJ_SET_CLASS(oop,c) ((oop)->_class = (c)) | ||||||
|  |  | ||||||
| /* this macro doesn't check the range of the actual value. | /* this macro doesn't check the range of the actual value. | ||||||
|  * make sure that the value of each bit fields given fall within the number |  * make sure that the value of each bit fields given fall within the number | ||||||
|  * of defined bits */ |  * of defined bits */ | ||||||
| @ -582,8 +542,48 @@ struct stix_obj_uint16_t | |||||||
| 	stix_uint16_t slot[1]; | 	stix_uint16_t slot[1]; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #if 0 | #define STIX_CLASS_NAMED_INSTVARS 8 | ||||||
|  | struct stix_class_t | ||||||
|  | { | ||||||
|  | 	STIX_OBJ_HEADER; | ||||||
|  |  | ||||||
|  | 	stix_oop_t      spec;         /* SmallInteger */ | ||||||
|  | 	stix_oop_t      superclass;   /* Another class */ | ||||||
|  | 	stix_oop_t      subclasses;   /* Array of subclasses */ | ||||||
|  | 	stix_oop_char_t name;         /* Symbol */ | ||||||
|  | 	stix_oop_char_t instvars;     /* String or Array? */ | ||||||
|  | 	stix_oop_char_t classvars;    /* String or Array? */ | ||||||
|  |  | ||||||
|  | 	stix_oop_oop_t  instmthds;    /* instance methods, MethodDictionary */ | ||||||
|  | 	stix_oop_oop_t  classmthds;   /* class methods, MethodDictionary */ | ||||||
|  |  | ||||||
|  | 	/* indexed part afterwards */ | ||||||
|  | 	stix_oop_t      classvar[1];  /* most classes have not class variables. better to be 0 */ | ||||||
|  | }; | ||||||
|  | typedef struct stix_class_t stix_class_t; | ||||||
|  | typedef struct stix_class_t* stix_oop_class_t; | ||||||
|  |  | ||||||
|  | #define STIX_SET_NAMED_INSTVARS 2 | ||||||
|  | struct stix_set_t | ||||||
|  | { | ||||||
|  | 	STIX_OBJ_HEADER; | ||||||
|  | 	stix_oop_t     tally;  /* SmallInteger */ | ||||||
|  | 	stix_oop_oop_t bucket; /* Array */ | ||||||
|  | }; | ||||||
|  | typedef struct stix_set_t stix_set_t; | ||||||
|  | typedef struct stix_set_t* stix_oop_set_t; | ||||||
|  |  | ||||||
|  | #define STIX_ASSOCIATION_NAMED_INSTVARS 2 | ||||||
|  | struct stix_association_t | ||||||
|  | { | ||||||
|  | 	STIX_OBJ_HEADER; | ||||||
|  | 	stix_oop_t key; | ||||||
|  | 	stix_oop_t value; | ||||||
|  | }; | ||||||
|  | typedef struct stix_association_t stix_association_t; | ||||||
|  | typedef struct stix_association_t* stix_oop_association_t; | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
| /* ----------------------------------------- | /* ----------------------------------------- | ||||||
|  * class structures for classes known to VM   |  * class structures for classes known to VM   | ||||||
|  * ----------------------------------------- */ |  * ----------------------------------------- */ | ||||||
| @ -653,62 +653,75 @@ enum stix_class_desc_t | |||||||
| 	STIX_SYSDIC_BUCKET = STIX_DICTIONARY_BUCKET, | 	STIX_SYSDIC_BUCKET = STIX_DICTIONARY_BUCKET, | ||||||
| 	STIX_SYSDIC_SIZE = STIX_DICTIONARY_SIZE | 	STIX_SYSDIC_SIZE = STIX_DICTIONARY_SIZE | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| struct stix_kcinfo_t |  | ||||||
| { |  | ||||||
| 	const stix_char_t* name; |  | ||||||
| 	int          super; |  | ||||||
| 	int          fixed; /* the number of fixed fields */ |  | ||||||
| 	int          vtype; /* variable class type */ |  | ||||||
|  |  | ||||||
| 	int          nivars;    /* instance variables */ |  | ||||||
| 	stix_cstr_t    ivars[10]; |  | ||||||
|  |  | ||||||
| 	int          ncvars;    /* class variables */ |  | ||||||
| 	stix_cstr_t    cvars[10]; |  | ||||||
|  |  | ||||||
| 	int          ncivars;   /* class instance variables */ |  | ||||||
| 	stix_cstr_t    civars[10]; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| typedef struct stix_kcinfo_t stix_kcinfo_t; |  | ||||||
|  |  | ||||||
| enum stix_kc_t |  | ||||||
| { |  | ||||||
| 	STIX_VM_KC_OBJECT, |  | ||||||
| 	STIX_VM_KC_UNDEFINED_OBJECT, |  | ||||||
| 	STIX_VM_KC_BEHAVIOR, |  | ||||||
| 	STIX_VM_KC_CLASS, |  | ||||||
| 	STIX_VM_KC_METACLASS, |  | ||||||
| 	STIX_VM_KC_BLOCK, |  | ||||||
| 	STIX_VM_KC_BOOLEAN, |  | ||||||
| 	STIX_VM_KC_TRUE, |  | ||||||
| 	STIX_VM_KC_FALSE, |  | ||||||
| 	STIX_VM_KC_CONTEXT, |  | ||||||
| 	STIX_VM_KC_METHOD, |  | ||||||
| 	STIX_VM_KC_MAGNITUDE, |  | ||||||
| 	STIX_VM_KC_ASSOCIATION, |  | ||||||
| 	STIX_VM_KC_CHARACTER, |  | ||||||
| 	STIX_VM_KC_NUMBER, |  | ||||||
| 	STIX_VM_KC_INTEGER, |  | ||||||
| 	STIX_VM_KC_SMALL_INTEGER, |  | ||||||
| 	STIX_VM_KC_LARGE_INTEGER, |  | ||||||
| 	STIX_VM_KC_COLLECTION, |  | ||||||
| 	STIX_VM_KC_INDEXED_COLLECTION, |  | ||||||
| 	STIX_VM_KC_ARRAY, |  | ||||||
| 	STIX_VM_KC_BYTE_ARRAY, |  | ||||||
| 	STIX_VM_KC_SYMBOL_TABLE, |  | ||||||
| 	STIX_VM_KC_DICTIONARY, |  | ||||||
| 	STIX_VM_KC_SYSTEM_DICTIONARY, |  | ||||||
| 	STIX_VM_KC_STRING, |  | ||||||
| 	STIX_VM_KC_SYMBOL, |  | ||||||
|  |  | ||||||
| 	STIX_VM_KC_MAX /* indicate the number of kernel classes */ |  | ||||||
| }; |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #define STIX_CLASSOF(stix,oop) ( \ | ||||||
|  | 	STIX_OOP_IS_SMINT(oop)? (stix)->_small_integer: \ | ||||||
|  | 	STIX_OOP_IS_CHAR(oop)? (stix)->_character: (oop)->_class \ | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | #define STIX_BYTESOF(stix,oop) \ | ||||||
|  | 	(STIX_OOP_IS_NUMERIC(oop)? \ | ||||||
|  | 		(STIX_SIZEOF(stix_oow_t)): \ | ||||||
|  | 		(STIX_SIZEOF(stix_obj_t) + STIX_ALIGN(((oop)->size + (oop)->extra) * (oop)->unit), STIX_SIZEOF(stix_oop_t)) \ | ||||||
|  | 	) | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | typedef struct stix_heap_t stix_heap_t; | ||||||
|  |  | ||||||
|  | struct stix_heap_t | ||||||
|  | { | ||||||
|  | 	stix_uint8_t* base;  /* start of a heap */ | ||||||
|  | 	stix_uint8_t* limit; /* end of a heap */ | ||||||
|  | 	stix_uint8_t* ptr;   /* next allocation pointer */ | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | typedef struct stix_t stix_t; | ||||||
|  |  | ||||||
|  | struct stix_t | ||||||
|  | { | ||||||
|  | 	stix_mmgr_t*  mmgr; | ||||||
|  | 	stix_errnum_t errnum; | ||||||
|  |  | ||||||
|  | 	struct | ||||||
|  | 	{ | ||||||
|  | 		int trait; | ||||||
|  | 		stix_oow_t default_symtab_size; | ||||||
|  | 		stix_oow_t default_sysdic_size; | ||||||
|  | 	} option; | ||||||
|  |  | ||||||
|  | 	/* ========================= */ | ||||||
|  |  | ||||||
|  | 	stix_heap_t* permheap; /* TODO: put kernel objects to here */ | ||||||
|  | 	stix_heap_t* curheap; | ||||||
|  | 	stix_heap_t* newheap; | ||||||
|  |  | ||||||
|  | 	/* ========================= */ | ||||||
|  | 	stix_oop_t _nil;  /* pointer to the nil object */ | ||||||
|  | 	stix_oop_t _true; | ||||||
|  | 	stix_oop_t _false; | ||||||
|  |  | ||||||
|  | 	stix_oop_t _stix; /* Stix */ | ||||||
|  | 	stix_oop_t _nil_object; /* NilObject */ | ||||||
|  | 	stix_oop_t _class; /* Class */ | ||||||
|  | 	stix_oop_t _object; /* Object */ | ||||||
|  | 	stix_oop_t _symbol; /* Symbol */ | ||||||
|  | 	stix_oop_t _array; /* Array */ | ||||||
|  | 	stix_oop_t _symbol_set; /* SymbolSet */ | ||||||
|  | 	stix_oop_t _system_dictionary; /* SystemDictionary */ | ||||||
|  | 	stix_oop_t _association; /* Association */ | ||||||
|  | 	stix_oop_t _character; /* Character */ | ||||||
|  | 	stix_oop_t _small_integer; /* SmallInteger */ | ||||||
|  |  | ||||||
|  | 	stix_oop_set_t symtab; /* system-wide symbol table. instance of SymbolSet */ | ||||||
|  | 	stix_oop_set_t sysdic; /* system dictionary. instance of SystemDictionary */ | ||||||
|  |  | ||||||
|  | 	stix_oop_t* tmp_stack[100]; /* stack for temporaries */ | ||||||
|  | 	stix_oow_t tmp_count; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| @ -796,8 +809,6 @@ STIX_EXPORT stix_oop_t stix_instantiate ( | |||||||
| 	stix_oow_t       vlen | 	stix_oow_t       vlen | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * The stix_ignite() function creates key initial objects. |  * The stix_ignite() function creates key initial objects. | ||||||
|  */ |  */ | ||||||
| @ -805,6 +816,24 @@ STIX_EXPORT int stix_ignite ( | |||||||
| 	stix_t* stix | 	stix_t* stix | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Temporary OOP management  | ||||||
|  |  */ | ||||||
|  | STIX_EXPORT void stix_pushtmp ( | ||||||
|  | 	stix_t*     stix, | ||||||
|  | 	stix_oop_t* oop_ptr | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | STIX_EXPORT void stix_poptmp ( | ||||||
|  | 	stix_t*     stix | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | STIX_EXPORT void stix_poptmps ( | ||||||
|  | 	stix_t*     stix, | ||||||
|  | 	stix_oow_t  count | ||||||
|  | ); | ||||||
|  |  | ||||||
| #if defined(__cplusplus) | #if defined(__cplusplus) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
							
								
								
									
										151
									
								
								stix/lib/sym.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								stix/lib/sym.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,151 @@ | |||||||
|  | /* | ||||||
|  |  * $Id$ | ||||||
|  |  * | ||||||
|  |     Copyright (c) 2014-2015 Chung, Hyung-Hwan. All rights reserved. | ||||||
|  |  | ||||||
|  |     Redistribution and use in source and binary forms, with or without | ||||||
|  |     modification, are permitted provided that the following conditions | ||||||
|  |     are met: | ||||||
|  |     1. Redistributions of source code must retain the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer. | ||||||
|  |     2. Redistributions in binary form must reproduce the above copyright | ||||||
|  |        notice, this list of conditions and the following disclaimer in the | ||||||
|  |        documentation and/or other materials provided with the distribution. | ||||||
|  |  | ||||||
|  |     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||||||
|  |     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||||
|  |     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||||
|  |     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  |     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||||
|  |     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||||
|  |     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||||
|  |     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||||
|  |     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||||
|  |     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include "stix-prv.h" | ||||||
|  |  | ||||||
|  | static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t old_bucket) | ||||||
|  | { | ||||||
|  | 	stix_oop_oop_t new_bucket; | ||||||
|  | 	stix_oow_t oldsz, newsz, index; | ||||||
|  | 	stix_oop_char_t symbol; | ||||||
|  |  | ||||||
|  | /* TODO: derive a better growth size */ | ||||||
|  | 	new_bucket = (stix_oop_oop_t)stix_instantiate (stix, stix->_array, STIX_NULL, STIX_OBJ_GET_SIZE(old_bucket) * 2);  | ||||||
|  | 	if (!new_bucket) return STIX_NULL; | ||||||
|  |  | ||||||
|  | 	oldsz = STIX_OBJ_GET_SIZE(old_bucket); | ||||||
|  | 	newsz = STIX_OBJ_GET_SIZE(new_bucket); | ||||||
|  |  | ||||||
|  | 	while (oldsz > 0) | ||||||
|  | 	{ | ||||||
|  | 		symbol = (stix_oop_char_t)old_bucket->slot[--oldsz]; | ||||||
|  | 		if ((stix_oop_t)symbol != stix->_nil) | ||||||
|  | 		{ | ||||||
|  | 			STIX_ASSERT (STIX_CLASSOF(stix,symbol) == stix->_symbol); | ||||||
|  | 			/*STIX_ASSERT (sym->size > 0);*/ | ||||||
|  |  | ||||||
|  | 			index = stix_hashchars(symbol->slot, STIX_OBJ_GET_SIZE(symbol)) % newsz; | ||||||
|  | 			while (new_bucket->slot[index] != stix->_nil)  | ||||||
|  | 				index = (index + 1) % newsz; | ||||||
|  | 			new_bucket->slot[index] = (stix_oop_t)symbol; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return new_bucket; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static stix_oop_t find_or_make_symbol (stix_t* stix, const stix_char_t* ptr, stix_oow_t len, int create) | ||||||
|  | { | ||||||
|  | 	stix_oow_t index, tally; | ||||||
|  | 	stix_oop_char_t symbol; | ||||||
|  |  | ||||||
|  | 	STIX_ASSERT (len > 0); | ||||||
|  | 	if (len <= 0)  | ||||||
|  | 	{ | ||||||
|  | 		/* i don't allow an empty symbol name */ | ||||||
|  | 		stix->errnum = STIX_EINVAL; | ||||||
|  | 		return STIX_NULL; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	STIX_ASSERT (STIX_CLASSOF(stix,stix->symtab->bucket) == stix->_array); | ||||||
|  | 	index = stix_hashchars(ptr, len) % STIX_OBJ_GET_SIZE(stix->symtab->bucket); | ||||||
|  |  | ||||||
|  | 	/* find a matching symbol in the open-addressed symbol table */ | ||||||
|  | 	while (stix->symtab->bucket->slot[index] != stix->_nil)  | ||||||
|  | 	{ | ||||||
|  | 		symbol = (stix_oop_char_t)stix->symtab->bucket->slot[index]; | ||||||
|  | 		STIX_ASSERT (STIX_CLASSOF(stix,symbol) == (stix_oop_t)stix->_symbol); | ||||||
|  |  | ||||||
|  | 		if (len == STIX_OBJ_GET_SIZE(symbol)) | ||||||
|  | 		{ | ||||||
|  | 			stix_oow_t i; | ||||||
|  |  | ||||||
|  | 			for (i = 0; i < len; i++) | ||||||
|  | 			{ | ||||||
|  | 				if (ptr[i] != symbol->slot[i]) goto not_equal; | ||||||
|  | 			} | ||||||
|  | 			return (stix_oop_t)symbol; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	not_equal: | ||||||
|  | 		index = (index + 1) % STIX_OBJ_GET_SIZE(stix->symtab->bucket); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (!create)  | ||||||
|  | 	{ | ||||||
|  | 		/* | ||||||
|  | 		stix->errnum = STIX_ENOENT; | ||||||
|  | 		return STIX_NULL; | ||||||
|  | 		*/ | ||||||
|  | 		return stix->_nil; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	tally = STIX_OOP_TO_SMINT(stix->symtab->tally); | ||||||
|  | 	if (tally + 1 >= STIX_OBJ_GET_SIZE(stix->symtab->bucket)) | ||||||
|  | 	{ | ||||||
|  | 		stix_oop_oop_t bucket; | ||||||
|  |  | ||||||
|  | 		/* TODO: make the growth policy configurable instead of growing | ||||||
|  | 			     it just before it gets full. The polcy can be grow it	 | ||||||
|  | 			     if it's 70% full */ | ||||||
|  |  | ||||||
|  | 		/* Enlarge the symbol table before it gets full to | ||||||
|  | 		 * make sure that it has at least one free slot left | ||||||
|  | 		 * after having added a new symbol. this is to help | ||||||
|  | 		 * traversal end at a _nil slot if no entry is found. */ | ||||||
|  | 		bucket = expand_bucket (stix, stix->symtab->bucket); | ||||||
|  | 		if (!bucket) return STIX_NULL; | ||||||
|  |  | ||||||
|  | 		stix->symtab->bucket = bucket; | ||||||
|  |  | ||||||
|  | 		/* recalculate the index for the expanded bucket */ | ||||||
|  | 		index = stix_hashchars(ptr, len) % STIX_OBJ_GET_SIZE(stix->symtab->bucket); | ||||||
|  |  | ||||||
|  | 		while (stix->symtab->bucket->slot[index] != stix->_nil)  | ||||||
|  | 			index = (index + 1) % STIX_OBJ_GET_SIZE(stix->symtab->bucket); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	/* create a new symbol since it isn't found in the symbol table */ | ||||||
|  | 	symbol = (stix_oop_char_t)stix_instantiate (stix, stix->_symbol, ptr, len); | ||||||
|  | 	if (symbol) | ||||||
|  | 	{ | ||||||
|  | 		stix->symtab->tally = STIX_OOP_FROM_SMINT(tally + 1); | ||||||
|  | 		stix->symtab->bucket->slot[index] = (stix_oop_t)symbol; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return (stix_oop_t)symbol; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | stix_oop_t stix_makesymbol (stix_t* stix, const stix_char_t* ptr, stix_oow_t len) | ||||||
|  | { | ||||||
|  | 	return find_or_make_symbol (stix, ptr, len, 1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | stix_oop_t stix_findsymbol (stix_t* stix, const stix_char_t* ptr, stix_oow_t len) | ||||||
|  | { | ||||||
|  | 	return find_or_make_symbol (stix, ptr, len, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user