From af9c144a1cd7cdc3429ef6cbcd2010fa94dd247b Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Thu, 5 Jan 2017 10:16:04 +0000 Subject: [PATCH] added Apex>>hash added Symbol>>asString revised String>>& added some methods to Dictionary --- stix/kernel/Apex.st | 60 +++++++++++---- stix/kernel/Collect.st | 127 ++++++++++++++++++++++++++++--- stix/kernel/Except.st | 164 ++++++++++++++++++++++++++-------------- stix/kernel/Stix.st | 11 ++- stix/kernel/test-014.st | 2 +- stix/lib/dic.c | 8 +- stix/lib/exec.c | 86 ++++++++++++++++++++- stix/lib/gc.c | 2 +- stix/lib/stix-utl.h | 103 ++++++++++++++++--------- stix/lib/stix.h | 11 ++- stix/lib/sym.c | 6 +- stix/lib/utl.c | 5 -- 12 files changed, 446 insertions(+), 139 deletions(-) diff --git a/stix/kernel/Apex.st b/stix/kernel/Apex.st index 9abcdd3..d8599da 100644 --- a/stix/kernel/Apex.st +++ b/stix/kernel/Apex.st @@ -121,29 +121,41 @@ self primitiveFailed. } - #method basicAt: anInteger + #method basicAt: index { -## TODO: chagne it to 'self outOfRangeError' or something. - self error: 'out of range'. + self index: index outOfRange: (self basicSize). } - #method basicAt: anInteger put: anObject + #method basicAt: index put: anObject { - self error: 'out of range'. + self index: index outOfRange: (self basicSize). } - #method(#class) basicAt: anInteger + #method(#class) basicAt: index { - self error: 'out of range'. + self index: index outOfRange: (self basicSize). } - #method(#class) basicAt: anInteger put: anObject + #method(#class) basicAt: index put: anObject { - self error: 'out of range'. + self index: index outOfRange: (self basicSize). + } + + ## ------------------------------------------------------- + ## ------------------------------------------------------- + #method(#class) hash + { + + self subclassResponsibility: #hash + } + #method hash + { + + self subclassResponsibility: #hash } ## ------------------------------------------------------- @@ -270,7 +282,6 @@ } " - ## ------------------------------------------------------- ## ------------------------------------------------------- ## method(#class) primitiveFailed @@ -300,10 +311,31 @@ self class error: aString. } + #method index: index outOfRange: ubound + { + self class index: index outOfRange: ubound. + } + #method cannotInstantiate { self class cannotInstantiate } + + #method subclassResponsibility: message_name + { + self class subclassResponsibility: message_name + } + + #method cannotExceptionizeError + { + self class cannotExceptionizeError + } + + #method exceptionizeError: trueOrFalse + { + + self class cannotExceptionizeError + } } #class Object(Apex) @@ -332,14 +364,14 @@ } } -(* -------------------- -#pooldic Error + +#pooldic ErrorCode { +(* migrate it into Error class *) #NONE := error(0). #GENERIC := error(1). - # + #NOENT := error(2). } -------------------- *) #class Error(Apex) { diff --git a/stix/kernel/Collect.st b/stix/kernel/Collect.st index 2005025..1e9f571 100644 --- a/stix/kernel/Collect.st +++ b/stix/kernel/Collect.st @@ -51,28 +51,47 @@ #class(#character) String(Array) { - #method & aString + #method & string { - ## concatenate two strings. -## TOOD: make this a primitive for performance. - | newsize newstr self_ubound | + (* TOOD: make this a primitive for performance. *) + + (* concatenate two strings. *) + | newsize newstr cursize appsize | - newsize := self basicSize + aString basicSize. - ##newstr := self class basicNew: newsize. - newstr := String basicNew: newsize. ## TODO: redefine , for symbol... it's a work arouind... symbols are not concatenated to a symbol at this moment. - self_ubound := self ubound. + cursize := self basicSize. + appsize := string basicSize. + newsize := cursize + appsize. + (*newstr := self class basicNew: newsize.*) + newstr := String basicNew: newsize. - 0 to: self_ubound do: [:i | newstr at: i put: (self at: i) ]. - 0 to: (aString ubound) do: [:i | newstr at: (i + self_ubound + 1) put: (aString at: i) ]. + 0 priorTo: cursize do: [:i | newstr at: i put: (self at: i) ]. + 0 priorTo: appsize do: [:i | newstr at: (i + cursize) put: (string at: i) ]. ^newstr } + + #method asString + { + ^self + } } ## ------------------------------------------------------------------------------- #class(#character) Symbol(String) { + #method asString + { + (* TODO: make this a primitive for performance *) + + (* convert a symbol to a string *) + | size str | + size := self basicSize. + str := String basicNew: size. + + 0 priorTo: size do: [:i | str at: i put: (self at: i) ]. + ^str. + } } ## ------------------------------------------------------------------------------- @@ -95,6 +114,94 @@ #class Set(Collection) { #dcl tally bucket. + + #method initialize + { + self.tally := 0. + self.bucket := Array new: 100. + } + + #method size + { + ^self.tally + } + + #method at: key + { + | ass | + ass := self __find: key or_upsert: false with: nil. + (ass notNil) ifTrue: [^ass value]. + ^ErrorCode.NOENT + } + + #method at: key ifAbsent: error_block + { + | ass | + ass := self __find: key or_upsert: false with: nil. + (ass notNil) ifTrue: [^ass value]. + ^error_block value. + } + + #method at: key put: value + { + self __find: key or_upsert: true with: value. + ^value + } + + #method __find: key or_upsert: upsert with: value + { + | hv ass bs index ntally | + + bs := self.bucket size. + hv := key hash. + index := hv rem: bs. + + [(ass := self.bucket at: index) notNil] + whileTrue: [ + [key == ass key] ifTrue: [ + (* found *) + upsert ifTrue: [ass value: value]. + ^ass + ]. + index := (index + 1) rem: bs. + ]. + + upsert ifFalse: [^nil]. + + ntally := self.tally + 1. + (ntally >= bs) ifTrue: [ + (* expand the bucket *) + + ]. + + ass := Association key: key value: value. + self.tally := ntally. + self.bucket at: index put: ass. + + ^ass + } + + #method do: block + { + | bs | + + bs := self.bucket size. + 0 priorTo: bs by: 1 do: [:i | + | ass | + (ass := self.bucket at: i) notNil ifTrue: [block value: ass value] + ]. + } + + #method keysAndValuesDo: block + { + | bs | + + bs := self.bucket size. + 0 priorTo: bs by: 1 do: [:i | + | ass | + (ass := self.bucket at: i) notNil ifTrue: [block value: ass key value: ass value] + ]. + } } #class SymbolSet(Set) diff --git a/stix/kernel/Except.st b/stix/kernel/Except.st index 0073053..9979bd5 100644 --- a/stix/kernel/Except.st +++ b/stix/kernel/Except.st @@ -28,6 +28,11 @@ ^self.messageText } + #method asString + { + ^(self class name) & ' - ' & self.messageText. + } + #method __signal { self.signalContext := thisContext. @@ -36,24 +41,24 @@ #method signal { - | excctx excblk retval actpos | + | exctx exblk retval actpos | self.signalContext := thisContext. - excctx := (thisContext sender) findExceptionContext. - [excctx notNil] whileTrue: [ - excblk := excctx findExceptionHandlerFor: (self class). - (excblk notNil and: - [actpos := excctx basicSize - 1. excctx basicAt: actpos]) ifTrue: [ - self.handlerContext := excctx. - excctx basicAt: actpos put: false. - [ retval := excblk value: self ] ensure: [ - excctx basicAt: actpos put: true + exctx := (thisContext sender) findExceptionContext. + [exctx notNil] whileTrue: [ + exblk := exctx findExceptionHandlerFor: (self class). + (exblk notNil and: + [actpos := exctx basicSize - 1. exctx basicAt: actpos]) ifTrue: [ + self.handlerContext := exctx. + exctx basicAt: actpos put: false. + [ retval := exblk value: self ] ensure: [ + exctx basicAt: actpos put: true ]. - thisContext unwindTo: (excctx sender) return: nil. - Processor return: retval to: (excctx sender). + thisContext unwindTo: (exctx sender) return: nil. + Processor return: retval to: (exctx sender). ]. - excctx := (excctx sender) findExceptionContext. + exctx := (exctx sender) findExceptionContext. ]. ## ----------------------------------------------------------------- @@ -195,6 +200,14 @@ #method ensureBlock { ## TODO: change 8 to a constant when stix is enhanced to support constant definition + + (* [ value-block ] ensure: [ ensure-block ] + * assuming ensure block is a parameter the ensure: method to a + * block context, the first parameter is placed after the fixed + * instance variables of the method context. As MethodContex has + * 8 instance variables, the ensure block must be at the 9th position + * which translates to index 8 *) + (self.method preambleCode == 11) ifFalse: [^nil]. ^self basicAt: 8. } @@ -202,21 +215,26 @@ #method findExceptionHandlerFor: exception_class { - ## find an exception handler block for a given exception class. - ## - ## for this to work, self must be an exception handler context. - ## For a single on:do: call, - ## self class specNumInstVars must return 8. - ## basicAt: 8 must be the on: argument. - ## basicAt: 9 must be the do: argument + (* find an exception handler block for a given exception class. + * + * for this to work, self must be an exception handler context. + * For a single on:do: call, + * self class specNumInstVars must return 8.(i.e.MethodContext has 8 instance variables.) + * basicAt: 8 must be the on: argument. + * basicAt: 9 must be the do: argument *) - (self isExceptionContext) ifTrue: [ - | bound exc | - ## NOTE: if on:do: has a temporary varible, bound must be adjusted to reflect it. - bound := self basicSize - 1. ## TODO: change 8 to a constant when stix is enhanced to support constant definition ## or calcuate the minimum size using the class information. - 8 to: bound by: 2 do: [ :i | + + (self isExceptionContext) ifTrue: [ + | size exc | + + (* NOTE: the following loop scans all parameters to the on:do: method. + * if the on:do: method contains local temporary variables, + * those must be skipped from scanning. *) + + size := self basicSize. + 8 priorTo: size by: 2 do: [ :i | exc := self basicAt: i. ((exception_class == exc) or: [exception_class inheritsFrom: exc]) ifTrue: [^self basicAt: (i + 1)]. ] @@ -226,20 +244,20 @@ #method handleException: exception { - ## ------------------------------------------------------------------- - ## <> - ## called by Exception>>signal. - ## this method only exists in the MethodContext and UndefinedObject. - ## the caller must make sure that the receiver object is - ## a method context or nil. Exception>>signal invokes this method - ## only for an exception context which is a method context. it - ## invokes it for nil when no exception context is found. - ## ------------------------------------------------------------------- + (* ----------------------------------------------------------------- + * <> + * called by Exception>>signal. + * this method only exists in the MethodContext and UndefinedObject. + * the caller must make sure that the receiver object is + * a method context or nil. Exception>>signal invokes this method + * only for an exception context which is a method context. it + * invokes it for nil when no exception context is found. + * ---------------------------------------------------------------- *) | excblk retval actpos | - ## position of the temporary variable 'active' in MethodContext>>on:do. - ## for this code to work, it must be the last temporary variable in the method. + (* position of the temporary variable 'active' in MethodContext>>on:do. + * for this code to work, it must be the last temporary variable in the method. *) actpos := (self basicSize) - 1. excblk := self findExceptionHandlerFor: (exception class). @@ -252,13 +270,13 @@ exception handlerContext: self. - ## ------------------------------------------------------------------- - ## if an exception occurs within an exception handler block, - ## the search will reach this context again as the exception block - ## is evaluated before actual unwinding. set the temporary variable - ## in the exception context to mask out this context from the search - ## list. - ## ------------------------------------------------------------------- + (* ----------------------------------------------------------------- + * if an exception occurs within an exception handler block, + * the search will reach this context again as the exception block + * is evaluated before actual unwinding. set the temporary variable + * in the exception context to mask out this context from the search + * list. + * ---------------------------------------------------------------- *) self basicAt: actpos put: false. [ retval := excblk value: exception ] ensure: [ self basicAt: actpos put: true @@ -266,13 +284,11 @@ ##(self.sender isNil) ifTrue: [ "TODO: CANNOT RETURN" ]. - ## ------------------------------------------------------------------- - ## return to self.sender which is a caller of the exception context (on:do:) - ## pass the first ensure context between thisContext and self.sender. - ## - ## [ [Exception signal: 'xxx'] ensure: [20] ] on: Exception do: [:ex | ...] - ## - ## ------------------------------------------------------------------- + (* ----------------------------------------------------------------- + * return to self.sender which is a caller of the exception context (on:do:) + * pass the first ensure context between thisContext and self.sender. + * [ [Exception signal: 'xxx'] ensure: [20] ] on: Exception do: [:ex | ...] + * ---------------------------------------------------------------- *) thisContext unwindTo: self.sender return: nil. Processor return: retval to: self.sender. } @@ -286,13 +302,14 @@ | exception_active | -"thisContext isExceptionContext dump. +(* ------------------------------- +thisContext isExceptionContext dump. (thisContext basicSize) dump. (thisContext basicAt: 8) dump. ## this should be anException (thisContext basicAt: 9) dump. ## this should be anExceptionBlock (thisContext basicAt: 10) dump. ## this should be handlerActive -'on:do: ABOUT TO EVALUE THE RECEIVER BLOCK' dump." - +'on:do: ABOUT TO EVALUE THE RECEIVER BLOCK' dump. +---------------------------------- *) exception_active := true. ^self value. } @@ -334,6 +351,10 @@ ##============================================================================ +#class InstantiationFailureException(Exception) +{ +} + #class NoSuchMessageException(Exception) { } @@ -342,6 +363,18 @@ { } +#class IndexOutOfRangeException(Exception) +{ +} + +#class SubclassResponsibilityException(Exception) +{ +} + +#class ErrorExceptionizationFailureException(Exception) +{ +} + #extend Apex { #method(#class) primitiveFailed @@ -362,14 +395,29 @@ ctx := thisContext. #method(#class) cannotInstantiate { - Exception signal: 'Cannot instantiate'. +## TOOD: accept a class + InstantiationFailureException signal: 'Cannot instantiate'. } - #method(#class) doesNotUnderstand: messageSymbol + #method(#class) doesNotUnderstand: message_name { ## TODO: implement this properly - NoSuchMessageException signal: (messageSymbol & ' not understood by ' & (self name)). + NoSuchMessageException signal: (message_name & ' not understood by ' & (self name)). + } + + #method(#class) index: index outOfRange: ubound + { + IndexOutOfRangeException signal: 'Out of range'. + } + + #method(#class) subclassResponsibility: message_name + { + SubclassResponsibilityException signal: ('Subclass must implment ' & message_name). + } + + #method(#class) cannotExceptionizeError + { +## todo: accept the object + ErrorExceptionizationFailureException signal: 'Cannot exceptionize an error' } } - - diff --git a/stix/kernel/Stix.st b/stix/kernel/Stix.st index 191bacf..a9ece74 100644 --- a/stix/kernel/Stix.st +++ b/stix/kernel/Stix.st @@ -11,6 +11,10 @@ { #dcl key value. + #method(#class) key: key value: value + { + ^self new key: key value: value + } #method key: key value: value { self.key := key. @@ -154,6 +158,9 @@ #method bitShift: aNumber { + (* positive number for left shift. + * negative number for right shift *) + self primitiveFailed. } @@ -303,7 +310,7 @@ #method preambleCode { - ^self.preamble bitAnd: 16rFF. + ^(self.preamble bitAnd: 16rFF) bitShift: -2. } #method owner @@ -396,4 +403,4 @@ f isNil ifTrue: [ self error: 'No such function' ]. ######################################################################################### #include 'Stdio.st'. -#include 'Console.st'. \ No newline at end of file +#include 'Console.st'. diff --git a/stix/kernel/test-014.st b/stix/kernel/test-014.st index 189e314..f43bc59 100644 --- a/stix/kernel/test-014.st +++ b/stix/kernel/test-014.st @@ -226,7 +226,7 @@ #! [ a = error(10) ] ifTrue: [....]. #! self t001 (error:10). - #! self t001: (error:10) + #! self t001: (error:10) } } diff --git a/stix/lib/dic.c b/stix/lib/dic.c index 708a9b5..4310c49 100644 --- a/stix/lib/dic.c +++ b/stix/lib/dic.c @@ -76,7 +76,7 @@ static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t oldbuc) key = (stix_oop_char_t)ass->key; STIX_ASSERT (stix, STIX_CLASSOF(stix,key) == (stix_oop_t)stix->_symbol); - index = stix_hashchars(key->slot, STIX_OBJ_GET_SIZE(key)) % newsz; + index = stix_hashoochars(key->slot, STIX_OBJ_GET_SIZE(key)) % newsz; while (newbuc->slot[index] != stix->_nil) index = (index + 1) % newsz; newbuc->slot[index] = (stix_oop_t)ass; } @@ -98,7 +98,7 @@ static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic, STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->tally) == stix->_small_integer); STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->bucket) == stix->_array); - index = stix_hashchars(key->slot, STIX_OBJ_GET_SIZE(key)) % STIX_OBJ_GET_SIZE(dic->bucket); + index = stix_hashoochars(key->slot, STIX_OBJ_GET_SIZE(key)) % STIX_OBJ_GET_SIZE(dic->bucket); /* find */ while (dic->bucket->slot[index] != stix->_nil) @@ -164,7 +164,7 @@ static stix_oop_association_t find_or_upsert (stix_t* stix, stix_oop_set_t dic, dic->bucket = bucket; /* recalculate the index for the expanded bucket */ - index = stix_hashchars(key->slot, STIX_OBJ_GET_SIZE(key)) % STIX_OBJ_GET_SIZE(dic->bucket); + index = stix_hashoochars(key->slot, STIX_OBJ_GET_SIZE(key)) % STIX_OBJ_GET_SIZE(dic->bucket); while (dic->bucket->slot[index] != stix->_nil) index = (index + 1) % STIX_OBJ_GET_SIZE(dic->bucket); @@ -203,7 +203,7 @@ static stix_oop_association_t lookup (stix_t* stix, stix_oop_set_t dic, const st STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->tally) == stix->_small_integer); STIX_ASSERT (stix, STIX_CLASSOF(stix,dic->bucket) == stix->_array); - index = stix_hashchars(name->ptr, name->len) % STIX_OBJ_GET_SIZE(dic->bucket); + index = stix_hashoochars(name->ptr, name->len) % STIX_OBJ_GET_SIZE(dic->bucket); while (dic->bucket->slot[index] != stix->_nil) { diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 8abe89b..74e6c15 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -1613,6 +1613,87 @@ static int pf_basic_at_put (stix_t* stix, stix_ooi_t nargs) return 1; } +static int pf_hash (stix_t* stix, stix_ooi_t nargs) +{ + stix_oop_t rcv; + stix_oow_t hv; + + STIX_ASSERT (stix, nargs == 0); + rcv = STIX_STACK_GETRCV(stix, nargs); + + switch (STIX_OOP_GET_TAG(rcv)) + { + case STIX_OOP_TAG_SMINT: + hv = STIX_OOP_TO_CHAR(rcv); + break; + + case STIX_OOP_TAG_CHAR: + hv = STIX_OOP_TO_CHAR(rcv); + break; + + case STIX_OOP_TAG_ERROR: + hv = STIX_OOP_TO_ERROR(rcv); + break; + + default: + { + int type; + + STIX_ASSERT (stix, STIX_OOP_IS_POINTER(rcv)); + type = STIX_OBJ_GET_FLAGS_TYPE(rcv); + switch (type) + { + case STIX_OBJ_TYPE_BYTE: + hv = stix_hashbytes(((stix_oop_byte_t)rcv)->slot, STIX_OBJ_GET_SIZE(rcv)); + break; + + case STIX_OBJ_TYPE_CHAR: + hv = stix_hashoochars (((stix_oop_char_t)rcv)->slot, STIX_OBJ_GET_SIZE(rcv)); + break; + + case STIX_OBJ_TYPE_HALFWORD: + hv = stix_hashhalfwords(((stix_oop_halfword_t)rcv)->slot, STIX_OBJ_GET_SIZE(rcv)); + break; + + case STIX_OBJ_TYPE_WORD: + hv = stix_hashwords(((stix_oop_word_t)rcv)->slot, STIX_OBJ_GET_SIZE(rcv)); + break; + + default: + /* STIX_OBJ_TYPE_OOP, ... */ + STIX_DEBUG1 (stix, " Cannot hash an object of type %d\n", type); + return 0; + } + break; + } + } + + hv %= STIX_SMOOI_MAX; + STIX_STACK_SETRET (stix, nargs, STIX_SMOOI_TO_OOP(hv)); + return 1; +} + +static int pf_exceptionize_error (stix_t* stix, stix_ooi_t nargs) +{ + stix_oop_t rcv; + + STIX_ASSERT (stix, nargs == 1); + + rcv = STIX_STACK_GETRCV(stix, nargs); + if (!STIX_OOP_IS_POINTER(rcv)) + { + /* the receiver is a special numeric object, not a normal pointer. + * excceptionization is not supported for small integers, characters, and errors. + * first of all, methods of these classes must not return errors */ + return 0; + } + +// TODO: ....... +// STIX_OBJ_SET_FLAGS_EXTRA (rcv, xxx); + STIX_STACK_SETRETTORCV (stix, nargs); + return 1; +} + static int pf_context_goto (stix_t* stix, stix_ooi_t nargs) { stix_oop_t rcv; @@ -2496,7 +2577,6 @@ static int pf_error_as_string (stix_t* stix, stix_ooi_t nargs) return 1; } - static int pf_ffi_open (stix_t* stix, stix_ooi_t nargs) { stix_oop_t rcv, arg; @@ -2809,6 +2889,9 @@ static pf_t pftab[] = { 1, 1, pf_basic_at, "_basic_at" }, { 2, 2, pf_basic_at_put, "_basic_at_put" }, + { 0, 0, pf_hash, "_hash" }, + + { 1, 1, pf_exceptionize_error, "_exceptionize_error" }, { 1, 1, pf_context_goto, "_context_goto" }, { 0, MAX_NARGS, pf_block_value, "_block_value" }, @@ -2855,7 +2938,6 @@ static pf_t pftab[] = { 0, 0, pf_error_as_integer, "_error_as_integer" }, { 0, 0, pf_error_as_string, "_error_as_string" }, - { 1, 1, pf_ffi_open, "_ffi_open" }, { 1, 1, pf_ffi_close, "_ffi_close" }, { 2, 2, pf_ffi_getsym, "_ffi_getsym" }, diff --git a/stix/lib/gc.c b/stix/lib/gc.c index 14a3ee2..aa31a24 100644 --- a/stix/lib/gc.c +++ b/stix/lib/gc.c @@ -370,7 +370,7 @@ static void compact_symbol_table (stix_t* stix, stix_oop_t _nil) STIX_ASSERT (stix, STIX_CLASSOF(stix,symbol) == stix->_symbol); - z = stix_hashchars(symbol->slot, STIX_OBJ_GET_SIZE(symbol)) % bucket_size; + z = stix_hashoochars(symbol->slot, STIX_OBJ_GET_SIZE(symbol)) % bucket_size; /* move an element if necessary */ if ((y > x && (z <= x || z > y)) || diff --git a/stix/lib/stix-utl.h b/stix/lib/stix-utl.h index 2ae6039..8a8a35a 100644 --- a/stix/lib/stix-utl.h +++ b/stix/lib/stix-utl.h @@ -33,48 +33,50 @@ extern "C" { #endif -#if defined(STIX_OOCH_IS_UCH) -# define stix_hashchars(ptr,len) stix_hashuchars(ptr,len) -# define stix_equaloochars(str1,str2,len) stix_equaluchars(str1,str2,len) -# define stix_compoocbcstr(str1,str2) stix_compucbcstr(str1,str2) -# define stix_compoocharsbcstr(str1,len1,str2) stix_compucharsbcstr(str1,len1,str2) -# define stix_compoocstr(str1,str2) stix_compucstr(str1,str2) -# define stix_copyoochars(dst,src,len) stix_copyuchars(dst,src,len) -# define stix_copybctooochars(dst,src,len) stix_copybtouchars(dst,src,len) -# define stix_copyoocstr(dst,len,src) stix_copyucstr(dst,len,src) -# define stix_findoochar(ptr,len,c) stix_finduchar(ptr,len,c) -# define stix_rfindoochar(ptr,len,c) stix_rfinduchar(ptr,len,c) -# define stix_countoocstr(str) stix_countucstr(str) -#else -# define stix_hashchars(ptr,len) stix_hashbchars(ptr,len) -# define stix_equaloochars(str1,str2,len) stix_equalbchars(str1,str2,len) -# define stix_compoocbcstr(str1,str2) stix_compbcstr(str1,str2) -# define stix_compoocharsbcstr(str1,len1,str2) stix_compbcharsbcstr(str1,len1,str2) -# define stix_compoocstr(str1,str2) stix_compbcstr(str1,str2) -# define stix_copyoochars(dst,src,len) stix_copybchars(dst,src,len) -# define stix_copybctooochars(dst,src,len) stix_copybchars(dst,src,len) -# define stix_copyoocstr(dst,len,src) stix_copybcstr(dst,len,src) -# define stix_findoochar(ptr,len,c) stix_findbchar(ptr,len,c) -# define stix_rfindoochar(ptr,len,c) stix_rfindbchar(ptr,len,c) -# define stix_countoocstr(str) stix_countbcstr(str) -#endif - - -/* ========================================================================= */ -/* utl.c */ -/* ========================================================================= */ STIX_EXPORT stix_oow_t stix_hashbytes ( const stix_oob_t* ptr, stix_oow_t len ); -STIX_EXPORT stix_oow_t stix_hashuchars ( - const stix_uch_t* ptr, +#if defined(STIX_HAVE_INLINE) + static STIX_INLINE stix_oow_t stix_hashbchars (const stix_bch_t* ptr, stix_oow_t len) + { + return stix_hashbytes((const stix_oob_t*)ptr,len * STIX_SIZEOF(stix_bch_t)); + } + + static STIX_INLINE stix_oow_t stix_hashuchars (const stix_uch_t* ptr, stix_oow_t len) + { + return stix_hashbytes((const stix_oob_t*)ptr,len * STIX_SIZEOF(stix_uch_t)); + } + + static STIX_INLINE stix_oow_t stix_hashwords (const stix_oow_t* ptr, stix_oow_t len) + { + return stix_hashbytes((const stix_oob_t*)ptr, len * STIX_SIZEOF(stix_oow_t)); + } + + static STIX_INLINE stix_oow_t stix_hashhalfwords (const stix_oohw_t* ptr, stix_oow_t len) + { + return stix_hashbytes((const stix_oob_t*)ptr, len * STIX_SIZEOF(stix_oohw_t)); + } +#else +# define stix_hashbchars(ptr,len) stix_hashbytes((const stix_oob_t*)ptr,len * STIX_SIZEOF(stix_bch_t)) +# define stix_hashuchars(ptr,len) stix_hashbytes((const stix_oob_t*)ptr,len * STIX_SIZEOF(stix_uch_t)) +# define stix_hashwords(ptr,len) stix_hashbytes((const stix_oob_t*)ptr, len * STIX_SIZEOF(stix_oow_t)) +# define stix_hashhalfwords(ptr,len) stix_hashbytes((const stix_oob_t*)ptr, len * STIX_SIZEOF(stix_oohw_t)) +#endif + +#if defined(STIX_OOCH_IS_UCH) +# define stix_hashoochars(ptr,len) stix_hashuchars(ptr,len) +#else +# define stix_hashoochars(ptr,len) stix_hashbchars(ptr,len) +#endif + + +STIX_EXPORT stix_oow_t stix_hashwords ( + const stix_oow_t* ptr, stix_oow_t len ); -#define stix_hashbchars(ptr,len) stix_hashbytes(ptr,len) - /** * The stix_equaluchars() function determines equality of two strings * of the same length \a len. @@ -181,6 +183,33 @@ STIX_EXPORT stix_oow_t stix_countbcstr ( const stix_bch_t* str ); +#if defined(STIX_OOCH_IS_UCH) +# define stix_equaloochars(str1,str2,len) stix_equaluchars(str1,str2,len) +# define stix_compoocbcstr(str1,str2) stix_compucbcstr(str1,str2) +# define stix_compoocharsbcstr(str1,len1,str2) stix_compucharsbcstr(str1,len1,str2) +# define stix_compoocstr(str1,str2) stix_compucstr(str1,str2) +# define stix_copyoochars(dst,src,len) stix_copyuchars(dst,src,len) +# define stix_copybctooochars(dst,src,len) stix_copybtouchars(dst,src,len) +# define stix_copyoocstr(dst,len,src) stix_copyucstr(dst,len,src) +# define stix_findoochar(ptr,len,c) stix_finduchar(ptr,len,c) +# define stix_rfindoochar(ptr,len,c) stix_rfinduchar(ptr,len,c) +# define stix_countoocstr(str) stix_countucstr(str) +#else + +# define stix_equaloochars(str1,str2,len) stix_equalbchars(str1,str2,len) +# define stix_compoocbcstr(str1,str2) stix_compbcstr(str1,str2) +# define stix_compoocharsbcstr(str1,len1,str2) stix_compbcharsbcstr(str1,len1,str2) +# define stix_compoocstr(str1,str2) stix_compbcstr(str1,str2) +# define stix_copyoochars(dst,src,len) stix_copybchars(dst,src,len) +# define stix_copybctooochars(dst,src,len) stix_copybchars(dst,src,len) +# define stix_copyoocstr(dst,len,src) stix_copybcstr(dst,len,src) +# define stix_findoochar(ptr,len,c) stix_findbchar(ptr,len,c) +# define stix_rfindoochar(ptr,len,c) stix_rfindbchar(ptr,len,c) +# define stix_countoocstr(str) stix_countbcstr(str) +#endif + + + STIX_EXPORT int stix_copyoocstrtosbuf ( stix_t* stix, const stix_ooch_t* str, @@ -279,9 +308,8 @@ STIX_EXPORT int stix_convutf8toucstr ( stix_oow_t* ucslen ); -/* ========================================================================= */ -/* utf8.c */ -/* ========================================================================= */ + + STIX_EXPORT stix_oow_t stix_uctoutf8 ( stix_uch_t uc, stix_bch_t* utf8, @@ -294,6 +322,7 @@ STIX_EXPORT stix_oow_t stix_utf8touc ( stix_uch_t* uc ); + #if defined(__cplusplus) } #endif diff --git a/stix/lib/stix.h b/stix/lib/stix.h index e8565ff..57b3159 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -526,7 +526,10 @@ struct stix_method_t * 8 - do primitive[index] * 9 - do named primitive[index] * 10 - exception handler + * 11 - ensure block */ + +/* NOTE: changing preamble code bit structure requires changes to CompiledMethod>>preambleCode */ #define STIX_METHOD_MAKE_PREAMBLE(code,index,flags) ((((stix_ooi_t)index) << 8) | ((stix_ooi_t)code << 2) | flags) #define STIX_METHOD_GET_PREAMBLE_CODE(preamble) ((((stix_ooi_t)preamble) & 0xFF) >> 2) #define STIX_METHOD_GET_PREAMBLE_INDEX(preamble) (((stix_ooi_t)preamble) >> 8) @@ -543,8 +546,9 @@ struct stix_method_t #define STIX_METHOD_PREAMBLE_RETURN_INSTVAR 7 #define STIX_METHOD_PREAMBLE_PRIMITIVE 8 #define STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE 9 /* index is an index to the symbol table */ -#define STIX_METHOD_PREAMBLE_EXCEPTION 10 -#define STIX_METHOD_PREAMBLE_ENSURE 11 + +#define STIX_METHOD_PREAMBLE_EXCEPTION 10 /* NOTE changing this requires changes in Except.st */ +#define STIX_METHOD_PREAMBLE_ENSURE 11 /* NOTE changing this requires changes in Except.st */ /* the index is an 16-bit unsigned integer. */ #define STIX_METHOD_PREAMBLE_INDEX_MIN 0x0000 @@ -554,6 +558,9 @@ struct stix_method_t /* preamble flags */ #define STIX_METHOD_PREAMBLE_FLAG_VARIADIC (1 << 0) +/* NOTE: if you change the number of instance variables for stix_context_t, + * you need to change the defintion of BlockContext and MethodContext. + * plus, you need to update various exception handling code in MethodContext */ #define STIX_CONTEXT_NAMED_INSTVARS 8 typedef struct stix_context_t stix_context_t; typedef struct stix_context_t* stix_oop_context_t; diff --git a/stix/lib/sym.c b/stix/lib/sym.c index 20b9111..b06649b 100644 --- a/stix/lib/sym.c +++ b/stix/lib/sym.c @@ -73,7 +73,7 @@ static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t oldbuc) STIX_ASSERT (stix, STIX_CLASSOF(stix,symbol) == stix->_symbol); /*STIX_ASSERT (stix, sym->size > 0);*/ - index = stix_hashchars(symbol->slot, STIX_OBJ_GET_SIZE(symbol)) % newsz; + index = stix_hashoochars(symbol->slot, STIX_OBJ_GET_SIZE(symbol)) % newsz; while (newbuc->slot[index] != stix->_nil) index = (index + 1) % newsz; newbuc->slot[index] = (stix_oop_t)symbol; } @@ -97,7 +97,7 @@ static stix_oop_t find_or_make_symbol (stix_t* stix, const stix_ooch_t* ptr, sti } STIX_ASSERT (stix, STIX_CLASSOF(stix,stix->symtab->bucket) == stix->_array); - index = stix_hashchars(ptr, len) % STIX_OBJ_GET_SIZE(stix->symtab->bucket); + index = stix_hashoochars(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) @@ -153,7 +153,7 @@ static stix_oop_t find_or_make_symbol (stix_t* stix, const stix_ooch_t* ptr, sti stix->symtab->bucket = bucket; /* recalculate the index for the expanded bucket */ - index = stix_hashchars(ptr, len) % STIX_OBJ_GET_SIZE(stix->symtab->bucket); + index = stix_hashoochars(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); diff --git a/stix/lib/utl.c b/stix/lib/utl.c index ec184db..376a459 100644 --- a/stix/lib/utl.c +++ b/stix/lib/utl.c @@ -48,11 +48,6 @@ stix_oow_t stix_hashbytes (const stix_oob_t* ptr, stix_oow_t len) return h; } -stix_oow_t stix_hashuchars (const stix_uch_t* ptr, stix_oow_t len) -{ - return stix_hashbytes ((const stix_oob_t *)ptr, len * STIX_SIZEOF(*ptr)); -} - int stix_equaluchars (const stix_uch_t* str1, const stix_uch_t* str2, stix_oow_t len) { stix_oow_t i;