added more code to stix_genpfmethod(). still incomplete

This commit is contained in:
hyunghwan.chung 2016-12-03 18:08:31 +00:00
parent 7b5fc708f7
commit b4a513cf40
9 changed files with 210 additions and 160 deletions

View File

@ -21,18 +21,18 @@
#method(#class) open: name for: mode
{
^(super new: 1) open: name for: mode
^(self new) open: name for: mode
}
#method open: name for: mode
{
<primitive: #stdio_open>
}
## #method open: name for: mode
## {
## <primitive: #stdio_open>
## }
#method close
{
<primitive: #stdio_close>
}
## #method close
## {
## <primitive: #stdio_close>
## }
}
#extend Stdio

View File

@ -45,12 +45,6 @@ enum class_mod_t
CLASS_INDEXED = (1 << 0)
};
enum mth_type_t
{
MTH_INSTANCE,
MTH_CLASS
};
enum var_type_t
{
/* NEVER Change the order and the value of 3 items below.
@ -1985,20 +1979,20 @@ static STIX_INLINE int add_class_level_variable (stix_t* stix, var_type_t index,
static STIX_INLINE int add_pool_dictionary (stix_t* stix, const stix_oocs_t* name, stix_oop_set_t pooldic_oop)
{
if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_oop_capa)
if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_imp_oops_capa)
{
stix_oow_t new_capa;
stix_oop_set_t* tmp;
new_capa = STIX_ALIGN(stix->c->cls.pooldic_oop_capa + 1, POOLDIC_OOP_BUFFER_ALIGN);
tmp = stix_reallocmem (stix, stix->c->cls.pooldic_oops, new_capa * STIX_SIZEOF(stix_oop_set_t));
new_capa = STIX_ALIGN(stix->c->cls.pooldic_imp_oops_capa + 1, POOLDIC_OOP_BUFFER_ALIGN);
tmp = stix_reallocmem (stix, stix->c->cls.pooldic_imp_oops, new_capa * STIX_SIZEOF(stix_oop_set_t));
if (!tmp) return -1;
stix->c->cls.pooldic_oop_capa = new_capa;
stix->c->cls.pooldic_oops = tmp;
stix->c->cls.pooldic_imp_oops_capa = new_capa;
stix->c->cls.pooldic_imp_oops = tmp;
}
stix->c->cls.pooldic_oops[stix->c->cls.pooldic_count] = pooldic_oop;
stix->c->cls.pooldic_imp_oops[stix->c->cls.pooldic_count] = pooldic_oop;
stix->c->cls.pooldic_count++;
/* TODO: check if pooldic_count overflows */
@ -2195,7 +2189,11 @@ static int add_method_name_fragment (stix_t* stix, const stix_oocs_t* name)
static int method_exists (stix_t* stix, const stix_oocs_t* name)
{
/* check if the current class contains a method of the given name */
#ifdef MTHDIC
return stix_lookupdic (stix, stix->c->cls.mthdic_oop[stix->c->mth.type], name) != STIX_NULL;
#else
return stix_lookupdic (stix, stix->c->cls.self_oop->mthdic[stix->c->mth.type], name) != STIX_NULL;
#endif
}
static int add_temporary_variable (stix_t* stix, const stix_oocs_t* name)
@ -2365,7 +2363,7 @@ static int resolve_pooldic (stix_t* stix, int dotted, const stix_oocs_t* name)
/* check if the same dictionary pool has been declared for import */
for (i = 0; i < stix->c->cls.pooldic_count; i++)
{
if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_oops[i])
if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_imp_oops[i])
{
set_syntax_error (stix, STIX_SYNERR_POOLDICDUP, TOKEN_LOC(stix), name);
return -1;
@ -2391,7 +2389,7 @@ static int import_pool_dictionary (stix_t* stix, stix_oop_set_t ns_oop, const st
/* check if the same dictionary pool has been declared for import */
for (i = 0; i < stix->c->cls.pooldic_count; i++)
{
if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_oops[i])
if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_imp_oops[i])
{
set_syntax_error (stix, STIX_SYNERR_POOLDICDUP, tok_loc, tok_name);
return -1;
@ -2897,7 +2895,7 @@ static int get_variable_info (stix_t* stix, const stix_oocs_t* name, const stix_
switch (var->type)
{
case VAR_INSTANCE:
if (stix->c->mth.type == MTH_CLASS)
if (stix->c->mth.type == STIX_METHOD_CLASS)
{
/* a class method cannot access an instance variable */
set_syntax_error (stix, STIX_SYNERR_VARINACC, name_loc, name);
@ -2918,7 +2916,7 @@ static int get_variable_info (stix_t* stix, const stix_oocs_t* name, const stix_
case VAR_CLASSINST:
/* class instance variable can be accessed by only class methods */
if (stix->c->mth.type == MTH_INSTANCE)
if (stix->c->mth.type == STIX_METHOD_INSTANCE)
{
/* an instance method cannot access a class-instance variable */
set_syntax_error (stix, STIX_SYNERR_VARINACC, name_loc, name);
@ -2958,7 +2956,7 @@ static int get_variable_info (stix_t* stix, const stix_oocs_t* name, const stix_
/* attempt to find the variable in pool dictionaries */
for (i = 0; i < stix->c->cls.pooldic_count; i++)
{
ass = stix_lookupdic (stix, stix->c->cls.pooldic_oops[i], name);
ass = stix_lookupdic (stix, stix->c->cls.pooldic_imp_oops[i], name);
if (ass)
{
if (ass2)
@ -4344,7 +4342,7 @@ static int add_compiled_method (stix_t* stix)
else if (stix->c->mth.pftype == 2)
{
preamble_code = STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE;
preamble_index = stix->c->mth.pfnum;
preamble_index = stix->c->mth.pfnum; /* index to literal frame */
}
else if (stix->c->mth.pftype == 3)
{
@ -4385,7 +4383,11 @@ need to write code to collect string.
stix_poptmps (stix, tmp_count); tmp_count = 0;
#ifdef MTHDIC
if (!stix_putatdic(stix, stix->c->cls.mthdic_oop[stix->c->mth.type], (stix_oop_t)name, (stix_oop_t)mth)) goto oops;
#else
if (!stix_putatdic(stix, stix->c->cls.self_oop->mthdic[stix->c->mth.type], (stix_oop_t)name, (stix_oop_t)mth)) goto oops;
#endif
return 0;
@ -4397,7 +4399,7 @@ oops:
static int compile_method_definition (stix_t* stix)
{
/* clear data required to compile a method */
stix->c->mth.type = MTH_INSTANCE;
stix->c->mth.type = STIX_METHOD_INSTANCE;
stix->c->mth.text.len = 0;
stix->c->mth.assignees.len = 0;
stix->c->mth.binsels.len = 0;
@ -4423,7 +4425,7 @@ static int compile_method_definition (stix_t* stix)
if (is_token_symbol(stix, VOCA_CLASS))
{
/* #method(#class) */
stix->c->mth.type = MTH_CLASS;
stix->c->mth.type = STIX_METHOD_CLASS;
GET_TOKEN (stix);
}
@ -4544,12 +4546,20 @@ static int make_defined_class (stix_t* stix)
/* TOOD: good dictionary size */
tmp = (stix_oop_t)stix_makedic (stix, stix->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE);
if (!tmp) return -1;
stix->c->cls.mthdic_oop[MTH_INSTANCE] = (stix_oop_set_t)tmp;
#ifdef MTHDIC
stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = (stix_oop_set_t)tmp;
#else
stix->c->cls.self_oop->mthdic[STIX_METHOD_INSTANCE] = (stix_oop_set_t)tmp;
#endif
/* TOOD: good dictionary size */
tmp = (stix_oop_t)stix_makedic (stix, stix->_method_dictionary, CLASS_METHOD_DICTIONARY_SIZE);
if (!tmp) return -1;
stix->c->cls.mthdic_oop[MTH_CLASS] = (stix_oop_set_t)tmp;
#ifdef MTHDIC
stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = (stix_oop_set_t)tmp;
#else
stix->c->cls.self_oop->mthdic[STIX_METHOD_CLASS] = (stix_oop_set_t)tmp;
#endif
/* TODO: initialize more fields??? whatelse. */
@ -4814,7 +4824,9 @@ static int __compile_class_definition (stix_t* stix, int extend)
return -1;
}
if (TOKEN_NAME_LEN(stix) < 1 || TOKEN_NAME_LEN(stix) > STIX_MOD_NAME_LEN_MAX)
if (TOKEN_NAME_LEN(stix) < 1 ||
TOKEN_NAME_LEN(stix) > STIX_MOD_NAME_LEN_MAX ||
stix_findoochar(TOKEN_NAME_PTR(stix), TOKEN_NAME_LEN(stix), '_'))
{
set_syntax_error (stix, STIX_SYNERR_MODNAME, TOKEN_LOC(stix), TOKEN_NAME(stix));
return -1;
@ -4860,16 +4872,18 @@ static int __compile_class_definition (stix_t* stix, int extend)
return -1;
}
#ifdef MTHDIC
/* use the method dictionary of an existing class object */
stix->c->cls.mthdic_oop[MTH_INSTANCE] = stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_INSTANCE];
stix->c->cls.mthdic_oop[MTH_CLASS] = stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_CLASS];
stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = stix->c->cls.self_oop->mthdic[STIX_METHOD_INSTANCE];
stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = stix->c->cls.self_oop->mthdic[STIX_METHOD_CLASS];
#endif
/* load the pooldic definition from the existing class object */
pds = stix->c->cls.self_oop->pooldics;
if ((stix_oop_t)pds != stix->_nil)
{
stix_ooch_t* ptr, * end;
STIX_ASSERT (STIX_CLASSOF(stix, pds) == stix->_string);
@ -4947,12 +4961,15 @@ static int __compile_class_definition (stix_t* stix, int extend)
return -1;
}
#ifdef MTHDIC
if (!extend)
{
/* link the method dictionaries created to the actual class object */
/* TODO: anything else to set? */
stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_INSTANCE] = stix->c->cls.mthdic_oop[MTH_INSTANCE];
stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_CLASS] = stix->c->cls.mthdic_oop[MTH_CLASS];
stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_INSTANCE] = stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE];
stix->c->cls.self_oop->mthdic[STIX_CLASS_MTHDIC_CLASS] = stix->c->cls.mthdic_oop[STIX_METHOD_CLASS];
}
#endif
GET_TOKEN (stix);
return 0;
@ -4984,8 +5001,10 @@ static int compile_class_definition (stix_t* stix, int extend)
stix->c->cls.self_oop = STIX_NULL;
stix->c->cls.super_oop = STIX_NULL;
stix->c->cls.mthdic_oop[MTH_INSTANCE] = STIX_NULL;
stix->c->cls.mthdic_oop[MTH_CLASS] = STIX_NULL;
#ifdef MTHDIC
stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = STIX_NULL;
stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = STIX_NULL;
#endif
stix->c->cls.ns_oop = STIX_NULL;
stix->c->cls.superns_oop = STIX_NULL;
stix->c->mth.literal_count = 0;
@ -4998,8 +5017,10 @@ static int compile_class_definition (stix_t* stix, int extend)
/* reset these oops plus literal pointers not to confuse gc_compiler() */
stix->c->cls.self_oop = STIX_NULL;
stix->c->cls.super_oop = STIX_NULL;
stix->c->cls.mthdic_oop[MTH_INSTANCE] = STIX_NULL;
stix->c->cls.mthdic_oop[MTH_CLASS] = STIX_NULL;
#ifdef MTHDIC
stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = STIX_NULL;
stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = STIX_NULL;
#endif
stix->c->cls.ns_oop = STIX_NULL;
stix->c->cls.superns_oop = STIX_NULL;
stix->c->mth.literal_count = 0;
@ -5152,19 +5173,21 @@ static int __compile_pooldic_definition (stix_t* stix)
/*TODO: tally and arlit_count range check */
/*if (!STIX_IN_SMOOI_RANGE(tally)) ERROR??*/
stix->c->cls.mthdic_oop[0] = stix_makedic (stix, stix->_pool_dictionary, STIX_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN));
if (!stix->c->cls.mthdic_oop[0]) return -1;
/* i use mthdic_oop[0] when compling #pooldic. it's not a real method dictionary.
* i just use it not to declare another field into the compiler */
stix->c->cls.pooldic_oop = stix_makedic (stix, stix->_pool_dictionary, STIX_ALIGN(tally + 10, POOL_DICTIONARY_SIZE_ALIGN));
if (!stix->c->cls.pooldic_oop) return -1;
for (i = 0; i < stix->c->mth.arlit_count; i += 2)
{
/* TODO: handle duplicate keys? */
if (!stix_putatdic(stix, stix->c->cls.mthdic_oop[0], stix->c->mth.arlit[i], stix->c->mth.arlit[i + 1])) return -1;
if (!stix_putatdic(stix, stix->c->cls.pooldic_oop, stix->c->mth.arlit[i], stix->c->mth.arlit[i + 1])) return -1;
}
/* eveything seems ok. register the pool dictionary to the main
* system dictionary or to the name space it belongs to */
lit = stix_makesymbol (stix, stix->c->cls.name.ptr, stix->c->cls.name.len);
if (!lit || !stix_putatdic (stix, stix->c->cls.ns_oop, lit, (stix_oop_t)stix->c->cls.mthdic_oop[0])) return -1;
if (!lit || !stix_putatdic (stix, stix->c->cls.ns_oop, lit, (stix_oop_t)stix->c->cls.pooldic_oop)) return -1;
return 0;
}
@ -5176,7 +5199,7 @@ static int compile_pooldic_definition (stix_t* stix)
* i'll be reusing some fields reserved for compling a class */
stix->c->cls.name.len = 0;
STIX_MEMSET (&stix->c->cls.fqn_loc, 0, STIX_SIZEOF(stix->c->cls.fqn_loc));
stix->c->cls.mthdic_oop[0] = STIX_NULL;
stix->c->cls.pooldic_oop = STIX_NULL;
stix->c->cls.ns_oop = STIX_NULL;
stix->c->mth.balit_count = 0;
stix->c->mth.arlit_count = 0;
@ -5184,7 +5207,7 @@ static int compile_pooldic_definition (stix_t* stix)
n = __compile_pooldic_definition (stix);
/* reset these oops plus literal pointers not to confuse gc_compiler() */
stix->c->cls.mthdic_oop[0] = STIX_NULL;
stix->c->cls.pooldic_oop = STIX_NULL;
stix->c->cls.ns_oop = STIX_NULL;
stix->c->mth.balit_count = 0;
stix->c->mth.arlit_count = 0;
@ -5258,11 +5281,16 @@ static void gc_compiler (stix_t* stix)
if (stix->c->cls.super_oop)
stix->c->cls.super_oop = stix_moveoop (stix, stix->c->cls.super_oop);
if (stix->c->cls.mthdic_oop[MTH_INSTANCE])
stix->c->cls.mthdic_oop[MTH_INSTANCE] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.mthdic_oop[MTH_INSTANCE]);
#ifdef MTHDIC
if (stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE])
stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.mthdic_oop[STIX_METHOD_INSTANCE]);
if (stix->c->cls.mthdic_oop[MTH_CLASS])
stix->c->cls.mthdic_oop[MTH_CLASS] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.mthdic_oop[MTH_CLASS]);
if (stix->c->cls.mthdic_oop[STIX_METHOD_CLASS])
stix->c->cls.mthdic_oop[STIX_METHOD_CLASS] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.mthdic_oop[STIX_METHOD_CLASS]);
#endif
if (stix->c->cls.pooldic_oop)
stix->c->cls.pooldic_oop = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.pooldic_oop);
if (stix->c->cls.ns_oop)
stix->c->cls.ns_oop = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.ns_oop);
@ -5272,7 +5300,7 @@ static void gc_compiler (stix_t* stix)
for (i = 0; i < stix->c->cls.pooldic_count; i++)
{
stix->c->cls.pooldic_oops[i] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.pooldic_oops[i]);
stix->c->cls.pooldic_imp_oops[i] = (stix_oop_set_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.pooldic_imp_oops[i]);
}
for (i = 0; i < stix->c->mth.literal_count; i++)
@ -5306,7 +5334,7 @@ static void fini_compiler (stix_t* stix)
}
if (stix->c->cls.pooldic.ptr) stix_freemem (stix, stix->c->cls.pooldic.ptr);
if (stix->c->cls.pooldic_oops) stix_freemem (stix, stix->c->cls.pooldic_oops);
if (stix->c->cls.pooldic_imp_oops) stix_freemem (stix, stix->c->cls.pooldic_imp_oops);
if (stix->c->mth.text.ptr) stix_freemem (stix, stix->c->mth.text.ptr);
if (stix->c->mth.assignees.ptr) stix_freemem (stix, stix->c->mth.assignees.ptr);

