diff --git a/lib/mom/instruction/message_setup.rb b/lib/mom/instruction/message_setup.rb index a53c1e21..7632147d 100644 --- a/lib/mom/instruction/message_setup.rb +++ b/lib/mom/instruction/message_setup.rb @@ -36,16 +36,16 @@ module Mom def build_with(builder) case from = method_source when Parfait::CallableMethod - builder.build { callable << from } + builder.build { callable! << from } when Parfait::CacheEntry builder.build do - cache_entry << from - callable << cache_entry[:cached_method] + cache_entry! << from + callable! << cache_entry[:cached_method] end when Integer builder.build do - arguments << message[:arguments] - callable << arguments[ from ] + arguments! << message[:arguments] + callable! << arguments[ from ] end else raise "unknown source #{method_source.class}:#{method_source}" @@ -64,11 +64,11 @@ module Mom # set the method into the message def build_message_data( builder ) builder.build do - space << Parfait.object_space - next_message << space[:next_message] + space! << Parfait.object_space + next_message! << space[:next_message] #FIXME in a multithreaded future this should be done using lock free compare and swap. - next_message_reg << next_message[:next_message] + next_message_reg! << next_message[:next_message] space[:next_message] << next_message_reg message[:next_message] << next_message diff --git a/lib/mom/instruction/resolve_method.rb b/lib/mom/instruction/resolve_method.rb index df008c4e..6c69ed77 100644 --- a/lib/mom/instruction/resolve_method.rb +++ b/lib/mom/instruction/resolve_method.rb @@ -37,20 +37,20 @@ module Mom cache_entry_ = @cache_entry builder = compiler.code_builder(self) builder.build do - word << name_ - cache_entry << cache_entry_ + word! << name_ + cache_entry! << cache_entry_ - type << cache_entry[:cached_type] - callable_method << type[:methods] + type! << cache_entry[:cached_type] + callable_method! << type[:methods] add_code while_start_label - space << Parfait.object_space + space! << Parfait.object_space space << space[:nil_object] space - callable_method if_zero exit_label - name << callable_method[:name] + name! << callable_method[:name] name - word if_zero ok_label diff --git a/lib/mom/instruction/return_sequence.rb b/lib/mom/instruction/return_sequence.rb index 0da0dce5..08d2c492 100644 --- a/lib/mom/instruction/return_sequence.rb +++ b/lib/mom/instruction/return_sequence.rb @@ -23,17 +23,17 @@ module Mom compiler.reset_regs builder = compiler.code_builder(self) builder.build do - object << message[:return_value] - caller_reg << message[:caller] + object! << message[:return_value] + caller_reg! << message[:caller] caller_reg[:return_value] << object - space << Parfait.object_space - next_message << space[:next_message] + space! << Parfait.object_space + next_message! << space[:next_message] message[:next_message] << next_message space[:next_message] << message end compiler.reset_regs builder.build do - return_address << message[:return_address] + return_address! << message[:return_address] return_address << return_address[ Parfait::Integer.integer_index] message << message[:caller] return_address.function_return diff --git a/lib/risc/builder.rb b/lib/risc/builder.rb index a4c7c798..a66890c0 100644 --- a/lib/risc/builder.rb +++ b/lib/risc/builder.rb @@ -28,17 +28,21 @@ module Risc # make the magic: convert incoming names into registers that have the # type set according to the name (using resolve_type) # anmes are stored, so subsequent calls use the same register - def method_missing(*args) - super if args.length != 1 - name = args[0] + def method_missing(name , *args) + super if args.length != 0 + name = name.to_s return @names[name] if @names.has_key?(name) - if name == :message + if name == "message" reg = Risc.message_reg reg.builder = self - elsif name.to_s.index("label") + return reg + end + if name.index("label") reg = Risc.label( @source , "#{name}_#{object_id}") @source_used = true else + raise "Must create (with !) before using #{name}" unless name[-1] == "!" + name = name[0 ... -1] type = infer_type(name ) reg = @compiler.use_reg( type.object_class.name ) reg.builder = self @@ -90,6 +94,7 @@ module Risc # but since the names in the builder are not variables, we need this method # as it says, swap the two names around. Names must exist def swap_names(left , right) + left , right = left.to_s , right.to_s l = @names[left] r = @names[right] raise "No such name #{left}" unless l @@ -127,9 +132,9 @@ module Risc to.builder = self # esecially div10 comes in without having used builder from.builder = self # not named regs, different regs ==> silent errors build do - space << Parfait.object_space + space! << Parfait.object_space to << space[:next_integer] - integer_tmp << to[:next_integer] + integer_tmp! << to[:next_integer] space[:next_integer] << integer_tmp to[Parfait::Integer.integer_index] << from end diff --git a/lib/risc/builtin/integer.rb b/lib/risc/builtin/integer.rb index 4239ee2f..75d851dc 100644 --- a/lib/risc/builtin/integer.rb +++ b/lib/risc/builtin/integer.rb @@ -14,9 +14,9 @@ module Risc def div4(context) compiler = compiler_for(:Integer,:div4 ,{}) compiler.compiler_builder(compiler.source).build do - integer << message[:receiver] + integer! << message[:receiver] integer.reduce_int - integer_reg << 2 + integer_reg! << 2 integer.op :>> , integer_reg add_new_int("div4", integer , integer_reg) message[:return_value] << integer_reg @@ -52,8 +52,8 @@ module Risc compiler = compiler_for(:Integer, operator ,{other: :Integer}) builder = compiler.compiler_builder(compiler.source) builder.build do - integer << message[:receiver] - integer_reg << message[:arguments] + integer! << message[:receiver] + integer_reg! << message[:arguments] integer_reg << integer_reg[ 1] integer.reduce_int integer_reg.reduce_int @@ -61,7 +61,7 @@ module Risc integer.op :- , integer_reg if_minus false_label if_zero( false_label ) if operator.to_s.length == 1 - object << Parfait.object_space.true_object + object! << Parfait.object_space.true_object branch merge_label add_code false_label object << Parfait.object_space.false_object @@ -89,8 +89,8 @@ module Risc compiler = compiler_for(:Integer, op_sym ,{other: :Integer}) builder = compiler.compiler_builder(compiler.source) builder.build do - integer << message[:receiver] - integer_reg << message[:arguments] + integer! << message[:receiver] + integer_reg! << message[:arguments] integer_reg << integer_reg[ 1] integer.reduce_int integer_reg.reduce_int diff --git a/lib/risc/builtin/object.rb b/lib/risc/builtin/object.rb index 5bfc1f9e..016db9d0 100644 --- a/lib/risc/builtin/object.rb +++ b/lib/risc/builtin/object.rb @@ -9,9 +9,9 @@ module Risc def get_internal_word( context ) compiler = compiler_for(:Object , :get_internal_word ,{at: :Integer}) compiler.compiler_builder(compiler.source).build do - object << message[:receiver] - integer << message[:arguments] - integer << integer_reg[1] + object! << message[:receiver] + integer! << message[:arguments] + integer << integer[1] integer.reduce_int object << object[integer] message[:return_value] << object @@ -25,10 +25,10 @@ module Risc def set_internal_word( context ) compiler = compiler_for(:Object , :set_internal_word , {at: :Integer, :value => :Object} ) compiler.compiler_builder(compiler.source).build do - object << message[:receiver] - integer << message[:arguments] - object_reg << integer[ 2] - integer << integer[ 1] + object! << message[:receiver] + integer! << message[:arguments] + object_reg! << integer[ 2] + integer << integer[1] integer.reduce_int object[integer] << object_reg message[:return_value] << object_reg @@ -56,9 +56,9 @@ module Risc Parfait::NamedList.type_for({}) , Parfait::NamedList.type_for({})) builder = compiler.compiler_builder(compiler.source) builder.build do - space << Parfait.object_space + space! << Parfait.object_space message << space[:next_message] - next_message << message[:next_message] + next_message! << message[:next_message] space[:next_message] << next_message end @@ -128,7 +128,7 @@ module Risc r8 = RegisterValue.new( :r8 , :Message) int = builder.compiler.use_reg(:Integer) builder.build do - integer_reg << message + integer_reg! << message message << r8 add_new_int( "_restore_message", integer_reg , int ) message[:return_value] << int diff --git a/lib/risc/builtin/word.rb b/lib/risc/builtin/word.rb index fa55c778..090eebd6 100644 --- a/lib/risc/builtin/word.rb +++ b/lib/risc/builtin/word.rb @@ -28,8 +28,8 @@ module Risc def get_internal_byte( context) compiler = compiler_for(:Word , :get_internal_byte , {at: :Integer}) compiler.compiler_builder(compiler.source).build do - object << message[:receiver] - integer << message[:arguments] + object! << message[:receiver] + integer! << message[:arguments] integer << integer[1] integer.reduce_int object <= object[integer] @@ -46,11 +46,11 @@ module Risc def set_internal_byte( context ) compiler = compiler_for(:Word, :set_internal_byte , {at: :Integer , :value => :Integer} ) compiler.compiler_builder(compiler.source).build do - word << message[:receiver] - integer << message[:arguments] + word! << message[:receiver] + integer! << message[:arguments] integer << integer[1] - integer_reg << message[:arguments] - integer_obj << integer_reg[2] + integer_reg! << message[:arguments] + integer_obj! << integer_reg[2] integer_reg << integer_reg[2] integer.reduce_int integer_reg.reduce_int diff --git a/test/risc/test_builder.rb b/test/risc/test_builder.rb index adc35735..03120f8c 100644 --- a/test/risc/test_builder.rb +++ b/test/risc/test_builder.rb @@ -17,12 +17,15 @@ module Risc assert_nil @builder.built end def test_alloc_space - reg = @builder.space + reg = @builder.space! assert_equal RegisterValue , reg.class assert_equal :Space , reg.type.class_name end + def test_not_alloc_space + assert_raises {@builder.space} + end def test_next_message - reg = @builder.next_message + reg = @builder.next_message! assert_equal :r1 , reg.symbol assert_equal :Message , reg.type.class_name end @@ -33,31 +36,31 @@ module Risc end def test_returns_built r1 = RegisterValue.new(:r1 , :Space) - built = @builder.build{ space << r1 } + built = @builder.build{ space! << r1 } assert_equal Transfer , built.class end def test_returns_two r1 = RegisterValue.new(:r1 , :Space) - built = @builder.build{ space << r1 ; space << r1} + built = @builder.build{ space! << r1 ; space << r1} assert_equal Transfer , built.next.class end def test_returns_slot r2 = RegisterValue.new(:r2 , :Message) r2.builder = @builder - built = @builder.build{ r2 << space[:next_message] } + built = @builder.build{ r2 << space![:next_message] } assert_equal SlotToReg , built.class assert_equal :r1 , built.array.symbol end def test_returns_slot_reverse r2 = RegisterValue.new(:r2 , :Message) r2.builder = @builder - built = @builder.build{ r2 << space[:next_message] } + built = @builder.build{ r2 << space![:next_message] } assert_equal SlotToReg , built.class assert_equal :r1 , built.array.symbol end def test_reuses_names r1 = RegisterValue.new(:r1 , :Space) - built = @builder.build{ space << r1 ; space << r1} + built = @builder.build{ space! << r1 ; space << r1} assert_equal built.to.symbol , built.next.to.symbol end def test_uses_message_as_message @@ -92,7 +95,7 @@ module Risc assert_equal @label , ret.label end def test_minus - op = @builder.build {space - callable_method} + op = @builder.build {space! - callable_method!} assert_equal OperatorInstruction , op.class assert_equal :- , op.operator assert_equal :Space , op.left.type.class_name diff --git a/test/risc/test_builder1.rb b/test/risc/test_builder1.rb index 6362e5c5..bd79df69 100644 --- a/test/risc/test_builder1.rb +++ b/test/risc/test_builder1.rb @@ -12,17 +12,17 @@ module Risc end def test_inserts_built r1 = RegisterValue.new(:r1 , :Space) - @builder.build{ space << r1 } + @builder.build{ space! << r1 } assert_equal Transfer , @compiler.risc_instructions.next.class assert_equal RegisterValue , @builder.space.class end def test_loads - @builder.build{ space << Parfait.object_space } + @builder.build{ space! << Parfait.object_space } assert_equal LoadConstant , @compiler.risc_instructions.next.class assert_equal RegisterValue , @builder.space.class end def test_two - @builder.build{ space << Parfait.object_space ; integer << 1} + @builder.build{ space! << Parfait.object_space ; integer! << 1} assert_equal LoadConstant , @compiler.risc_instructions.next.class assert_equal LoadData , @compiler.risc_instructions.next(2).class end