added many lines of code for initial loading
This commit is contained in:
parent
c74266293d
commit
0b97fee2c4
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);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user