View File

@ -992,13 +992,13 @@ static stix_oop_method_t find_method (stix_t* stix, stix_oop_t receiver, const s
{
/* receiver is a class object (an instance of Class) */
c = receiver;
dic_no = STIX_CLASS_MTHDIC_CLASS;
dic_no = STIX_METHOD_CLASS;
}
else
{
/* receiver is not a class object. so take its class */
c = (stix_oop_t)cls;
dic_no = STIX_CLASS_MTHDIC_INSTANCE;
dic_no = STIX_METHOD_INSTANCE;
}
STIX_ASSERT (c != stix->_nil);
@ -1039,7 +1039,7 @@ not_found:
{
/* the object is an instance of Class. find the method
* in an instance method dictionary of Class also */
mthdic = ((stix_oop_class_t)cls)->mthdic[STIX_CLASS_MTHDIC_INSTANCE];
mthdic = ((stix_oop_class_t)cls)->mthdic[STIX_METHOD_INSTANCE];
STIX_ASSERT ((stix_oop_t)mthdic != stix->_nil);
STIX_ASSERT (STIX_CLASSOF(stix, mthdic) == stix->_method_dictionary);
@ -2893,7 +2893,7 @@ static int start_method (stix_t* stix, stix_oop_method_t method, stix_oow_t narg
STIX_ASSERT (STIX_OBJ_GET_FLAGS_EXTRA(name));
STIX_ASSERT (STIX_CLASSOF(stix,name) == stix->_symbol);
handler = stix_querymodforpfimpl (stix, ((stix_oop_char_t)name)->slot, STIX_OBJ_GET_SIZE(name));
handler = stix_querymod (stix, ((stix_oop_char_t)name)->slot, STIX_OBJ_GET_SIZE(name));
}
if (handler)
@ -2915,15 +2915,19 @@ static int start_method (stix_t* stix, stix_oop_method_t method, stix_oow_t narg
return -1; /* hard primitive failure */
}
if (n >= 1) break; /* primitive ok*/
}
/* soft primitive failure or handler not found.
* if handler is not found, 0 must be printed in the debug message. */
STIX_DEBUG1 (stix, "Soft failure indicated by primitive function %p\n", handler);
/* soft primitive failure */
STIX_DEBUG1 (stix, "Soft failure indicated by primitive function %p\n", handler);
}
else
{
/* no handler found */
STIX_DEBUG0 (stix, "Soft failure for non-existent primitive function\n");
}
#if defined(STIX_USE_OBJECT_TRAILER)
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TRAILER(method));
if (method->slot[STIX_OBJ_GET_SIZE(method)] == 0) /* this trailer size field not a small integer */
if (STIX_METHOD_GET_CODE_SIZE(method) == 0) /* this trailer size field not a small integer */
#else
if (method->code == stix->_nil)
#endif

