From f10c781d0781285f23c7928971d7b606567923ec Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 28 May 2008 00:08:53 +0200 Subject: [PATCH] Refactored structure and accessors for arrayed objects (at the VM level) --- goo/st-array.c | 21 ++++++- goo/st-array.h | 37 +++--------- goo/st-byte-array.c | 42 +++++++------ goo/st-byte-array.h | 9 +-- goo/st-class.c | 2 +- goo/st-descriptor.h | 7 +-- goo/st-float-array.h | 1 - goo/st-float.c | 7 +++ goo/st-generator.c | 4 +- goo/st-hashed-collection.c | 2 +- goo/st-heap-object.c | 20 +++++++ goo/st-heap-object.h | 35 +++++++++++ goo/st-interpreter.c | 2 +- goo/st-large-integer.c | 15 +++++ goo/st-node.c | 2 +- goo/st-object.h | 15 +---- goo/st-primitives.c | 136 ++++++++++++++++++++++++++----------------- goo/st-symbol.c | 32 ++++++++-- goo/st-symbol.h | 1 + goo/st-universe.c | 24 ++++---- st/ArrayedCollection.st | 39 ++++++++++++- st/Association.st | 5 ++ st/Behavior.st | 4 +- st/BlockContext.st | 11 +--- st/Float.st | 2 +- st/LargeInteger.st | 5 ++ st/Object.st | 20 +++++++ st/SequenceableCollection.st | 27 +++++++++ st/SmallInteger.st | 2 +- st/class-defs.st | 1 + 30 files changed, 364 insertions(+), 166 deletions(-) diff --git a/goo/st-array.c b/goo/st-array.c index 7cc90fa..33a6e33 100644 --- a/goo/st-array.c +++ b/goo/st-array.c @@ -35,7 +35,7 @@ allocate_arrayed (st_oop klass, st_smi size) st_oop array = st_allocate_object (ST_TYPE_SIZE (STArray) + size); st_heap_object_initialize_header (array, klass); - ST_ARRAY (array)->size = st_smi_new (size); + ST_ARRAYED_OBJECT (array)->size = st_smi_new (size); st_oop *elements = st_array_element (array, 1); for (st_smi i = 0; i < size; i++) @@ -50,13 +50,32 @@ allocate (st_oop klass) return allocate_arrayed (klass, 0); } +static st_oop +array_copy (st_oop object) +{ + st_oop copy; + st_smi size; + + size = st_smi_value (st_arrayed_object_size (object)); + + copy = st_object_new_arrayed (st_object_class (object), size); + + st_oops_copy (st_array_element (copy, 1), + st_array_element (object, 1), + size); + + return copy; +} + const STDescriptor * st_array_descriptor (void) { static const STDescriptor __descriptor = { .allocate = allocate, .allocate_arrayed = allocate_arrayed, + .copy = array_copy, }; return & __descriptor; } + diff --git a/goo/st-array.h b/goo/st-array.h index 565bb53..2420aee 100644 --- a/goo/st-array.h +++ b/goo/st-array.h @@ -31,42 +31,23 @@ typedef struct { - STHeader header; - - st_oop size; + STArrayedObject header; st_oop elements[]; } STArray; +INLINE st_oop *st_array_element (st_oop object, st_smi i); -INLINE st_oop st_array_size (st_oop object); - -INLINE bool st_array_range_check (st_oop object, st_smi i); - -INLINE st_oop *st_array_element (st_oop object, st_smi i); +INLINE st_oop st_array_at (st_oop object, st_smi i); -INLINE st_oop st_array_at (st_oop object, st_smi i); - -INLINE void st_array_at_put (st_oop object, st_smi i, st_oop value); +INLINE void st_array_at_put (st_oop object, st_smi i, st_oop value); const STDescriptor *st_array_descriptor (void); /* inline definitions */ #define ST_ARRAY(oop) ((STArray *) ST_POINTER (oop)) -INLINE st_oop -st_array_size (st_oop object) -{ - return ST_ARRAY (object)->size; -} - -INLINE bool -st_array_range_check (st_oop object, st_smi i) -{ - return 1 <= i && i <= st_smi_value (st_array_size (object)); -} - /* * returns address of element at index i > 0 */ @@ -76,23 +57,23 @@ st_array_element (st_oop object, st_smi i) /* by obtaining the element address as an offset from `&array->size', * we avoid the slight overhead of subtraction if we had used `&array->elements[i - 1]' instead. */ - return (&ST_ARRAY (object)->size) + i; + return ST_ARRAY (object)->elements + i - 1; } INLINE st_oop st_array_at (st_oop object, st_smi i) { - g_assert (1 <= i && i <= st_array_size (object)); + g_assert (1 <= i && i <= st_arrayed_object_size (object)); - return * st_array_element (object, i); + return ST_ARRAY (object)->elements[i - 1]; } INLINE void st_array_at_put (st_oop object, st_smi i, st_oop value) { - g_assert (1 <= i && i <= st_array_size (object)); + g_assert (1 <= i && i <= st_arrayed_object_size (object)); - *st_array_element (object, i) = value; + ST_ARRAY (object)->elements[i - 1] = value; } #endif /* __ST_ARRAY_H__ */ diff --git a/goo/st-byte-array.c b/goo/st-byte-array.c index b766756..63de692 100644 --- a/goo/st-byte-array.c +++ b/goo/st-byte-array.c @@ -31,28 +31,16 @@ #define ST_BYTE_ARRAY(oop) ((STByteArray *) ST_POINTER (oop)) -st_oop -st_byte_array_size (st_oop object) -{ - return ST_BYTE_ARRAY (object)->size; -} - guchar * st_byte_array_bytes (st_oop object) { return ST_BYTE_ARRAY (object)->bytes; } -bool -st_byte_array_range_check (st_oop object, st_smi i) -{ - return 1 <= i && i <= st_smi_value (st_byte_array_size (object)); -} - guchar st_byte_array_at (st_oop object, st_smi i) { - g_assert (1 <= i && i <= st_smi_value (st_byte_array_size (object))); + g_assert (1 <= i && i <= st_smi_value (st_arrayed_object_size (object))); return st_byte_array_bytes (object)[i - 1]; } @@ -60,7 +48,7 @@ st_byte_array_at (st_oop object, st_smi i) void st_byte_array_at_put (st_oop object, st_smi i, guchar value) { - g_assert (1 <= i && i <= st_smi_value (st_byte_array_size (object))); + g_assert (1 <= i && i <= st_smi_value (st_arrayed_object_size (object))); st_byte_array_bytes (object)[i - 1] = value; } @@ -96,7 +84,7 @@ allocate_arrayed (st_oop klass, st_smi size) st_oop array = st_allocate_object (ST_TYPE_SIZE (STByteArray) + (size_rounded / sizeof (st_oop))); st_heap_object_initialize_header (array, klass); - ST_BYTE_ARRAY (array)->size = st_smi_new (size); + ST_ARRAYED_OBJECT (array)->size = st_smi_new (size); memset (st_byte_array_bytes (array), 0, size_rounded); @@ -119,8 +107,8 @@ st_byte_array_equal (st_oop object, st_oop other) st_object_class (other) != st_symbol_class) return false; - size = st_smi_value (st_byte_array_size (object)); - size_other = st_smi_value (st_byte_array_size (other)); + size = st_smi_value (st_arrayed_object_size (object)); + size_other = st_smi_value (st_arrayed_object_size (other)); if (size != size_other) return false; @@ -134,7 +122,7 @@ st_byte_array_hash (st_oop object) const signed char *p = (signed char *) st_byte_array_bytes (object); guint32 h = *p; - long size = st_smi_value (st_byte_array_size (object)); + long size = st_smi_value (st_arrayed_object_size (object)); if (size == 0 || !h) return h; @@ -146,6 +134,23 @@ st_byte_array_hash (st_oop object) return h; } +static st_oop +byte_array_copy (st_oop object) +{ + st_oop copy; + st_smi size; + + size = st_smi_value (st_arrayed_object_size (object)); + + copy = allocate_arrayed (st_object_class (object), size); + + memcpy (st_byte_array_bytes (copy), + st_byte_array_bytes (object), + size); + + return copy; +} + const STDescriptor * st_byte_array_descriptor (void) @@ -153,6 +158,7 @@ st_byte_array_descriptor (void) static const STDescriptor __descriptor = { .allocate = allocate, .allocate_arrayed = allocate_arrayed, + .copy = byte_array_copy }; return & __descriptor; diff --git a/goo/st-byte-array.h b/goo/st-byte-array.h index c28b054..9c4741d 100644 --- a/goo/st-byte-array.h +++ b/goo/st-byte-array.h @@ -32,25 +32,18 @@ typedef struct { - STHeader header; - - st_oop size; + STArrayedObject header; guchar bytes[]; } STByteArray; - -st_oop st_byte_array_size (st_oop object); - guchar *st_byte_array_bytes (st_oop object); guchar st_byte_array_at (st_oop object, st_smi i); void st_byte_array_at_put (st_oop object, st_smi i, guchar value); -bool st_byte_array_range_check (st_oop object, st_smi i); - bool st_byte_array_equal (st_oop object, st_oop other); guint st_byte_array_hash (st_oop object); diff --git a/goo/st-class.c b/goo/st-class.c index b8b390f..45697e0 100644 --- a/goo/st-class.c +++ b/goo/st-class.c @@ -48,7 +48,7 @@ st_behavior_all_instance_variables (st_oop klass) names = st_behavior_instance_variables (klass); if (names != st_nil) { - size = st_smi_value (st_array_size (names)); + size = st_smi_value (st_arrayed_object_size (names)); for (st_smi i = 1; i <= size; i++) b = g_list_prepend (b, (gpointer) g_strdup (st_byte_array_bytes (st_array_at (names, i)))); } diff --git a/goo/st-descriptor.h b/goo/st-descriptor.h index 76530f7..3f54055 100644 --- a/goo/st-descriptor.h +++ b/goo/st-descriptor.h @@ -45,12 +45,11 @@ typedef enum typedef struct { - STFormat format; + st_oop (* allocate) (st_oop klass); - /* allocation */ - st_oop (*allocate) (st_oop klass); + st_oop (* allocate_arrayed) (st_oop klass, st_smi size); - st_oop (*allocate_arrayed) (st_oop klass, st_smi size); + st_oop (* copy) (st_oop object); } STDescriptor; diff --git a/goo/st-float-array.h b/goo/st-float-array.h index 11b52c5..bbf4bee 100644 --- a/goo/st-float-array.h +++ b/goo/st-float-array.h @@ -33,7 +33,6 @@ typedef struct { STHeader header; - st_oop size; double elements[]; } STFloatArray; diff --git a/goo/st-float.c b/goo/st-float.c index 3f62555..444cc62 100644 --- a/goo/st-float.c +++ b/goo/st-float.c @@ -47,6 +47,12 @@ st_float_new (double value) return f; } +static st_oop +float_copy (st_oop object) +{ + return st_float_new (st_float_value (object)); +} + const STDescriptor * st_float_descriptor (void) { @@ -55,6 +61,7 @@ st_float_descriptor (void) static const STDescriptor __descriptor = { .allocate = allocate, .allocate_arrayed = NULL, + .copy = float_copy }; return & __descriptor; diff --git a/goo/st-generator.c b/goo/st-generator.c index 1bfcd4d..0267661 100644 --- a/goo/st-generator.c +++ b/goo/st-generator.c @@ -1709,7 +1709,7 @@ print_literals (st_oop literals) printf ("literals: "); - for (int i = 1; i <= st_smi_value (st_array_size (literals)); i++) { + for (int i = 1; i <= st_smi_value (st_arrayed_object_size (literals)); i++) { st_oop lit = st_array_at (literals, i); @@ -1738,7 +1738,7 @@ st_print_method (st_oop method) literals = st_method_literals (method); bytecodes = (guchar *) st_byte_array_bytes (st_method_bytecode (method)); - size = st_byte_array_size (st_method_bytecode (method)); + size = st_arrayed_object_size (st_method_bytecode (method)); print_bytecodes (literals, bytecodes, size); diff --git a/goo/st-hashed-collection.c b/goo/st-hashed-collection.c index b02a2a4..570a738 100644 --- a/goo/st-hashed-collection.c +++ b/goo/st-hashed-collection.c @@ -35,7 +35,7 @@ #define DEFAULT_CAPACITY 5 #define TALLY(collection) (ST_HASHED_COLLECTION (collection)->tally) #define ARRAY(collection) (ST_HASHED_COLLECTION (collection)->array) -#define ARRAY_SIZE(array) (st_smi_value (st_array_size (array))) +#define ARRAY_SIZE(array) (st_smi_value (st_arrayed_object_size (array))) #define ST_HASHED_COLLECTION(oop) ((STHashedCollection *) ST_POINTER (oop)) diff --git a/goo/st-heap-object.c b/goo/st-heap-object.c index f0a9001..b814e08 100644 --- a/goo/st-heap-object.c +++ b/goo/st-heap-object.c @@ -113,13 +113,33 @@ allocate (st_oop klass) return object; } +static st_oop +object_copy (st_oop object) +{ + st_oop klass; + st_oop copy; + st_smi instance_size; + + klass = st_heap_object_class (object); + instance_size = st_smi_value (st_behavior_instance_size (klass)); + copy = st_object_new (klass); + + st_oops_copy (st_heap_object_body (copy), + st_heap_object_body (object), + instance_size); + + return copy; +} + const STDescriptor * st_heap_object_descriptor (void) { static const STDescriptor __descriptor = { .allocate = allocate, .allocate_arrayed = NULL, + .copy = object_copy, }; return & __descriptor; } + diff --git a/goo/st-heap-object.h b/goo/st-heap-object.h index 7aeeb63..f2e4b20 100644 --- a/goo/st-heap-object.h +++ b/goo/st-heap-object.h @@ -28,6 +28,7 @@ #include #include #include +#include /* Every heap-allocated object starts with this layout */ /* format of mark oop @@ -49,6 +50,13 @@ typedef struct st_oop fields[]; } STHeader; +typedef struct +{ + STHeader header; + st_smi size; + +} STArrayedObject; + extern int st_current_hash; @@ -78,6 +86,8 @@ enum #define st_heap_object_class(oop) (ST_POINTER (oop)->klass) #define st_heap_object_body(oop) (ST_POINTER (oop)->fields) +#define ST_ARRAYED_OBJECT(oop) ((STArrayedObject *) ST_POINTER (oop)) + void st_heap_object_initialize_header (st_oop object, st_oop klass); void st_heap_object_initialize_body (st_oop object, st_smi instance_size); @@ -96,6 +106,31 @@ bool st_heap_object_nonpointer (st_oop object); void st_heap_object_set_nonpointer (st_oop object, bool nonpointer); + +INLINE st_oop st_arrayed_object_size (st_oop object); + +INLINE bool st_arrayed_object_range_check (st_oop object, st_smi i); + + const STDescriptor *st_heap_object_descriptor (void) G_GNUC_CONST; + +INLINE const STDescriptor * +st_heap_object_descriptor_for_object (st_oop object) +{ + return st_descriptors[st_heap_object_format (object)]; +} + +INLINE st_oop +st_arrayed_object_size (st_oop object) +{ + return ST_ARRAYED_OBJECT (object)->size; +} + +INLINE bool +st_arrayed_object_range_check (st_oop object, st_smi i) +{ + return 1 <= i && i <= st_smi_value (st_arrayed_object_size (object)); +} + #endif /* __ST_HEAP_OBJECT_H__ */ diff --git a/goo/st-interpreter.c b/goo/st-interpreter.c index 46912a5..cbec285 100644 --- a/goo/st-interpreter.c +++ b/goo/st-interpreter.c @@ -663,7 +663,7 @@ st_interpreter_main (STExecutionState *es) ip += 3; - literal_index = st_smi_value (st_array_size (st_method_literals (es->method))) - 1; + literal_index = st_smi_value (st_arrayed_object_size (st_method_literals (es->method))) - 1; method = st_interpreter_lookup_method (es, st_behavior_superclass (es->literals[literal_index])); diff --git a/goo/st-large-integer.c b/goo/st-large-integer.c index d8b92f3..63ed7e6 100644 --- a/goo/st-large-integer.c +++ b/goo/st-large-integer.c @@ -335,12 +335,27 @@ allocate (st_oop klass) return allocate_with_value (klass, NULL); } + +static st_oop +large_integer_copy (st_oop object) +{ + mp_int value; + int result; + + result = mp_init_copy (&value, VALUE (object)); + if (result != MP_OKAY) + g_assert_not_reached (); + + return st_large_integer_new (&value); +} + const STDescriptor * st_large_integer_descriptor (void) { static const STDescriptor __descriptor = { .allocate = allocate, .allocate_arrayed = NULL, + .copy = large_integer_copy, }; return & __descriptor; diff --git a/goo/st-node.c b/goo/st-node.c index 13c6261..8ef31b4 100644 --- a/goo/st-node.c +++ b/goo/st-node.c @@ -77,7 +77,7 @@ print_tuple (st_oop tuple) { int size; - size = st_smi_value (st_array_size (tuple)); + size = st_smi_value (st_arrayed_object_size (tuple)); printf ("#("); for (int i = 1; i <= size; i++) { diff --git a/goo/st-object.h b/goo/st-object.h index 2698942..ed1b9f4 100644 --- a/goo/st-object.h +++ b/goo/st-object.h @@ -44,8 +44,7 @@ INLINE st_oop st_object_class (st_oop object); bool st_object_equal (st_oop object, st_oop other); guint st_object_hash (st_oop object); - -char *st_object_printString (st_oop object); +char *st_object_printString (st_oop object); /* inline definitions */ @@ -85,18 +84,6 @@ st_object_class (st_oop object) return st_heap_object_class (object); } -INLINE const STDescriptor * -st_object_descriptor (st_oop object) -{ - if (G_UNLIKELY (st_object_is_smi (object))) - g_assert_not_reached (); - - if (G_UNLIKELY (st_object_is_smi (object))) - g_assert_not_reached (); - - return st_descriptors[st_heap_object_format (object)]; -} - INLINE bool st_object_is_symbol (st_oop object) { diff --git a/goo/st-primitives.c b/goo/st-primitives.c index bd12419..334f9f5 100644 --- a/goo/st-primitives.c +++ b/goo/st-primitives.c @@ -50,10 +50,28 @@ INLINE st_smi pop_integer (STExecutionState *es) { st_oop object = ST_STACK_POP (es); - - set_success (es, st_object_is_smi (object)); + + if (G_LIKELY (st_object_is_smi (object))) + return st_smi_value (object); + + set_success (es, false); + + return 0; +} + +INLINE st_smi +pop_integer32 (STExecutionState *es) +{ + st_oop object = ST_STACK_POP (es); + + if (G_LIKELY (st_object_is_smi (object))) + return st_smi_value (object); + else if (st_object_class (object) == st_large_integer_class) + return (st_smi) mp_get_int (st_large_integer_value (object)); + + set_success (es, false); - return st_smi_value (object); + return 0; } static void @@ -73,7 +91,7 @@ SmallInteger_add (STExecutionState *es) } static void -SmallInteger_minus (STExecutionState *es) +SmallInteger_sub (STExecutionState *es) { st_smi y = pop_integer (es); st_smi x = pop_integer (es); @@ -691,6 +709,25 @@ LargeInteger_bitXor (STExecutionState *es) } static void +LargeInteger_bitShift (STExecutionState *es) +{ + st_oop receiver = pop_large_integer (es); + st_smi displacement = pop_integer32 (es); + st_oop result; + bool error; + + if (es->success) + result = st_large_integer_bitshift (receiver, displacement, &error); + + set_success (es, error == false); + + if (es->success) + ST_STACK_PUSH (es, result); + else + ST_STACK_UNPOP (es, 2); +} + +static void LargeInteger_asFloat (STExecutionState *es) { st_oop receiver = pop_large_integer (es); @@ -755,7 +792,7 @@ Float_add (STExecutionState *es) } static void -Float_minus (STExecutionState *es) +Float_sub (STExecutionState *es) { st_oop y = pop_float (es); st_oop x = pop_float (es); @@ -1132,7 +1169,11 @@ print_backtrace (STExecutionState *es) receiver = st_method_context_receiver (home); selector = (char*) st_byte_array_bytes (st_method_selector (st_method_context_method (home))); - klass = (char*) st_byte_array_bytes (st_class_name (st_object_class (receiver))); + + if (st_object_class (st_object_class (receiver)) == st_metaclass_class) + klass = g_strdup_printf ("%s class", (char *) st_byte_array_bytes (st_class_name (receiver))); + else + klass = (char*) st_byte_array_bytes (st_class_name (st_object_class (receiver))); printf ("%s>>#%s", klass, selector); if (st_object_class (context) == st_block_context_class) @@ -1181,10 +1222,12 @@ Object_identityHash (STExecutionState *es) object = ST_STACK_POP (es); - if (st_object_is_smi (object)) + if (st_object_is_heap (object)) + result = st_smi_new (st_heap_object_hash (object)); + else if (st_object_is_smi (object)) result = st_smi_new (st_smi_hash (object)); else - result = st_smi_new (st_heap_object_hash (object)); + result = st_smi_new (st_character_hash (object)); ST_STACK_PUSH (es, result); } @@ -1192,7 +1235,17 @@ Object_identityHash (STExecutionState *es) static void Object_copy (STExecutionState *es) { - g_assert_not_reached (); + st_oop receiver; + st_oop copy; + + receiver = ST_STACK_POP (es); + + if (st_object_is_heap (receiver)) + copy = st_heap_object_descriptor_for_object (receiver)->copy (receiver); + else + copy = receiver; + + ST_STACK_PUSH (es, copy); } static void @@ -1255,7 +1308,7 @@ Object_perform_withArguments (STExecutionState *es) else method = st_method_context_method (es->context); - array_size = st_smi_value (st_array_size (array)); + array_size = st_smi_value (st_arrayed_object_size (array)); set_success (es, (es->sp + array_size - 1) < st_method_stack_depth (method)); if (es->success) { @@ -1311,7 +1364,7 @@ Behavior_newSize (STExecutionState *es) st_smi size; st_oop instance; - size = pop_integer (es); + size = pop_integer32 (es); klass = ST_STACK_POP (es); instance = st_object_new_arrayed (klass, size); @@ -1326,7 +1379,7 @@ Array_at (STExecutionState *es) st_oop receiver = ST_STACK_POP (es); st_oop result; - if (!st_array_range_check (receiver, index)) { + if (!st_arrayed_object_range_check (receiver, index)) { set_success (es, false); ST_STACK_UNPOP (es, 2); return; @@ -1341,10 +1394,10 @@ static void Array_at_put (STExecutionState *es) { st_oop object = ST_STACK_POP (es); - st_smi index = pop_integer (es); + st_smi index = pop_integer32 (es); st_oop receiver = ST_STACK_POP (es); - if (!st_array_range_check (receiver, index)) { + if (!st_arrayed_object_range_check (receiver, index)) { set_success (es, false); ST_STACK_UNPOP (es, 3); return; @@ -1355,7 +1408,6 @@ Array_at_put (STExecutionState *es) ST_STACK_PUSH (es, object); } - static void Array_size (STExecutionState *es) { @@ -1363,14 +1415,14 @@ Array_size (STExecutionState *es) object = ST_STACK_POP (es); - ST_STACK_PUSH (es, st_array_size (object)); + ST_STACK_PUSH (es, st_arrayed_object_size (object)); } static void ByteArray_at (STExecutionState *es) { - st_smi index = pop_integer (es); + st_smi index = pop_integer32 (es); st_oop receiver = ST_STACK_POP (es); st_oop result; @@ -1379,7 +1431,7 @@ ByteArray_at (STExecutionState *es) return; } - if (!st_byte_array_range_check (receiver, index)) { + if (!st_arrayed_object_range_check (receiver, index)) { set_success (es, false); ST_STACK_UNPOP (es, 2); return; @@ -1394,7 +1446,7 @@ static void ByteArray_at_put (STExecutionState *es) { st_smi byte = pop_integer (es); - st_smi index = pop_integer (es); + st_smi index = pop_integer32 (es); st_oop receiver = ST_STACK_POP (es); if (!es->success) { @@ -1402,7 +1454,7 @@ ByteArray_at_put (STExecutionState *es) return; } - if (!st_byte_array_range_check (receiver, index)) { + if (!st_arrayed_object_range_check (receiver, index)) { set_success (es, false); ST_STACK_UNPOP (es, 3); return; @@ -1420,13 +1472,13 @@ ByteArray_size (STExecutionState *es) object = ST_STACK_POP (es); - ST_STACK_PUSH (es, st_byte_array_size (object)); + ST_STACK_PUSH (es, st_arrayed_object_size (object)); } static void ByteString_at (STExecutionState *es) { - st_smi index = pop_integer (es); + st_smi index = pop_integer32 (es); st_oop receiver = ST_STACK_POP (es); st_oop character; char *charptr; @@ -1436,7 +1488,7 @@ ByteString_at (STExecutionState *es) return; } - if (G_UNLIKELY (!st_byte_array_range_check (receiver, index))) { + if (G_UNLIKELY (!st_arrayed_object_range_check (receiver, index))) { set_success (es, false); ST_STACK_UNPOP (es, 2); return; @@ -1573,7 +1625,7 @@ ByteString_hash (STExecutionState *es) static void WideString_at (STExecutionState *es) { - st_smi index = pop_integer (es); + st_smi index = pop_integer32 (es); st_oop receiver = ST_STACK_POP (es); st_oop character; @@ -1582,7 +1634,7 @@ WideString_at (STExecutionState *es) return; } - if (!st_word_array_range_check (receiver, index)) { + if (!st_arrayed_object_range_check (receiver, index)) { set_success (es, false); ST_STACK_UNPOP (es, 2); return; @@ -1597,7 +1649,7 @@ static void WideString_at_put (STExecutionState *es) { st_oop character = ST_STACK_POP (es); - st_smi index = pop_integer (es); + st_smi index = pop_integer32 (es); st_oop receiver = ST_STACK_POP (es); if (!es->success) { @@ -1607,7 +1659,7 @@ WideString_at_put (STExecutionState *es) set_success (es, st_object_class (character) == st_character_class); - if (!st_word_array_range_check (receiver, index)) { + if (!st_arrayed_object_range_check (receiver, index)) { set_success (es, false); ST_STACK_UNPOP (es, 3); return; @@ -1625,7 +1677,7 @@ WordArray_size (STExecutionState *es) receiver = ST_STACK_POP (es); - ST_STACK_PUSH (es, st_word_array_size (receiver)); + ST_STACK_PUSH (es, st_arrayed_object_size (receiver)); } INLINE void @@ -1661,24 +1713,6 @@ BlockContext_value (STExecutionState *es) } static void -BlockContext_valueColon (STExecutionState *es) -{ - activate_block_context (es); -} - -static void -BlockContext_value_value (STExecutionState *es) -{ - activate_block_context (es); -} - -static void -BlockContext_value_value_value (STExecutionState *es) -{ - activate_block_context (es); -} - -static void BlockContext_valueWithArguments (STExecutionState *es) { st_oop block; @@ -1694,7 +1728,7 @@ BlockContext_valueWithArguments (STExecutionState *es) } argcount = st_smi_value (st_block_context_argcount (block)); - if (argcount != st_smi_value (st_array_size (values))) { + if (argcount != st_smi_value (st_arrayed_object_size (values))) { st_interpreter_set_success (es, false); return; } @@ -1744,7 +1778,7 @@ Character_characterFor (STExecutionState *es) const STPrimitive st_primitives[] = { { "SmallInteger_add", SmallInteger_add }, - { "SmallInteger_minus", SmallInteger_minus }, + { "SmallInteger_sub", SmallInteger_sub }, { "SmallInteger_lt", SmallInteger_lt }, { "SmallInteger_gt", SmallInteger_gt }, { "SmallInteger_le", SmallInteger_le }, @@ -1777,11 +1811,12 @@ const STPrimitive st_primitives[] = { { "LargeInteger_bitOr", LargeInteger_bitOr }, { "LargeInteger_bitXor", LargeInteger_bitXor }, { "LargeInteger_bitAnd", LargeInteger_bitAnd }, + { "LargeInteger_bitShift", LargeInteger_bitShift }, { "LargeInteger_printString", LargeInteger_printString }, { "LargeInteger_asFloat", LargeInteger_asFloat }, { "Float_add", Float_add }, - { "Float_minus", Float_minus }, + { "Float_sub", Float_sub }, { "Float_lt", Float_lt }, { "Float_gt", Float_gt }, { "Float_le", Float_le }, @@ -1840,9 +1875,6 @@ const STPrimitive st_primitives[] = { { "Character_characterFor", Character_characterFor }, { "BlockContext_value", BlockContext_value }, - { "BlockContext_valueColon", BlockContext_valueColon }, - { "BlockContext_value_value", BlockContext_value_value }, - { "BlockContext_value_value_value", BlockContext_value_value_value }, { "BlockContext_valueWithArguments", BlockContext_valueWithArguments }, }; diff --git a/goo/st-symbol.c b/goo/st-symbol.c index 0044b3e..12d9494 100644 --- a/goo/st-symbol.c +++ b/goo/st-symbol.c @@ -25,11 +25,28 @@ #include "st-symbol.h" #include "st-hashed-collection.h" #include "st-byte-array.h" +#include "st-word-array.h" #include "st-object.h" #include +char * +st_string_bytes (st_oop string) +{ + if (st_object_class (string) == st_string_class) { + return g_strdup ((const char *) st_byte_array_bytes (string)); + + } else if (st_object_class (string) == st_wide_string_class) { + return g_ucs4_to_utf8 (st_word_array_element (string, 1), + st_smi_value (st_arrayed_object_size (string)), + NULL, NULL, NULL); + } else { + g_assert_not_reached (); + return NULL; + } +} + bool st_symbol_equal (st_oop object, st_oop other) { @@ -45,11 +62,13 @@ st_symbol_equal (st_oop object, st_oop other) static st_oop string_new (st_oop klass, const char *bytes) { - int len = strlen (bytes); - - st_oop string = st_object_new_arrayed (klass, len); - - guchar *data = st_byte_array_bytes (string); + st_oop string; + guchar *data; + int len; + + len = strlen (bytes); + string = st_object_new_arrayed (klass, len); + data = st_byte_array_bytes (string); memcpy (data, bytes, len); @@ -66,10 +85,11 @@ st_oop st_symbol_new (const char *bytes) { st_oop element = st_set_like (st_symbol_table, st_string_new (bytes)); + st_oop symbol; if (element == st_nil) { - st_oop symbol = string_new (st_symbol_class, bytes); + symbol = string_new (st_symbol_class, bytes); st_set_add (st_symbol_table, symbol); diff --git a/goo/st-symbol.h b/goo/st-symbol.h index 966b3e4..0804289 100644 --- a/goo/st-symbol.h +++ b/goo/st-symbol.h @@ -36,6 +36,7 @@ st_oop st_symbol_new (const char *bytes); bool st_symbol_equal (st_oop object, st_oop other); +char *st_string_bytes (st_oop string); #endif /* __ST_SYMBOL_H__ */ diff --git a/goo/st-universe.c b/goo/st-universe.c index 37bf3d6..0c5979d 100644 --- a/goo/st-universe.c +++ b/goo/st-universe.c @@ -33,6 +33,7 @@ #include "st-word-array.h" #include "st-small-integer.h" #include "st-hashed-collection.h" +#include "st-large-integer.h" #include "st-symbol.h" #include "st-universe.h" #include "st-heap-object.h" @@ -68,14 +69,14 @@ st_oop st_association_class = 0, st_string_class = 0, st_symbol_class = 0, - st_wide_string_class = 0, + st_wide_string_class = 0, st_compiled_method_class = 0, st_method_context_class = 0, st_block_context_class = 0, st_selector_doesNotUnderstand = 0, - st_selector_mustBeBoolean = 0, - st_selector_startupSystem = 0, - st_selector_cannotReturn = 0; + st_selector_mustBeBoolean = 0, + st_selector_startupSystem = 0, + st_selector_cannotReturn = 0; @@ -173,15 +174,10 @@ initialize_class (const char *name, st_behavior_superclass (metaclass) = st_dictionary_at (st_smalltalk, st_symbol_new ("Class")); } else { - - superclass = st_global_get (super_name); - if (superclass == st_nil) { - g_debug (name); + if (superclass == st_nil) g_assert (superclass != st_nil); - } - klass = st_global_get (name); if (klass == st_nil) @@ -469,7 +465,6 @@ init_specials (void) st_selector_mustBeBoolean = st_symbol_new ("mustBeBoolean"); st_selector_startupSystem = st_symbol_new ("startupSystem"); st_selector_cannotReturn = st_symbol_new ("cannotReturn"); - } // RESERVE 500 MB worth of virtual address space @@ -497,14 +492,15 @@ st_bootstrap_universe (void) st_descriptors[ST_FORMAT_BYTE_ARRAY] = st_byte_array_descriptor (); st_descriptors[ST_FORMAT_WORD_ARRAY] = st_word_array_descriptor (); st_descriptors[ST_FORMAT_FLOAT] = st_float_descriptor (); + st_descriptors[ST_FORMAT_LARGE_INTEGER] = st_large_integer_descriptor (); st_nil = create_nil_object (); st_object_class_ = class_new (ST_FORMAT_OBJECT, 0); st_undefined_object_class = class_new (ST_FORMAT_OBJECT, 0); - st_metaclass_class = class_new (ST_FORMAT_OBJECT, 0); + st_metaclass_class = class_new (ST_FORMAT_OBJECT, INSTANCE_SIZE_METACLASS); st_behavior_class = class_new (ST_FORMAT_OBJECT, 0); - st_class_class_ = class_new (ST_FORMAT_OBJECT, 0); + st_class_class_ = class_new (ST_FORMAT_OBJECT, INSTANCE_SIZE_CLASS); st_smi_class = class_new (ST_FORMAT_OBJECT, 0); st_large_integer_class = class_new (ST_FORMAT_LARGE_INTEGER, 0); st_character_class = class_new (ST_FORMAT_OBJECT, 0); @@ -515,8 +511,8 @@ st_bootstrap_universe (void) st_dictionary_class = class_new (ST_FORMAT_OBJECT, INSTANCE_SIZE_DICTIONARY); st_set_class = class_new (ST_FORMAT_OBJECT, INSTANCE_SIZE_SET); st_byte_array_class = class_new (ST_FORMAT_BYTE_ARRAY, 0); - st_string_class = class_new (ST_FORMAT_BYTE_ARRAY, 0); st_symbol_class = class_new (ST_FORMAT_BYTE_ARRAY, 0); + st_string_class = class_new (ST_FORMAT_BYTE_ARRAY, 0); st_wide_string_class = class_new (ST_FORMAT_WORD_ARRAY, 0); st_association_class = class_new (ST_FORMAT_OBJECT, INSTANCE_SIZE_ASSOCIATION); st_compiled_method_class = class_new (ST_FORMAT_OBJECT, 0); diff --git a/st/ArrayedCollection.st b/st/ArrayedCollection.st index 7c5c82c..134ecb6 100644 --- a/st/ArrayedCollection.st +++ b/st/ArrayedCollection.st @@ -1,4 +1,41 @@ + +"instance creation" + +ArrayedCollection classMethod! +new + ^ self new: 0! + +ArrayedCollection classMethod! +with: anObject + ^ (self new: 1) + at: 1 put: anObject; + yourself! + +ArrayedCollection classMethod! +with: firstObject with: secondObject + ^ (self new: 2) + at: 1 put: firstObject; + at: 2 put: secondObject; + yourself! + +ArrayedCollection classMethod! +with: firstObject with: secondObject with: thirdObject + ^ (self new: 3) + at: 1 put: firstObject; + at: 2 put: secondObject; + at: 3 put: thirdObject; + yourself! + +ArrayedCollection classMethod! +with: firstObject with: secondObject with: thirdObject with: fourthObject + ^ (self new: 4) + at: 1 put: firstObject; + at: 2 put: secondObject; + at: 3 put: thirdObject; + at: 4 put: fourthObject; + yourself! + "accessing" ArrayedCollection method! @@ -13,4 +50,4 @@ add: anObject ArrayedCollection method! add: anObject - ^ self shouldNotImplement! \ No newline at end of file + ^ self shouldNotImplement! diff --git a/st/Association.st b/st/Association.st index 6572bd8..bdca083 100644 --- a/st/Association.st +++ b/st/Association.st @@ -47,6 +47,11 @@ value: aValue value := aValue! +"comparing" + + + + "printing" Association method! diff --git a/st/Behavior.st b/st/Behavior.st index 35b59eb..00cfcd6 100644 --- a/st/Behavior.st +++ b/st/Behavior.st @@ -28,9 +28,7 @@ name Metaclass method! name - instanceClass = nil - ifTrue: [^ 'a Metaclass'] - ifFalse: [^ instanceClass name , ' class']! + ^ instanceClass name , ' class'! Behavior method! format diff --git a/st/BlockContext.st b/st/BlockContext.st index 875e9fc..daa7bfc 100644 --- a/st/BlockContext.st +++ b/st/BlockContext.st @@ -8,22 +8,17 @@ value BlockContext method! value: argument - + self primitiveFailed! BlockContext method! value: firstArgument value: secondArgument - + self primitiveFailed! BlockContext method! value: firstArgument value: secondArgument value: thirdArgument - - self primitiveFailed! - -BlockContext method! -valueWithArguments: anArray - + self primitiveFailed! BlockContext method! diff --git a/st/Float.st b/st/Float.st index 3c40753..7e79af1 100644 --- a/st/Float.st +++ b/st/Float.st @@ -93,7 +93,7 @@ Float method! Float method! - aNumber - + ^ super - aNumber! Float method! diff --git a/st/LargeInteger.st b/st/LargeInteger.st index b4484a9..c5dfbb9 100644 --- a/st/LargeInteger.st +++ b/st/LargeInteger.st @@ -83,6 +83,11 @@ bitXor: aNumber ^ super bitXor: aNumber! +LargeInteger method! +bitShift: aNumber + + ^ super bitShift: aNumber! + "coercion" diff --git a/st/Object.st b/st/Object.st index fa52e90..bbfaf75 100644 --- a/st/Object.st +++ b/st/Object.st @@ -170,6 +170,14 @@ isFraction "error handling" Object method! +assert: aBlock + aBlock value or: [ self error: 'assertion failed' ]! + +Object method! +assert: aBlock description: aString + aBlock value or: [ self error: aString ]! + +Object method! error: aString ! @@ -204,6 +212,18 @@ notYetImplemented self error: 'This method is not yet implemented'! +"copying" + +Object method! +copy + ^ self basicCopy! + +Object method! +basicCopy + + self primitiveFailed! + + "private" Object method! diff --git a/st/SequenceableCollection.st b/st/SequenceableCollection.st index 6c64977..17414ed 100644 --- a/st/SequenceableCollection.st +++ b/st/SequenceableCollection.st @@ -21,6 +21,33 @@ SequenceableCollection method! ^ collection! +"comparing" + +SequenceableCollection method! += aCollection + | i | + + self size = aCollection size + ifFalse: [ ^ false ]. + + i := 1. + self do: [ :element | + element = (aCollection at: i) ifFalse: [ ^ false ]. + i := i + 1 ]. + + ^ true! + +SequenceableCollection method! +hash + | hash | + + hash := 11111111111111111. + + self do: [ :element | + hash := hash bitXor: ((hash bitShift: 5) + element hash + (hash bitShift: -2))]. + + ^ hash! + "accessing" SequenceableCollection method! diff --git a/st/SmallInteger.st b/st/SmallInteger.st index 580b300..4ff1406 100644 --- a/st/SmallInteger.st +++ b/st/SmallInteger.st @@ -42,7 +42,7 @@ SmallInteger method! SmallInteger method! - aNumber - + ^ super - aNumber! SmallInteger method! diff --git a/st/class-defs.st b/st/class-defs.st index dc272a8..bdb73f7 100644 --- a/st/class-defs.st +++ b/st/class-defs.st @@ -100,6 +100,7 @@ Class named: 'Association' instanceVariableNames: 'key value' classVariableNames: ''! + "Streams" Class named: 'Stream' -- 2.11.4.GIT