diff --git a/kernel/Makefile.frag b/kernel/Makefile.frag index c94ea1a..12a6769 100644 --- a/kernel/Makefile.frag +++ b/kernel/Makefile.frag @@ -1,3 +1,3 @@ $(srcdir)/kernel/stamp-classes: \ -kernel/Array.st kernel/CompildMeth.st kernel/LookupTable.st kernel/RunArray.st kernel/Iterable.st kernel/ArrayColl.st kernel/CompiledBlk.st kernel/Magnitude.st kernel/Semaphore.st kernel/DeferBinding.st kernel/Association.st kernel/HomedAssoc.st kernel/ContextPart.st kernel/MappedColl.st kernel/SeqCollect.st kernel/Autoload.st kernel/DLD.st kernel/Memory.st kernel/Set.st kernel/Bag.st kernel/Date.st kernel/Message.st kernel/SharedQueue.st kernel/Behavior.st kernel/Delay.st kernel/Metaclass.st kernel/SmallInt.st kernel/BlkClosure.st kernel/Continuation.st kernel/Generator.st kernel/Dictionary.st kernel/MethodDict.st kernel/SortCollect.st kernel/BlkContext.st kernel/DirMessage.st kernel/MethodInfo.st kernel/Stream.st kernel/Boolean.st kernel/Directory.st kernel/MthContext.st kernel/String.st kernel/UniString.st kernel/ExcHandling.st kernel/Namespace.st kernel/SymLink.st kernel/VFS.st kernel/VFSZip.st kernel/Builtins.st kernel/False.st kernel/Number.st kernel/Symbol.st kernel/ByteArray.st kernel/FilePath.st kernel/File.st kernel/ObjDumper.st kernel/SysDict.st kernel/ScaledDec.st kernel/FileSegment.st kernel/Object.st kernel/Time.st kernel/FileStream.st kernel/Security.st kernel/OrderColl.st kernel/CCallable.st kernel/CCallback.st kernel/CFuncs.st kernel/Float.st kernel/PkgLoader.st kernel/Transcript.st kernel/CObject.st kernel/Fraction.st kernel/Point.st kernel/True.st kernel/CStruct.st kernel/IdentDict.st kernel/PosStream.st kernel/UndefObject.st kernel/CType.st kernel/IdentitySet.st kernel/ProcSched.st kernel/ProcEnv.st kernel/ValueAdapt.st kernel/CharArray.st kernel/Integer.st kernel/Process.st kernel/CallinProcess.st kernel/WeakObjects.st kernel/Character.st kernel/UniChar.st kernel/Interval.st kernel/RWStream.st kernel/OtherArrays.st kernel/Class.st kernel/LargeInt.st kernel/Random.st kernel/WriteStream.st kernel/ClassDesc.st kernel/Link.st kernel/ReadStream.st kernel/ObjMemory.st kernel/Collection.st kernel/LinkedList.st kernel/Rectangle.st kernel/AnsiDates.st kernel/CompildCode.st kernel/LookupKey.st kernel/BindingDict.st kernel/AbstNamespc.st kernel/RootNamespc.st kernel/SysExcept.st kernel/DynVariable.st kernel/HashedColl.st kernel/FileDescr.st kernel/FloatD.st kernel/FloatE.st kernel/FloatQ.st kernel/URL.st kernel/VarBinding.st kernel/RecursionLock.st kernel/Getopt.st kernel/Regex.st kernel/StreamOps.st + touch $(srcdir)/kernel/stamp-classes diff --git a/kernel/UniChar.st b/kernel/UniChar.st index 0b48eed..53d3401 100644 --- a/kernel/UniChar.st +++ b/kernel/UniChar.st @@ -41,27 +41,77 @@ character objects. UnicodeCharacter objects are created when accessing UnicodeStrings, or with Character class>>#codePoint:.'> - UnicodeCharacter class >> value: anInteger [ - "Returns the character object, possibly a Character, corresponding - to anInteger. Error if anInteger is not an integer, or not in - 0..16r10FFFF. - - This is only a primitive for speed. UnicodeCharacter's #value: - method is equivalent to #codePoint: (which is the same for - Character and UnicodeCharacter)." + UnicodeCharacter class >> primitiveValue: anInteger [ + "Returns the character object, possibly a Character, corresponding +to anInteger. Error if anInteger is not an integer, or not in +0..16r10FFFF. +This is only a primitive for speed. UnicodeCharacter's #value: +method is equivalent to #codePoint: (which is the same for +Character and UnicodeCharacter)." + + + + anInteger isInteger + ifFalse: + [ SystemExceptions.WrongClass signalOn: anInteger mustBe: SmallInteger ] + ifTrue: + [ SystemExceptions.ArgumentOutOfRange + signalOn: anInteger + mustBeBetween: 0 + and: 1114111 ] + ] + + UnicodeCharacter class >> charLookup: aWeakArray at: anInteger value: anUnicodeInteger [ + + + ^ (aWeakArray at: anInteger + 1) ifNil: [ aWeakArray at: anInteger + 1 put: (self primitiveValue: anUnicodeInteger) ] + ] + + UnicodeCharacter class >> lookup: aWeakArray at: anInteger value: anUnicodeInteger [ + + + | index | + index := (anInteger bitShift: -8) + 1. + ^ self + charLookup: ((aWeakArray at: index) ifNil: [ aWeakArray at: index put: (WeakArray new: 256) ]) + at: (anInteger bitAnd: 255) + value: anUnicodeInteger + ] + UnicodeCharacter class >> lookup: anInteger [ + + + | index | + index := (anInteger bitShift: -16) + 1. + ^ self + lookup: (index = 1 + ifTrue: [ FixedTable ] + ifFalse: [ (Table at: index) ifNil: [ Table at: index put: (WeakArray new: 256) ] ]) + at: (anInteger bitAnd: 65535) + value: anInteger + ] + + UnicodeCharacter class >> inlinedLookup: anInteger [ + + + | index array | + index := (anInteger bitShift: -16) + 1. + array := index = 1 + ifTrue: [ FixedTable ] + ifFalse: [ (Table at: index) ifNil: [ Table at: index put: (WeakArray new: 256) ] ]. + index := ((anInteger bitAnd: 65535) bitShift: -8) + 1. + array := (array at: index) ifNil: [ array at: index put: (WeakArray new: 256) ]. + index := (anInteger bitAnd: 255) + 1. + ^ (array at: index) ifNil: [ array at: index put: (self primitiveValue: anInteger) ] + ] + + UnicodeCharacter class >> value: anInteger [ - - anInteger isInteger - ifFalse: - [SystemExceptions.WrongClass signalOn: anInteger mustBe: SmallInteger] - ifTrue: - [SystemExceptions.ArgumentOutOfRange - signalOn: anInteger - mustBeBetween: 0 - and: 1114111] + + ^ self primitiveValue: anInteger ] + * aNumber [ "Returns a String with aNumber occurrences of the receiver." diff --git a/libgst/dict.c b/libgst/dict.c index adb28f6..3106a19 100644 --- a/libgst/dict.c +++ b/libgst/dict.c @@ -176,6 +176,8 @@ OOP _gst_weak_key_identity_dictionary_class = NULL; OOP _gst_weak_value_identity_dictionary_class = NULL; OOP _gst_write_stream_class = NULL; OOP _gst_processor_oop = NULL; +OOP _gst_unicodechar_table_oop = NULL; +OOP _gst_unicodechar_fixedtable_oop = NULL; /* Answer the number of slots that are in a dictionary of OLDNUMFIELDS items after growing it. */ @@ -1017,6 +1019,9 @@ init_smalltalk_dictionary (void) sprintf (fullVersionString, "GNU Smalltalk version %s", VERSION PACKAGE_GIT_REVISION); + instantiate_with (_gst_array_class, 16, &_gst_unicodechar_table_oop); + instantiate_with (_gst_array_class, 256, &_gst_unicodechar_fixedtable_oop); + add_smalltalk ("Smalltalk", _gst_smalltalk_dictionary); add_smalltalk ("Version", _gst_string_new (fullVersionString)); add_smalltalk ("KernelFilePath", _gst_string_new (_gst_kernel_file_path)); @@ -1024,6 +1029,8 @@ init_smalltalk_dictionary (void) add_smalltalk ("SymbolTable", _gst_symbol_table); add_smalltalk ("Processor", _gst_processor_oop); add_smalltalk ("Features", featuresArrayOOP); + add_smalltalk ("UnicodeCharTable", _gst_unicodechar_table_oop); + add_smalltalk ("UnicodeCharFixedTable", _gst_unicodechar_fixedtable_oop); /* Add subspaces */ add_smalltalk ("CSymbols", @@ -1316,6 +1323,10 @@ _gst_init_dictionary_on_image_load (mst_Boolean prim_table_matches) prepare_primitive_numbers_table (); init_runtime_objects (); + + _gst_unicodechar_table_oop = dictionary_at (_gst_smalltalk_dictionary, _gst_intern_string ("UnicodeCharTable")); + _gst_unicodechar_fixedtable_oop = dictionary_at (_gst_smalltalk_dictionary, _gst_intern_string ("UnicodeCharFixedTable")); + return (true); } diff --git a/libgst/dict.h b/libgst/dict.h index 087c5ae..3964966 100644 --- a/libgst/dict.h +++ b/libgst/dict.h @@ -436,6 +436,8 @@ extern OOP _gst_weak_key_identity_dictionary_class ATTRIBUTE_HIDDEN; extern OOP _gst_weak_value_identity_dictionary_class ATTRIBUTE_HIDDEN; extern OOP _gst_write_stream_class ATTRIBUTE_HIDDEN; extern OOP _gst_processor_oop ATTRIBUTE_HIDDEN; +extern OOP _gst_unicodechar_table_oop ATTRIBUTE_HIDDEN; +extern OOP _gst_unicodechar_fixedtable_oop ATTRIBUTE_HIDDEN; /* The size of the indexed instance variables corresponding to the various instanceSpec values declared in gstpriv.h. */ diff --git a/libgst/dict.inl b/libgst/dict.inl index ec5b392..8a5b24d 100644 --- a/libgst/dict.inl +++ b/libgst/dict.inl @@ -590,17 +590,49 @@ char_new (unsigned codePoint) { gst_char charObject; OOP charOOP; + int index; + OOP arrayOOP, oop; if (codePoint <= 127) return CHAR_OOP_AT (codePoint); if UNCOMMON (codePoint > 0x10FFFF) codePoint = 0xFFFD; - charObject = (gst_char) new_instance (_gst_unicode_character_class, &charOOP); + index = codePoint >> 16; + if (index == 0) + arrayOOP = _gst_unicodechar_fixedtable_oop; + else + { + if (IS_NIL (ARRAY_AT (_gst_unicodechar_table_oop, index))) + { + instantiate_with (_gst_array_class, 256, &oop); + _gst_make_oop_weak (oop); + ARRAY_AT_PUT (_gst_unicodechar_table_oop, index, oop); + } - charObject->codePoint = FROM_INT (codePoint); - MAKE_OOP_READONLY (charOOP, true); - return (charOOP); + arrayOOP = ARRAY_AT (_gst_unicodechar_table_oop, index); + } + + index = ((codePoint & 65535) >> 8) + 1; + if (IS_NIL (ARRAY_AT (arrayOOP, index))) + { + instantiate_with (_gst_array_class, 256, &oop); + _gst_make_oop_weak (oop); + ARRAY_AT_PUT (arrayOOP, index, oop); + } + + arrayOOP = ARRAY_AT (arrayOOP, index); + + index = (codePoint & 255) + 1; + if (IS_NIL (charOOP = ARRAY_AT (arrayOOP, index))) + { + charObject = (gst_char) new_instance (_gst_unicode_character_class, &charOOP); + charObject->codePoint = FROM_INT (codePoint); + MAKE_OOP_READONLY (charOOP, true); + ARRAY_AT_PUT(arrayOOP, index, charOOP); + } + + return charOOP; } uintptr_t