View File

@ -411,7 +411,7 @@ static void log_write (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, st
struct tm tm, *tmp;
time_t now;
/*if (mask & STIX_LOG_GC) return;*/ /* don't show gc logs */
if (mask & STIX_LOG_GC) return; /* don't show gc logs */
/* TODO: beautify the log message.
* do classification based on mask. */

View File

@ -45,7 +45,7 @@
#define STIX_USE_MAKE_BLOCK
/* this is for gc debugging */
/*#define STIX_DEBUG_GC*/
#define STIX_DEBUG_GC
#define STIX_DEBUG_COMPILER
/*#define STIX_DEBUG_VM_PROCESSOR*/
/*#define STIX_DEBUG_VM_EXEC*/
@ -479,8 +479,10 @@ struct stix_compiler_t
stix_oop_class_t self_oop;
stix_oop_t super_oop; /* this may be nil. so the type is stix_oop_t */
stix_oop_set_t mthdic_oop[2];
#ifdef MTHDIC
stix_oop_set_t mthdic_oop[2]; /* used when compiling a method definition */
#endif
stix_oop_set_t pooldic_oop; /* used when compiling a pooldic definition */
stix_oop_set_t ns_oop;
stix_oocs_t fqn;
stix_oocs_t name;
@ -503,18 +505,20 @@ struct stix_compiler_t
* var_count[2] - number of class instance variables */
stix_oow_t var_count[3];
/* buffer to hold pooldic import declaration */
stix_oocs_t pooldic;
stix_oow_t pooldic_capa;
stix_oow_t pooldic_count;
stix_oop_set_t* pooldic_oops;
stix_oow_t pooldic_oop_capa;
/* used to hold imported pool dictionarie objects */
stix_oop_set_t* pooldic_imp_oops;
stix_oow_t pooldic_imp_oops_capa;
} cls;
/* information about a function being comipled */
/* information about a method being comipled */
struct
{
int type;
stix_method_type_t type;
/* method source text */
stix_oocs_t text;
@ -590,16 +594,8 @@ struct stix_oochbuf_t
stix_oow_t capa;
};
struct stix_decoder_t
{
stix_oochbuf_t fltout;
stix_bchbuf_t fltfmt;
};
#endif
#if defined(STIX_USE_OBJECT_TRAILER)
/* let it point to the trailer of the method */
# define SET_ACTIVE_METHOD_CODE(stix) ((stix)->active_code = (stix_oob_t*)&(stix)->active_method->slot[STIX_OBJ_GET_SIZE((stix)->active_method) + 1 - STIX_METHOD_NAMED_INSTVARS])
@ -1268,10 +1264,10 @@ int stix_importmod (
);
/*
* The stix_querymodforpfimpl() function finds a primitive function in modules
* The stix_querymod() function finds a primitive function in modules
* with a full primitive identifier.
*/
stix_pfimpl_t stix_querymodforpfimpl (
stix_pfimpl_t stix_querymod (
stix_t* stix,
const stix_ooch_t* pfid,
stix_oow_t pfidlen

View File

@ -505,7 +505,7 @@ stix_mod_data_t* stix_openmod (stix_t* stix, const stix_ooch_t* name, stix_oow_t
/* attempt to find an external module */
STIX_MEMSET (&md, 0, STIX_SIZEOF(md));
stix_copyoochars (md.name, name, namelen);
stix_copyoochars ((stix_ooch_t*)md.mod.name, name, namelen);
if (stix->vmprim.dl_open && stix->vmprim.dl_getsym && stix->vmprim.dl_close)
{
md.handle = stix->vmprim.dl_open (stix, &buf[MOD_PREFIX_LEN]);
@ -551,7 +551,7 @@ stix_mod_data_t* stix_openmod (stix_t* stix, const stix_ooch_t* name, stix_oow_t
mdp->pair = pair;
STIX_DEBUG2 (stix, "Opened a module [%S] - %p\n", mdp->name, mdp->handle);
STIX_DEBUG2 (stix, "Opened a module [%S] - %p\n", mdp->mod.name, mdp->handle);
/* the module loader must ensure to set a proper query handler */
STIX_ASSERT (mdp->mod.query != STIX_NULL);
@ -566,14 +566,14 @@ void stix_closemod (stix_t* stix, stix_mod_data_t* mdp)
if (mdp->handle)
{
stix->vmprim.dl_close (stix, mdp->handle);
STIX_DEBUG2 (stix, "Closed a module [%S] - %p\n", mdp->name, mdp->handle);
STIX_DEBUG2 (stix, "Closed a module [%S] - %p\n", mdp->mod.name, mdp->handle);
mdp->handle = STIX_NULL;
}
if (mdp->pair)
{
/*mdp->pair = STIX_NULL;*/ /* this reset isn't needed as the area will get freed by stix_rbt_delete()) */
stix_rbt_delete (&stix->modtab, mdp->name, stix_countoocstr(mdp->name));
stix_rbt_delete (&stix->modtab, mdp->mod.name, stix_countoocstr(mdp->mod.name));
}
}
@ -583,6 +583,11 @@ int stix_importmod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, st
stix_mod_data_t* mdp;
int r = 0;
/* stix_openmod(), stix_closemod(), etc calls a user-defined callback.
* i need to protect _class in case the user-defined callback allocates
* a OOP memory chunk and GC occurs */
stix_pushtmp (stix, &_class);
pair = stix_rbt_search (&stix->modtab, name, len);
if (pair)
{
@ -601,7 +606,7 @@ int stix_importmod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, st
if (!mdp->mod.import)
{
STIX_DEBUG1 (stix, "Cannot import module [%S] - importing not supported by the module\n", mdp->name);
STIX_DEBUG1 (stix, "Cannot import module [%S] - importing not supported by the module\n", mdp->mod.name);
stix->errnum = STIX_ENOIMPL;
r = -1;
goto done;
@ -609,7 +614,7 @@ int stix_importmod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, st
if (mdp->mod.import (stix, &mdp->mod, _class) <= -1)
{
STIX_DEBUG1 (stix, "Cannot import module [%S] - module's import() returned failure\n", mdp->name);
STIX_DEBUG1 (stix, "Cannot import module [%S] - module's import() returned failure\n", mdp->mod.name);
r = -1;
goto done;
}
@ -621,10 +626,11 @@ done:
stix_closemod (stix, mdp);
}
stix_poptmp (stix);
return r;
}
stix_pfimpl_t stix_querymodforpfimpl (stix_t* stix, const stix_ooch_t* pfid, stix_oow_t pfidlen)
stix_pfimpl_t stix_querymod (stix_t* stix, const stix_ooch_t* pfid, stix_oow_t pfidlen)
{
/* primitive function identifier
* _funcname
@ -666,41 +672,66 @@ stix_pfimpl_t stix_querymodforpfimpl (stix_t* stix, const stix_ooch_t* pfid, sti
if ((handler = mdp->mod.query (stix, &mdp->mod, sep + 1)) == STIX_NULL)
{
/* the primitive function is not found. keep the module open */
STIX_DEBUG2 (stix, "Cannot find a primitive function [%S] in a module [%S]\n", sep + 1, mdp->name);
STIX_DEBUG2 (stix, "Cannot find a primitive function [%S] in a module [%S]\n", sep + 1, mdp->mod.name);
stix->errnum = STIX_ENOENT; /* TODO: proper error code and handling */
return STIX_NULL;
}
STIX_DEBUG3 (stix, "Found a primitive function [%S] in a module [%S] - %p\n", sep + 1, mdp->name, handler);
STIX_DEBUG3 (stix, "Found a primitive function [%S] in a module [%S] - %p\n", sep + 1, mdp->mod.name, handler);
return handler;
}
/* -------------------------------------------------------------------------- */
/* add a new primitive method */
int stix_addmethod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, stix_pfimpl_t func)
int stix_genpfmethod (stix_t* stix, stix_mod_t* mod, stix_oop_t _class, stix_method_type_t type, const stix_ooch_t* mthname, const stix_ooch_t* pfname)
{
/* NOTE: this function is a subset of add_compiled_method() in comp.c */
stix_oop_char_t nsym;
stix_oop_char_t mnsym, pfidsym;
stix_oop_method_t mth;
stix_oop_class_t cls;
stix_oow_t tmp_count = 0, i;
stix_ooi_t arg_count = 0;
stix_oocs_t cs;
STIX_ASSERT (STIX_CLASSOF(stix, _class) == stix->_class);
cls = (stix_oop_class_t)_class;
stix_pushtmp (stix, (stix_oop_t*)&cls); tmp_count++;
STIX_ASSERT (STIX_CLASSOF(stix, (stix_oop_t)cls->mthdic[type]) == stix->_method_dictionary);
/* TODO: check if name is a valid method name */
for (i = 0; name[i]; i++)
for (i = 0; mthname[i]; i++)
{
if (name[i] == ':') arg_count++;
if (mthname[i] == ':') arg_count++;
}
/* TODO: check if name is a valid method name - more checks... */
/* TOOD: if the method name is a binary selector, it can still have an argument.. so the check below is invalid... */
if (arg_count > 0 && mthname[i - 1] != ':')
{
STIX_DEBUG2 (stix, "Cannot generate primitive function method [%S] in [%O] - invalid name\n", mthname, cls->name);
stix->errnum = STIX_EINVAL;
goto oops;
}
nsym = (stix_oop_char_t)stix_makesymbol (stix, name, i);
if (!nsym) return -1;
stix_pushtmp (stix, (stix_oop_t*)&name); tmp_count++;
cs.ptr = (stix_ooch_t*)mthname;
cs.len = i;
if (stix_lookupdic (stix, cls->mthdic[type], &cs) != STIX_NULL)
{
STIX_DEBUG2 (stix, "Cannot generate primitive function method [%S] in [%O] - duplicate\n", mthname, cls->name);
stix->errnum = STIX_EEXIST;
goto oops;
}
mnsym = (stix_oop_char_t)stix_makesymbol (stix, mthname, i);
if (!mnsym) goto oops;
stix_pushtmp (stix, (stix_oop_t*)&mnsym); tmp_count++;
/* TODO:... */
/* pfid => mod->name + '_' + pfname */
pfidsym = (stix_oop_char_t)stix_makesymbol (stix, pfname, stix_countoocstr(pfname));
if (!pfidsym) goto oops;
stix_pushtmp (stix, (stix_oop_t*)&pfidsym); tmp_count++;
#if defined(STIX_USE_OBJECT_TRAILER)
mth = (stix_oop_method_t)stix_instantiatewithtrailer (stix, stix->_method, 1, STIX_NULL, 0);
@ -709,23 +740,23 @@ int stix_addmethod (stix_t* stix, stix_oop_t _class, const stix_ooch_t* name, st
#endif
if (!mth) goto oops;
/* store the symbol name to the literal frame */
mth->slot[0] = (stix_oop_t)nsym;
/* store the primitive function name symbol to the literal frame */
mth->slot[0] = (stix_oop_t)pfidsym;
/* add the primitive as a name primitive with index of -1.
* set the preamble_data to the pointer to the primitive function. */
/* premable should contain the index to the literal frame - 0 */
mth->owner = cls;
mth->name = nsym;
mth->preamble = STIX_SMOOI_TO_OOP(STIX_METHOD_MAKE_PREAMBLE(STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE, -1));
mth->preamble_data[0] = STIX_SMOOI_TO_OOP((stix_oow_t)func >> (STIX_OOW_BITS / 2));
mth->preamble_data[1] = STIX_SMOOI_TO_OOP((stix_oow_t)func & STIX_LBMASK(stix_oow_t, STIX_OOW_BITS / 2));
mth->name = mnsym;
mth->preamble = STIX_SMOOI_TO_OOP(STIX_METHOD_MAKE_PREAMBLE(STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE, 0));
mth->preamble_data[0] = STIX_SMOOI_TO_OOP(0);
mth->preamble_data[1] = STIX_SMOOI_TO_OOP(0);
mth->tmpr_count = STIX_SMOOI_TO_OOP(arg_count);
mth->tmpr_nargs = STIX_SMOOI_TO_OOP(arg_count);
stix_poptmps (stix, tmp_count); tmp_count = 0;
/* TODO: class method? */
/* instance method */
if (!stix_putatdic (stix, cls->mthdic[STIX_CLASS_MTHDIC_INSTANCE], (stix_oop_t)nsym, (stix_oop_t)mth)) goto oops;
/* TODO: emit BCODE_RETURN_NIL ? */
if (!stix_putatdic (stix, cls->mthdic[type], (stix_oop_t)mnsym, (stix_oop_t)mth)) goto oops;
return 0;
oops:

View File

@ -52,6 +52,7 @@ enum stix_errnum_t
STIX_ESYSMEM, /**< insufficient system memory */
STIX_EOOMEM, /**< insufficient object memory */
STIX_EINVAL, /**< invalid parameter or data */
STIX_EEXIST, /**< existing/duplicate data */
STIX_ETOOBIG, /**< data too large */
STIX_EMSGSND, /**< message sending error. even doesNotUnderstand: is not found */
STIX_ERANGE, /**< range error. overflow and underflow */
@ -159,6 +160,17 @@ typedef struct stix_obj_word_t* stix_oop_word_t;
#endif
enum stix_method_type_t
{
STIX_METHOD_INSTANCE,
STIX_METHOD_CLASS,
/* --------------------------- */
STIX_METHOD_TYPE_COUNT
};
typedef enum stix_method_type_t stix_method_type_t;
/*
* OOP encoding
* An object pointer(OOP) is an ordinary pointer value to an object.
@ -424,13 +436,11 @@ struct stix_class_t
/* [0] - instance methods, MethodDictionary
* [1] - class methods, MethodDictionary */
stix_oop_set_t mthdic[2];
stix_oop_set_t mthdic[STIX_METHOD_TYPE_COUNT];
/* indexed part afterwards */
stix_oop_t slot[1]; /* class instance variables and class variables. */
};
#define STIX_CLASS_MTHDIC_INSTANCE 0
#define STIX_CLASS_MTHDIC_CLASS 1
#define STIX_ASSOCIATION_NAMED_INSTVARS 2
typedef struct stix_association_t stix_association_t;
@ -757,6 +767,7 @@ typedef void (*stix_mod_unload_t) (
struct stix_mod_t
{
const stix_ooch_t name[STIX_MOD_NAME_LEN_MAX + 1];
stix_mod_import_t import;
stix_mod_query_t query;
stix_mod_unload_t unload;
@ -765,7 +776,6 @@ struct stix_mod_t
struct stix_mod_data_t
{
stix_ooch_t name[STIX_MOD_NAME_LEN_MAX + 1];
void* handle;
stix_rbt_pair_t* pair; /* internal backreference to stix->modtab */
stix_mod_t mod;
@ -1081,10 +1091,6 @@ STIX_EXPORT void stix_gc (
stix_t* stix
);
STIX_EXPORT stix_oow_t stix_getpayloadbytes (
stix_t* stix,
stix_oop_t oop
);
/**
* The stix_instantiate() function creates a new object of the class
@ -1176,6 +1182,22 @@ STIX_EXPORT void stix_freemem (
);
/* =========================================================================
* PRIMITIVE METHOD MANIPULATION
* ========================================================================= */
STIX_EXPORT int stix_genpfmethod (
stix_t* stix,
stix_mod_t* mod,
stix_oop_t _class,
stix_method_type_t type,
const stix_ooch_t* mthname,
const stix_ooch_t* name
);
/* =========================================================================
* STRING ENCODING CONVERSION
* ========================================================================= */
#if defined(STIX_OOCH_IS_UCH)
# define stix_oocstobcs(stix,oocs,oocslen,bcs,bcslen) stix_ucstobcs(stix,oocs,oocslen,bcs,bcslen)
# define stix_bcstooocs(stix,bcs,bcslen,oocs,oocslen) stix_bcstoucs(stix,bcs,bcslen,oocs,oocslen)
@ -1201,6 +1223,11 @@ STIX_EXPORT int stix_ucstobcs (
stix_oow_t* bcslen
);
/* =========================================================================
* STIX VM LOGGING
* ========================================================================= */
STIX_EXPORT stix_ooi_t stix_logbfmt (
stix_t* stix,
stix_oow_t mask,

View File

@ -302,37 +302,5 @@ int stix_mod_console (stix_t* stix, stix_mod_t* mod)
mod->query = query;
mod->unload = unload;
mod->ctx = STIX_NULL;
#if 0
#include 'Stix.st'.
#import 'Console'.
c = stix_findclass (stix, "Console");
if (!c) c = stix_makeclass (stix, "Console", "x y"); <- provides an API to create a simple class
stix_addmethod (stix, c, "open", pf_open);
stix_addmethod (stix, c, "close:", pf_close);
stix_addmethod (stix, c, "setCursorTo:", pf_setcursor);
stix_addmethod (stix, c, "clear", pf_clear );
stix_addmethod (stix, c, "write", pf_write );
/* GRAMMER ENHANCEMENT */
fun abc (a, b, c) <----- this style, register C style method
{
}
fun abc: a with: b c: c <----- smalltalk style
{
}
abc->def (a, b, c) <------- use -> as an c style method indicator
abc abc: a with: b c: c
#endif
return 0;
}

View File

@ -128,10 +128,18 @@ static fnctab_t fnctab[] =
{ "puts", pf_puts }
};
static stix_ooch_t voca_open_for[] = { 'o','p','e','n',':','f','o','r',':','\0' };
static stix_ooch_t voca_open[] = { 'o','p','e','n','\0' };
static stix_ooch_t voca_close[] = { 'c','l','o','s','e','\0' };
/* ------------------------------------------------------------------------ */
static int import (stix_t* stix, stix_mod_t* mod, stix_oop_t _class)
{
stix_pushtmp (stix, &_class);
stix_genpfmethod (stix, mod, _class, STIX_METHOD_INSTANCE, voca_open_for, voca_open);
stix_genpfmethod (stix, mod, _class, STIX_METHOD_CLASS, voca_close, voca_close);
stix_poptmp (stix);
return 0;
}
@ -186,18 +194,6 @@ int stix_mod_stdio (stix_t* stix, stix_mod_t* mod)
#include 'Stix.st'.
#import 'Console'.
c = stix_findclass (stix, "Console");
if (!c) c = stix_makeclass (stix, "Console", "x y"); <- provides an API to create a simple class
stix_addmethod (stix, c, "open", pf_open);
stix_addmethod (stix, c, "close:", pf_close);
stix_addmethod (stix, c, "setCursorTo:", pf_setcursor);
stix_addmethod (stix, c, "clear", pf_clear );
stix_addmethod (stix, c, "write", pf_write );
/* GRAMMER ENHANCEMENT */
fun abc (a, b, c) <----- this style, register C style method
{