diff --git a/stix/lib/comp.c b/stix/lib/comp.c index 98e067b..3023a7a 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -28,6 +28,12 @@ #define TOKEN_NAME_ALIGN 256 #define CLASS_BUFFER_ALIGN 8 /* 256 */ +#define LITERAL_BUFFER_ALIGN 8 /* 256 */ + + +/* initial method dictionary size */ +#define INSTANCE_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */ +#define CLASS_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */ #if 0 @@ -56,9 +62,10 @@ enum class_mod_t CLASS_EXTENDED = (1 << 1) }; -enum mth_mod_t +enum mth_type_t { - MTH_CLASS = (1 << 0) + MTH_INSTANCE, + MTH_CLASS }; enum var_type_t @@ -264,7 +271,7 @@ static void set_syntax_error (stix_t* stix, stix_synerrnum_t num, const stix_iol } } -static int copy_string_to (stix_t* stix, const stix_ucs_t* src, stix_ucs_t* dst, stix_size_t* dst_capa, int append, stix_uch_t append_delim) +static int copy_string_to (stix_t* stix, const stix_ucs_t* src, stix_ucs_t* dst, stix_size_t* dst_capa, int append, stix_uch_t add_delim) { stix_size_t len, pos; @@ -272,7 +279,7 @@ static int copy_string_to (stix_t* stix, const stix_ucs_t* src, stix_ucs_t* dst, { pos = dst->len; len = dst->len + src->len; - if (append_delim != '\0') len++; + if (add_delim != '\0') len++; } else { @@ -294,7 +301,7 @@ static int copy_string_to (stix_t* stix, const stix_ucs_t* src, stix_ucs_t* dst, *dst_capa = capa; } - if (append && append_delim) dst->ptr[pos++] = append_delim; + if (append && add_delim) dst->ptr[pos++] = add_delim; stix_copychars (&dst->ptr[pos], src->ptr, src->len); dst->len = len; return 0; @@ -1244,123 +1251,84 @@ static int emit_do_primitive (stix_t* stix, int no) return emit_code (stix, code, len); } -#if 0 -static int __add_literal (stix_t* fsc, stix_word_t literal) -{ - stix_word_t i; - - for (i = 0; i < fsc->literal_count; i++) { - /* - * it would remove redundancy of symbols and small integers. - * more complex redundacy check may be done somewhere else - * like in __add_string_literal. - */ - if (fsc->literals[i] == literal) return i; - } - - if (fsc->literal_count >= STIX_COUNTOF(fsc->literals)) { - fsc->errnum = STIX_FSC_ERROR_TOO_MANY_LITERALS; - return -1; - } - - fsc->literals[fsc->literal_count++] = literal; - return fsc->literal_count - 1; -} - -static int __add_character_literal (stix_t* fsc, stix_uch_t ch) -{ - stix_word_t i, c, literal; - stix_vm_t* stx = fsc->stx; - - for (i = 0; i < fsc->literal_count; i++) { - c = STIX_ISSMALLINT(fsc->literals[i])? - stx->class_smallinteger: STIX_CLASS (stx, fsc->literals[i]); - if (c != stx->class_character) continue; - - if (ch == STIX_CHAR_AT(stx,fsc->literals[i],0)) return i; - } - - literal = stix_instantiate ( - stx, stx->class_character, &ch, STIX_NULL, 0); - return __add_literal (fsc, literal); -} - -static int __add_string_literal ( - stix_t* fsc, const stix_uch_t* str, stix_word_t size) -{ - stix_word_t i, c, literal; - stix_vm_t* stx = fsc->stx; - - for (i = 0; i < fsc->literal_count; i++) { - c = STIX_ISSMALLINT(fsc->literals[i])? - stx->class_smallinteger: STIX_CLASS (stx, fsc->literals[i]); - if (c != stx->class_string) continue; - - if (stix_strxncmp (str, size, - STIX_DATA(stx,fsc->literals[i]), - STIX_SIZE(stx,fsc->literals[i])) == 0) return i; - } - - literal = stix_instantiate ( - stx, stx->class_string, STIX_NULL, str, size); - return __add_literal (fsc, literal); -} - -static int __add_symbol_literal ( - stix_t* fsc, const stix_uch_t* str, stix_word_t size) -{ - stix_vm_t* stx = fsc->stx; - return __add_literal (fsc, stix_new_symbolx(stx, str, size)); -} - -static int finish_method (stix_t* fsc) -{ - stix_vm_t* stx = fsc->stx; - stix_oop_class_t class_obj; - stix_method_t* method_obj; - stix_word_t method, selector; - - STIX_ASSERT (fsc->bcd.size != 0); - - class_obj = (stix_class_t*) STIX_OBJPTR(stx, fsc->method_class); - - if (class_obj->methods == stx->nil) - { - /* TODO: reconfigure method dictionary size */ - class_obj->methods = stix_instantiate ( - stx, stx->class_system_dictionary, - STIX_NULL, STIX_NULL, 64); - } - STIX_ASSERT (class_obj->methods != stx->nil); - - selector = stix_new_symbolx ( - stx, fsc->met.name.buf, fsc->method_name.size); - - method = stix_instantiate(stx, stx->class_method, - STIX_NULL, fsc->literals, fsc->literal_count); - method_obj = (stix_method_t*)STIX_OBJPTR(stx, method); - - /* TODO: text saving must be optional */ - /*method_obj->text = stix_instantiate ( - stx, stx->class_string, STIX_NULL, - fsc->text, stix_strlen(fsc->text)); - */ - method_obj->selector = selector; - method_obj->bytecodes = stix_instantiate ( - stx, stx->class_bytearray, STIX_NULL, - fsc->bcd.buf, fsc->bcd.size); - - /* TODO: better way to store argument count & temporary count */ - method_obj->tmpcount = STIX_TO_SMALLINT(fsc->met.tmpr.count - fsc->met.tmpr.nargs); - method_obj->argcount = STIX_TO_SMALLINT(fsc->met.tmpr.nargs); - - stix_dict_put (stx, class_obj->methods, selector, method); - return 0; -} #endif +static int add_literal (stix_t* stix, stix_oop_t lit, stix_size_t* index) +{ + stix_size_t i; + for (i = 0; i < stix->c->mth.literal_count; i++) + { + /* + * this removes redundancy of symbols, characters, and small integers. + * more complex redundacy check may be done somewhere else like + * in add_string_literal(). + */ + if (stix->c->mth.literals[i] == lit) + { + *index = i; + return i; + } + } + if (stix->c->mth.literal_count >= stix->c->mth.literal_capa) + { + stix_oop_t* tmp; + stix_size_t new_capa; + + new_capa = STIX_ALIGN (stix->c->mth.literal_count + 1, LITERAL_BUFFER_ALIGN); + tmp = (stix_oop_t*)stix_reallocmem (stix, stix->c->mth.literals, new_capa * STIX_SIZEOF(*tmp)); + if (!tmp) return -1; + + stix->c->mth.literal_capa = new_capa; + stix->c->mth.literals = tmp; + } + + *index = stix->c->mth.literal_count; + stix->c->mth.literals[stix->c->mth.literal_count++] = lit; + return 0; +} + +static STIX_INLINE int add_character_literal (stix_t* stix, stix_uch_t ch, stix_size_t* index) +{ + return add_literal (stix, STIX_OOP_FROM_CHAR(ch), index); +} + +static int add_string_literal (stix_t* stix, const stix_ucs_t* str, stix_size_t* index) +{ + stix_oop_t lit; + stix_size_t i; + + for (i = 0; i < stix->c->mth.literal_count; i++) + { + lit = stix->c->mth.literals[i]; + + if (STIX_CLASSOF(stix, lit) == stix->_string && + STIX_OBJ_GET_SIZE(lit) == str->len && + stix_equalchars(((stix_oop_char_t)lit)->slot, str->ptr, str->len)) + { + *index = i; + return 0; + } + } + + lit = stix_instantiate (stix, stix->_string, str->ptr, str->len); + if (!lit) return -1; + + return add_literal (stix, lit, index); +} + +static int add_symbol_literal (stix_t* stix, const stix_ucs_t* str, stix_size_t* index) +{ + stix_oop_t tmp; + + tmp = stix_makesymbol (stix, str->ptr, str->len); + if (!tmp) return -1; + + return add_literal (stix, tmp, index); +} + +/* TODO: add_array_literal, add_byte_array_literal () */ #if 0 static int parse_block_statements (stix_t* fsc) @@ -1481,8 +1449,11 @@ static int parse_primary (stix_t* fsc, const stix_uch_t* ident, int* is_super) stix_word_t tmp; STIX_STRTOI (tmp, fsc->tok.name.buffer, STIX_NULL, 10); literal = STIX_TO_SMALLINT(tmp); + + pos = __add_literal(fsc, literal); - if (pos == -1) return -1; + if (pos <= -1) return -1; + EMIT_PUSH_LITERAL_CONSTANT (fsc, pos); GET_TOKEN (fsc); } @@ -1812,9 +1783,6 @@ static int parse_unary_message (stix_t* fsc, int is_super) #endif -#endif - - static STIX_INLINE int set_class_name (stix_t* stix, const stix_ucs_t* name) { return copy_string_to (stix, name, &stix->c->cls.name, &stix->c->cls.name_capa, 0, '\0'); @@ -1825,7 +1793,7 @@ static STIX_INLINE int set_superclass_name (stix_t* stix, const stix_ucs_t* name return copy_string_to (stix, name, &stix->c->cls.supername, &stix->c->cls.supername_capa, 0, '\0'); } -static STIX_INLINE int append_class_level_variable (stix_t* stix, var_type_t index, const stix_ucs_t* name) +static STIX_INLINE int add_class_level_variable (stix_t* stix, var_type_t index, const stix_ucs_t* name) { int n; @@ -1964,26 +1932,26 @@ done: return pos; } -static int append_method_name (stix_t* stix, const stix_ucs_t* name) +static int add_method_name (stix_t* stix, const stix_ucs_t* name) { /* method name segments are concatenated without any delimiters */ return copy_string_to (stix, name, &stix->c->mth.name, &stix->c->mth.name_capa, 1, '\0'); } -static stix_ssize_t find_method_name (stix_t* stix, stix_oop_class_t self, const stix_ucs_t* name) +static int method_exists (stix_t* stix, const stix_ucs_t* name) { - /* TODO: .................... */ - return 0; + /* check if the current class contains a method of the given name */ + return stix_lookupdic (stix, stix->c->cls.mthdic_oop[stix->c->mth.type], name) != STIX_NULL; } -static int append_temporary (stix_t* stix, const stix_ucs_t* name) +static int add_temporary_variable (stix_t* stix, const stix_ucs_t* name) { /* temporary variable names are added to the string with leading * space if it's not the first variable */ return copy_string_to (stix, name, &stix->c->mth.tmprs, &stix->c->mth.tmprs_capa, 1, ' '); } -static STIX_INLINE stix_ssize_t find_temporary (stix_t* stix, const stix_ucs_t* name) +static STIX_INLINE stix_ssize_t find_temporary_variable (stix_t* stix, const stix_ucs_t* name) { return find_word_in_string(&stix->c->mth.tmprs, name); } @@ -2032,7 +2000,7 @@ printf ("duplicate variable name type %d pos %lu\n", var.type, var.pos); return -1; } - if (append_class_level_variable(stix, dcl_type, &stix->c->tok.name) <= -1) return -1; + if (add_class_level_variable(stix, dcl_type, &stix->c->tok.name) <= -1) return -1; } else { @@ -2058,7 +2026,7 @@ static int compile_unary_method_name (stix_t* stix) STIX_ASSERT (stix->c->mth.name.len == 0); STIX_ASSERT (stix->c->mth.tmpr_nargs == 0); - if (append_method_name (stix, &stix->c->tok.name) <= -1) return -1; + if (add_method_name (stix, &stix->c->tok.name) <= -1) return -1; GET_TOKEN (stix); return 0; } @@ -2068,7 +2036,7 @@ static int compile_binary_method_name (stix_t* stix) STIX_ASSERT (stix->c->mth.name.len == 0); STIX_ASSERT (stix->c->mth.tmpr_nargs == 0); - if (append_method_name (stix, &stix->c->tok.name) <= -1) return -1; + if (add_method_name (stix, &stix->c->tok.name) <= -1) return -1; GET_TOKEN (stix); /* collect the argument name */ @@ -2083,8 +2051,9 @@ static int compile_binary_method_name (stix_t* stix) /* no duplication check is performed against class-level variable names. * a duplcate name will shade a previsouly defined variable. */ - if (append_temporary(stix, &stix->c->tok.name) <= -1) return -1; + if (add_temporary_variable(stix, &stix->c->tok.name) <= -1) return -1; stix->c->mth.tmpr_nargs++; +/* TODO: check if tmpr_nargs exceededs LIMIT (SMINT MAX). also bytecode max */ GET_TOKEN (stix); return 0; @@ -2097,7 +2066,7 @@ static int compile_keyword_method_name (stix_t* stix) do { - if (append_method_name(stix, &stix->c->tok.name) <= -1) return -1; + if (add_method_name(stix, &stix->c->tok.name) <= -1) return -1; GET_TOKEN (stix); if (stix->c->tok.type != STIX_IOTOK_IDENT) @@ -2107,13 +2076,13 @@ static int compile_keyword_method_name (stix_t* stix) return -1; } - if (find_temporary(stix, &stix->c->tok.name) >= 0) + if (find_temporary_variable(stix, &stix->c->tok.name) >= 0) { set_syntax_error (stix, STIX_SYNERR_ARGNAMEDUP, &stix->c->tok.loc, &stix->c->tok.name); return -1; } - if (append_temporary(stix, &stix->c->tok.name) <= -1) return -1; + if (add_temporary_variable(stix, &stix->c->tok.name) <= -1) return -1; stix->c->mth.tmpr_nargs++; GET_TOKEN (stix); @@ -2160,7 +2129,7 @@ static int compile_method_name (stix_t* stix) if (n >= 0) { - if (find_method_name(stix, stix->c->cls.self_oop, &stix->c->mth.name) >= 0) + if (method_exists(stix, &stix->c->mth.name)) { set_syntax_error (stix, STIX_SYNERR_MTHNAMEDUP, &stix->c->mth.name_loc, &stix->c->mth.name); return -1; @@ -2191,15 +2160,16 @@ static int compile_method_temporaries (stix_t* stix) GET_TOKEN (stix); while (stix->c->tok.type == STIX_IOTOK_IDENT) { - if (find_temporary(stix, &stix->c->tok.name) >= 0) + if (find_temporary_variable(stix, &stix->c->tok.name) >= 0) { set_syntax_error (stix, STIX_SYNERR_TMPRNAMEDUP, &stix->c->tok.loc, &stix->c->tok.name); return -1; } - if (append_temporary(stix, &stix->c->tok.name) <= -1) return -1; + if (add_temporary_variable(stix, &stix->c->tok.name) <= -1) return -1; stix->c->mth.tmpr_count++; +/* TODO: check if tmpr_count exceededs LIMIT (SMINT MAX). also bytecode max */ GET_TOKEN (stix); } @@ -2378,15 +2348,50 @@ static int compile_method_statements (stix_t* stix) return 0; } +static int add_compiled_method (stix_t* stix) +{ + stix_oop_t sel; /* selector */ + stix_oop_method_t mth; /* method */ + stix_oop_t code; + stix_size_t tmp_count = 0; + + sel = stix_makesymbol (stix, stix->c->mth.name.ptr, stix->c->mth.name.len); + if (!sel) return -1; + stix_pushtmp (stix, &sel); tmp_count++; + + mth = (stix_oop_method_t)stix_instantiate (stix, stix->_method_dictionary, stix->c->mth.literals, stix->c->mth.literal_count); + if (!mth) goto oops; + stix_pushtmp (stix, (stix_oop_t*)&mth); tmp_count++; + + code = stix_instantiate (stix, stix->_byte_array, stix->c->mth.code.ptr, stix->c->mth.code.len); + if (!code) goto oops; + + mth->owner = stix->c->cls.self_oop; + mth->tmpr_count = STIX_OOP_FROM_SMINT(stix->c->mth.tmpr_count); + mth->tmpr_nargs = STIX_OOP_FROM_SMINT(stix->c->mth.tmpr_nargs); + mth->code = code; + /*TODO: preserve source??? mth->source = TODO */ + + stix_poptmps (stix, tmp_count); tmp_count = 0; + + if (!stix_putatdic (stix, stix->c->cls.mthdic_oop[stix->c->mth.type], sel, (stix_oop_t)mth)) goto oops; + return 0; + +oops: + stix_poptmps (stix, tmp_count); + return -1; +} + static int compile_class_method (stix_t* stix) { /* clear data required to compile a method */ - stix->c->mth.flags = 0; + stix->c->mth.type = MTH_INSTANCE; stix->c->mth.name.len = 0; STIX_MEMSET (&stix->c->mth.name_loc, 0, STIX_SIZEOF(stix->c->mth.name_loc)); stix->c->mth.tmprs.len = 0; stix->c->mth.tmpr_count = 0; stix->c->mth.tmpr_nargs = 0; + stix->c->mth.literal_count = 0; stix->c->mth.code.len = 0; if (stix->c->tok.type == STIX_IOTOK_LPAREN) @@ -2397,7 +2402,7 @@ static int compile_class_method (stix_t* stix) if (is_token_symbol(stix, KSYM_CLASS)) { /* #method(#class) */ - stix->c->mth.flags |= MTH_CLASS; + stix->c->mth.type = MTH_CLASS; GET_TOKEN (stix); } @@ -2424,8 +2429,7 @@ static int compile_class_method (stix_t* stix) if (compile_method_temporaries(stix) <= -1 || compile_method_primitive(stix) <= -1 || - compile_method_statements(stix) <= -1 /*|| - finish_method(stix) <= -1*/) return -1; + compile_method_statements(stix) <= -1) return -1; if (stix->c->tok.type != STIX_IOTOK_RBRACE) { @@ -2435,6 +2439,9 @@ static int compile_class_method (stix_t* stix) } GET_TOKEN (stix); + /* add a compiled method to the method dictionary */ + if (add_compiled_method(stix) <= -1) return -1; + return 0; } @@ -2494,29 +2501,42 @@ printf (" CONFLICTING CLASS DEFINITION %lu %lu %lu %lu\n", stix->c->cls.self_oop->selfspec = STIX_OOP_FROM_SMINT(self_spec); } +/* TODO: check if the current class definition conflicts with the superclass. + * if superclass is byte variable, the current class cannot be word variable or something else. +* TODO: TODO: TODO: + */ STIX_OBJ_SET_FLAGS_KERNEL (stix->c->cls.self_oop, 2); - tmp = stix_makesymbol(stix, stix->c->cls.name.ptr, stix->c->cls.name.len); + tmp = stix_makesymbol (stix, stix->c->cls.name.ptr, stix->c->cls.name.len); if (!tmp) return -1; stix->c->cls.self_oop->name = (stix_oop_char_t)tmp; - tmp = stix_makestring(stix, stix->c->cls.vars[0].ptr, stix->c->cls.vars[0].len); + tmp = stix_makestring (stix, stix->c->cls.vars[0].ptr, stix->c->cls.vars[0].len); if (!tmp) return -1; stix->c->cls.self_oop->instvars = (stix_oop_char_t)tmp; - tmp = stix_makestring(stix, stix->c->cls.vars[1].ptr, stix->c->cls.vars[1].len); + tmp = stix_makestring (stix, stix->c->cls.vars[1].ptr, stix->c->cls.vars[1].len); if (!tmp) return -1; stix->c->cls.self_oop->classvars = (stix_oop_char_t)tmp; - tmp = stix_makestring(stix, stix->c->cls.vars[2].ptr, stix->c->cls.vars[2].len); + tmp = stix_makestring (stix, stix->c->cls.vars[2].ptr, stix->c->cls.vars[2].len); if (!tmp) return -1; stix->c->cls.self_oop->classinstvars = (stix_oop_char_t)tmp; - tmp = stix_instantiate(stix, stix->_method_dictionary, STIX_NULL, 0); +/* TOOD: good dictionary size */ + tmp = stix_makedic (stix, stix->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; - stix->c->cls.mthdic_oop = (stix_oop_set_t)tmp; + stix->c->cls.mthdic_oop[MTH_INSTANCE] = (stix_oop_set_t)tmp; + +/* TOOD: good dictionary size */ + tmp = 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; + /* TODO: initialize more fields??? whatelse. */ +/* TODO: update the subclasses field of the superclass if it's not nil */ + if (just_made) { /* register the class to the system dictionary */ @@ -2756,6 +2776,10 @@ printf ("\n"); set_syntax_error (stix, STIX_SYNERR_DCLBANNED, &stix->c->tok.loc, &stix->c->tok.name); return -1; } + + /* use the method dictionary of an existing class object */ + stix->c->cls.mthdic_oop[0] = stix->c->cls.self_oop->instmths; + stix->c->cls.mthdic_oop[1] = stix->c->cls.self_oop->classmths; } else { @@ -2783,6 +2807,14 @@ printf ("\n"); return -1; } + + if (!(stix->c->cls.flags & CLASS_EXTENDED)) + { +/* TODO: anything else to set? */ + stix->c->cls.self_oop->instmths = stix->c->cls.mthdic_oop[MTH_INSTANCE]; + stix->c->cls.self_oop->classmths = stix->c->cls.mthdic_oop[MTH_CLASS]; + } + GET_TOKEN (stix); return 0; } @@ -2805,15 +2837,19 @@ static int compile_class_definition (stix_t* stix) stix->c->cls.self_oop = STIX_NULL; stix->c->cls.super_oop = STIX_NULL; - stix->c->cls.mthdic_oop = STIX_NULL; + stix->c->cls.mthdic_oop[MTH_INSTANCE] = STIX_NULL; + stix->c->cls.mthdic_oop[MTH_CLASS] = STIX_NULL; + stix->c->mth.literal_count = 0; /* do main compilation work */ n = __compile_class_definition (stix); - /* reset these oops not to confuse gc_compiler() */ + /* 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 = STIX_NULL; + stix->c->cls.mthdic_oop[MTH_INSTANCE] = STIX_NULL; + stix->c->cls.mthdic_oop[MTH_CLASS] = STIX_NULL; + stix->c->mth.literal_count = 0; return n; } @@ -2866,11 +2902,24 @@ static void gc_compiler (stix_t* stix) /* called when garbage collection is performed */ if (stix->c) { + stix_size_t i; + if (stix->c->cls.self_oop) stix->c->cls.self_oop = (stix_oop_class_t)stix_moveoop (stix, (stix_oop_t)stix->c->cls.self_oop); 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]); + + 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]); + + for (i = 0; i < stix->c->mth.literal_count; i++) + { + stix->c->mth.literals[i] = stix_moveoop (stix, stix->c->mth.literals[i]); + } } } @@ -2896,6 +2945,7 @@ static void fini_compiler (stix_t* stix) if (stix->c->mth.tmprs.ptr) stix_freemem (stix, stix->c->mth.tmprs.ptr); if (stix->c->mth.name.ptr) stix_freemem (stix, stix->c->mth.name.ptr); if (stix->c->mth.code.ptr) stix_freemem (stix, stix->c->mth.code.ptr); + if (stix->c->mth.literals) stix_freemem (stix, stix->c->mth.literals); stix_freemem (stix, stix->c); stix->c = STIX_NULL; diff --git a/stix/lib/dic.c b/stix/lib/dic.c index ad41268..10b0cfa 100644 --- a/stix/lib/dic.c +++ b/stix/lib/dic.c @@ -214,21 +214,25 @@ stix_oop_t stix_lookupdic (stix_t* stix, stix_oop_set_t dic, const stix_ucs_t* n return lookup (stix, dic, name); } -stix_oop_set_t stix_makedic (stix_t* stix, stix_oop_t cls, stix_oow_t size) +stix_oop_t stix_makedic (stix_t* stix, stix_oop_t cls, stix_oow_t size) { stix_oop_set_t dic; stix_oop_t tmp; + STIX_ASSERT (STIX_CLASSOF(stix,cls) == stix->_class); + STIX_ASSERT (cls != stix->_system_dictionary); + dic = (stix_oop_set_t)stix_instantiate (stix, cls, STIX_NULL, 0); if (!dic) return STIX_NULL; - dic->tally = STIX_OOP_FROM_SMINT(0); + STIX_ASSERT (STIX_OBJ_GET_SIZE(dic) == STIX_SET_NAMED_INSTVARS); stix_pushtmp (stix, (stix_oop_t*)&dic); tmp = stix_instantiate (stix, stix->_array, STIX_NULL, size); stix_poptmp (stix); if (!tmp) return STIX_NULL; + dic->tally = STIX_OOP_FROM_SMINT(0); dic->bucket = (stix_oop_oop_t)tmp; - return dic; + return (stix_oop_t)dic; } diff --git a/stix/lib/gc.c b/stix/lib/gc.c index 22fbf3e..e0ebc4c 100644 --- a/stix/lib/gc.c +++ b/stix/lib/gc.c @@ -199,24 +199,24 @@ printf ("STARTING GC curheap base %p ptr %p newheap base %p ptr %p\n", stix->_true = stix_moveoop (stix, stix->_true); stix->_false = stix_moveoop (stix, stix->_false); -/*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->_stix = stix_moveoop (stix, stix->_stix); stix->_class = stix_moveoop (stix, stix->_class); stix->_nil_object = stix_moveoop (stix, stix->_nil_object); stix->_object = stix_moveoop (stix, stix->_object); stix->_array = stix_moveoop (stix, stix->_array); + stix->_byte_array = stix_moveoop (stix, stix->_byte_array); stix->_string = stix_moveoop (stix, stix->_string); stix->_symbol = stix_moveoop (stix, stix->_symbol); stix->_symbol_set = stix_moveoop (stix, stix->_symbol_set); stix->_system_dictionary = stix_moveoop (stix, stix->_system_dictionary); stix->_method_dictionary = stix_moveoop (stix, stix->_method_dictionary); + stix->_method = stix_moveoop (stix, stix->_method); stix->_association = stix_moveoop (stix, stix->_association); stix->_true_class = stix_moveoop (stix, stix->_true_class); stix->_false_class = stix_moveoop (stix, stix->_false_class); stix->_character = stix_moveoop (stix, stix->_character); stix->_small_integer = stix_moveoop (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) stix_moveoop (stix, (stix_oop_t)stix->sysdic); for (i = 0; i < stix->tmp_count; i++) diff --git a/stix/lib/ignite.c b/stix/lib/ignite.c index 4bd7aee..2b0d6c8 100644 --- a/stix/lib/ignite.c +++ b/stix/lib/ignite.c @@ -110,6 +110,7 @@ static int ignite_1 (stix_t* stix) * String * Symbol * Array + * ByteArray * SymbolSet * Character * SmallIntger @@ -118,11 +119,13 @@ static int ignite_1 (stix_t* stix) 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->_byte_array = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 1, STIX_OBJ_TYPE_BYTE)); stix->_string = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 1, STIX_OBJ_TYPE_CHAR)); 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->_method_dictionary = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_SET_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP)); + stix->_method = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_METHOD_NAMED_INSTVARS, 1, STIX_OBJ_TYPE_OOP)); stix->_association = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(STIX_ASSOCIATION_NAMED_INSTVARS, 0, STIX_OBJ_TYPE_OOP)); stix->_true_class = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); stix->_false_class = alloc_kernel_class (stix, 0, STIX_CLASS_SPEC_MAKE(0, 0, STIX_OBJ_TYPE_OOP)); diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index 8e649b1..3513634 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -304,43 +304,6 @@ struct stix_synerr_t typedef struct stix_synerr_t stix_synerr_t; -/* - * The Smalltalk-80 Bytecodes - * Range Bits Function - * ------------------------------------------------------------- - * 0-15 0000iiii Push Receiver Variable #iiii - * 16-31 0001iiii Push Temporary Location #iiii - * 32-63 001iiiii Push Literal Constant #iiiii - * 64-95 010iiiii Push Literal Variable #iiiii - * 96-103 01100iii Pop and Store Receiver Variable #iii - * 104-111 01101iii Pop and Store Temporary Location #iii - * 112-119 01110iii Push (receiver, _true, _false, _nil, -1, 0, 1, 2) [iii] - * 120-123 011110ii Return (receiver, _true, _false, _nil) [ii] From Message - * 124-125 0111110i Return Stack Top From (Message, Block) [i] - * 126-127 0111111i unused - * 128 10000000 jjkkkkkk Push (Receiver Variable, Temporary Location, Literal Constant, Literal Variable) [jj] #kkkkkk - * 129 10000001 jjkkkkkk Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk - * 130 10000010 jjkkkkkk Pop and Store (Receiver Variable, Temporary Location, Illegal, Literal Variable) [jj] #kkkkkk - * 131 10000011 jjjkkkkk Send Literal Selector #kkkkk With jjj Arguments - * 132 10000100 jjjjjjjj kkkkkkkk Send Literal Selector #kkkkkkkk With jjjjjjjj Arguments - * 133 10000101 jjjkkkkk Send Literal Selector #kkkkk To Superclass With jjj Arguments - * 134 10000110 jjjjjjjj kkkkkkkk Send Literal Selector #kkkkkkkk To Superclass With jjjjjjjj Arguments - * 135 10000111 Pop Stack Top - * 136 10001000 Duplicate Stack Top - * 137 10001001 Push Active Context - * 138-143 unused - * 144-151 10010iii Jump iii + 1 (i.e., 1 through 8) - * 152-159 10011iii Pop and Jump On False iii +1 (i.e., 1 through 8) - * 160-167 10100iii jjjjjjjj Jump(iii - 4) *256+jjjjjjjj - * 168-171 101010ii jjjjjjjj Pop and Jump On True ii *256+jjjjjjjj - * 172-175 101011ii jjjjjjjj Pop and Jump On False ii *256+jjjjjjjj - * 176-191 1011iiii Send Arithmetic Message #iiii - * 192-207 1100iiii Send Special Message #iiii - * 208-223 1101iiii Send Literal Selector #iiii With No Arguments - * 224-239 1110iiii Send Literal Selector #iiii With 1 Argument - * 240-255 1111iiii Send Literal Selector #iiii With 2 Arguments - */ - /** * The stix_code_t type defines byte-code enumerators. */ @@ -515,7 +478,7 @@ 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; + stix_oop_set_t mthdic_oop[2]; stix_ucs_t name; stix_size_t name_capa; @@ -539,7 +502,7 @@ struct stix_compiler_t /* information about a function being comipled */ struct { - int flags; + int type; stix_ucs_t name; stix_size_t name_capa; @@ -553,10 +516,14 @@ struct stix_compiler_t stix_size_t tmpr_nargs; /* literals */ - int literal_count; + stix_oop_t* literals; + stix_size_t literal_count; + stix_size_t literal_capa; - stix_oow_t prim_no; /* primitive number */ + /* primitive number */ + stix_oow_t prim_no; + /* byte code */ stix_code_t code; stix_size_t code_capa; } mth; @@ -731,7 +698,7 @@ stix_oop_t stix_lookupdic ( const stix_ucs_t* name ); -stix_oop_set_t stix_makedic ( +stix_oop_t stix_makedic ( stix_t* stix, stix_oop_t cls, stix_oow_t size @@ -794,17 +761,6 @@ int stix_utf8toucs ( stix_size_t* ucslen ); - -/** - * The stix_ucslen() function returns the number of characters before - * a terminating null. - */ -/* -stix_size_t stix_ucslen ( - const stix_uch_t* ucs -); -*/ - /* ========================================================================= */ /* comp.c */ /* ========================================================================= */ diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 3d791de..8b12ab2 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -109,7 +109,6 @@ typedef struct stix_ucs_t stix_ucs_t; (value = (((type)(value)) | (((bits) & STIX_LBMASK(type,length)) << (offset)))) -#define STIX /** * The STIX_BITS_MAX() macros calculates the maximum value that the 'nbits' * bits of an unsigned integer of the given 'type' can hold. @@ -313,14 +312,14 @@ typedef struct stix_obj_t* stix_oop_t; /* these are more specialized types for stix_obj_t */ typedef struct stix_obj_oop_t stix_obj_oop_t; typedef struct stix_obj_char_t stix_obj_char_t; -typedef struct stix_obj_uint8_t stix_obj_uint8_t; -typedef struct stix_obj_uint16_t stix_obj_uint16_t; +typedef struct stix_obj_byte_t stix_obj_byte_t; +typedef struct stix_obj_word_t stix_obj_word_t; /* these are more specialized types for stix_oop_t */ typedef struct stix_obj_oop_t* stix_oop_oop_t; typedef struct stix_obj_char_t* stix_oop_char_t; -typedef struct stix_obj_uint8_t* stix_oop_uint8_t; -typedef struct stix_obj_uint16_t* stix_oop_uint16_t; +typedef struct stix_obj_byte_t* stix_oop_byte_t; +typedef struct stix_obj_word_t* stix_oop_word_t; #define STIX_OOW_BITS (STIX_SIZEOF(stix_oow_t) * 8) #define STIX_OOP_BITS (STIX_SIZEOF(stix_oop_t) * 8) @@ -479,18 +478,28 @@ struct stix_obj_char_t stix_uch_t slot[1]; }; -struct stix_obj_uint8_t +struct stix_obj_byte_t { STIX_OBJ_HEADER; - stix_uint8_t slot[1]; + stix_byte_t slot[1]; }; -struct stix_obj_uint16_t +struct stix_obj_word_t { STIX_OBJ_HEADER; - stix_uint16_t slot[1]; + stix_oow_t slot[1]; }; +#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_CLASS_NAMED_INSTVARS 10 struct stix_class_t { @@ -510,8 +519,8 @@ struct stix_class_t stix_oop_char_t classinstvars; /* String */ /* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */ - stix_oop_oop_t instfuns; /* instance methods, MethodDictionary */ - stix_oop_oop_t classfuns; /* class methods, MethodDictionary */ + stix_oop_set_t instmths; /* instance methods, MethodDictionary */ + stix_oop_set_t classmths; /* class methods, MethodDictionary */ /* indexed part afterwards */ stix_oop_t classvar[1]; /* most classes have no class variables. better to be 0 */ @@ -519,16 +528,6 @@ struct stix_class_t 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 { @@ -539,7 +538,26 @@ struct stix_association_t typedef struct stix_association_t stix_association_t; typedef struct stix_association_t* stix_oop_association_t; +#define STIX_METHOD_NAMED_INSTVARS 5 +struct stix_method_t +{ + STIX_OBJ_HEADER; + stix_oop_class_t owner; /* Class */ + + /* number of temporaries including arguments */ + stix_oop_t tmpr_count; /* SmallInteger */ + /* number of arguments in temporaries */ + stix_oop_t tmpr_nargs; /* SmallInteger */ + + stix_oop_t code; /* ByteArray */ + stix_oop_t source; /* TODO: what should I put? */ + + /* variable indexed part */ + stix_oop_t literal[1]; +}; +typedef struct stix_method_t stix_method_t; +typedef struct stix_method_t* stix_oop_method_t; /** * The STIX_CLASSOF() macro return the class of an object including a numeric @@ -576,6 +594,8 @@ struct stix_cb_t { stix_cbimpl_t gc; stix_cbimpl_t fini; + + /* private below */ stix_cb_t* prev; stix_cb_t* next; }; @@ -618,9 +638,11 @@ struct stix_t stix_oop_t _string; /* String */ stix_oop_t _symbol; /* Symbol */ stix_oop_t _array; /* Array */ + stix_oop_t _byte_array; /* ByteArray */ stix_oop_t _symbol_set; /* SymbolSet */ stix_oop_t _system_dictionary; /* SystemDictionary */ stix_oop_t _method_dictionary; /* MethodDictionary */ + stix_oop_t _method; /* CompiledMethod */ stix_oop_t _association; /* Association */ stix_oop_t _true_class; /* True */ stix_oop_t _false_class; /* False */