From d1cfaed466d5b1d39f359a7855e2bd33b51db0b5 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Fri, 25 May 2018 10:19:25 +0000 Subject: [PATCH] fixed a compiler bug in handling 'super' with multiple messages sent at the same time as in 'super abc + 10' --- moo/kernel/Collect.moo | 23 +++++++++++++++++++++-- moo/kernel/Socket.moo | 8 ++++---- moo/lib/comp.c | 16 +++++++++++++--- moo/lib/exec.c | 2 +- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index 55a6232..1dd69aa 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -302,7 +302,8 @@ class OrderedCollection(SequenceableCollection) method(#class) new: size { - ^self _basicNew initialize: size. + | x | + ^super basicNew initialize: size. } method initialize: size @@ -325,7 +326,7 @@ class OrderedCollection(SequenceableCollection) Exception signal: ('index ' & index asString & ' out of range'). } - method at: index put: obj + method at: index put: obj { | i | i := index + self.firstIndex. @@ -429,6 +430,24 @@ System log(System.Log.FATAL, S'REMOVING ... ', obj, '--->', self.lastIndex, S'\n self.firstIndex := self.firstIndex + shift_count. self.lastIndex := self.lastIndex + shift_count. } + + method insert: obj at: index + { + ## internal use only - index must be between 0 and self size inclusive + + | i start | + if (self size == self.contents size) { self growBy: 8 shiftBy: 8 }. + start := self.firstIndex + index. + i := self.lastIndex. + while (i > start) + { + self.contents at: i put: (self.contents at: i - 1). + i := i - 1. + }. + self.lastIndex := self.lastIndex + 1. + self.contents at: index + self.firstIndex put: obj. + ^obj + } } ## ------------------------------------------------------------------------------- diff --git a/moo/kernel/Socket.moo b/moo/kernel/Socket.moo index 75a11bb..809528e 100644 --- a/moo/kernel/Socket.moo +++ b/moo/kernel/Socket.moo @@ -254,7 +254,7 @@ class Socket(Object) from 'sck' method(#class) __with: handle { ###self addToBeFinalized. - ^(self _basicNew initialize) __open(handle) + ^(self basicNew initialize) __open(handle) } method(#class) family: family type: type @@ -263,7 +263,7 @@ class Socket(Object) from 'sck' ## new is prohibited. so use _basicNew with initialize. ##^(self new) open(family, type, 0) - ^(self _basicNew initialize) open(family, type, 0) + ^(self basicNew initialize) open(family, type, 0) } method close @@ -308,7 +308,7 @@ class SyncSocket(Socket) method(#class) __with: handle { ###self addToBeFinalized. - ^(self _basicNew initialize) __open(handle) + ^(self basicNew initialize) __open(handle) } method(#class) family: family type: type @@ -317,7 +317,7 @@ class SyncSocket(Socket) ## new is prohibited. so use _basicNew with initialize. ##^(self new) open(family, type, 0) - ^(self _basicNew initialize) open(family, type, 0) + ^(self basicNew initialize) open(family, type, 0) } method initialize diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 4ed3a24..89a3b62 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -5409,7 +5409,13 @@ static int compile_message_expression (moo_t* moo, int to_super) noop_pos = moo->c->mth.code.len; if (emit_byte_instruction(moo, BCODE_NOOP) <= -1) return -1; - if (compile_binary_message(moo, to_super) <= -1) return -1; + + /* to_super is reset to 0 because a unary message + * has been sent to super and this binary message + * is following the unary message. + * for instance, in "super abc + 10", + is sent + * to the 'self' which is the result of super abc */ + if (compile_binary_message(moo, 0/*to_super*/) <= -1) return -1; } if (TOKEN_TYPE(moo) == MOO_IOTOK_KEYWORD) @@ -5422,7 +5428,9 @@ static int compile_message_expression (moo_t* moo, int to_super) noop_pos = moo->c->mth.code.len; if (emit_byte_instruction(moo, BCODE_NOOP) <= -1) return -1; - if (compile_keyword_message(moo, to_super) <= -1) return -1; + /* don't pass to_super. pass 0 as it can't be the + * first message after 'super' */ + if (compile_keyword_message(moo, 0/*to_super*/) <= -1) return -1; } break; @@ -5441,7 +5449,9 @@ static int compile_message_expression (moo_t* moo, int to_super) noop_pos = moo->c->mth.code.len; if (emit_byte_instruction(moo, BCODE_NOOP) <= -1) return -1; - if (compile_keyword_message(moo, to_super) <= -1) return -1; + /* don't pass to_super. pass 0 as it can't be the + * first message after 'super' */ + if (compile_keyword_message(moo, 0/*to_super*/) <= -1) return -1; } break; diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 2d86264..9de8e24 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -4001,7 +4001,7 @@ static int send_message (moo_t* moo, moo_oop_char_t selector, int to_super, moo_ mthname.ptr = MOO_OBJ_GET_CHAR_SLOT(selector); mthname.len = MOO_OBJ_GET_SIZE(selector); - method = moo_findmethod (moo, receiver, &mthname, to_super); + method = moo_findmethod(moo, receiver, &mthname, to_super); if (!method) { static moo_ooch_t fbm[] = {