diff --git a/lib/risc/builder.rb b/lib/risc/builder.rb index 32db670d..26b5b54b 100644 --- a/lib/risc/builder.rb +++ b/lib/risc/builder.rb @@ -24,27 +24,6 @@ module Risc @source_used = false end - # Infer the type from a symbol. In the simplest case the symbol is the class name. - # But in building, sometimes variations are needed, so next_message or caller work - # too (and both return "Message") - # A general "_reg"/"_obj"/"_const" or "_tmp" at the end of the name will be removed - # An error is raised if the symbol/object can not be inferred - def infer_type( name ) - as_string = name.to_s - parts = as_string.split("_") - if( ["reg" , "obj" , "tmp" , "self" , "const", "1" , "2"].include?( parts.last ) ) - parts.pop - as_string = parts.join("_") - end - as_string = "word" if as_string == "name" - as_string = "message" if as_string == "next_message" - as_string = "message" if as_string == "caller" - sym = as_string.camelise.to_sym - clazz = Parfait.object_space.get_class_by_name(sym) - raise "Not implemented/found object #{name}:#{sym}" unless clazz - return clazz.instance_type - end - def if_zero( label ) @source_used = true add_code Risc::IsZero.new(@source , label) @@ -93,18 +72,17 @@ module Risc def load_object(object) @compiler.load_object(object) end + # for some methods that return an integer it is beneficial to pre allocate the # integer and store it in the return value. That is what this function does. # # Those (builtin) methods, mostly syscall wrappers then go on to do this and that # clobbering registers and so the allocate and even move would be difficult. # We sidestep all that by pre-allocating. + # + # Note: this was pre register-allocate. clobbering is history, maybe revisit? def prepare_int_return - integer_tmp = allocate_int - reset_names - build do - message[:return_value] << integer_tmp - end + message[:return_value] << allocate_int end # allocate int fetches a new int, for sure. It is a builder method, rather than @@ -129,16 +107,17 @@ module Risc cont_label = Risc.label("continue int allocate" , "cont_label") factory = load_object Parfait.object_space.get_factory_for(:Integer) null = load_object Parfait.object_space.nil_object + int = nil build do null.op :- , factory[:next_object] if_not_zero cont_label factory[:next_object] << factory[:reserve] call_get_more - integer << factory[:next_object] add_code cont_label - factory[:next_object] << integer[:next_integer] + int = factory[:next_object].to_reg + factory[:next_object] << int[:next_integer] end - integer_tmp! + int end # Call_get_more calls the method get_more on the factory (see there). diff --git a/test/risc/test_builder1.rb b/test/risc/test_builder1.rb index 078f3d85..fcc93101 100644 --- a/test/risc/test_builder1.rb +++ b/test/risc/test_builder1.rb @@ -14,7 +14,7 @@ module Risc end def test_allocate_returns int = @builder.allocate_int - assert_equal :integer_tmp , int.symbol + assert int.symbol.to_s.split(".").first.start_with?("id_") end def test_allocate_len int = @builder.allocate_int diff --git a/test/risc/test_builder2.rb b/test/risc/test_builder2.rb deleted file mode 100644 index 1b56fc79..00000000 --- a/test/risc/test_builder2.rb +++ /dev/null @@ -1,51 +0,0 @@ -require_relative "../helper" - -module Risc - class TestBuilderInfer < MiniTest::Test - - def setup - Parfait.boot!(Parfait.default_test_options) - Risc.boot! - method = FakeCallable.new - @compiler = Risc::MethodCompiler.new( method, SlotMachine::Label.new( "source_name", "return_label") ) - @builder = @compiler.builder(method) - end - def test_list - assert_equal :List , @builder.infer_type(:list).class_name - end - def test_name - assert_equal :Word , @builder.infer_type(:name).class_name - end - def test_word - assert_equal :Word , @builder.infer_type(:word).class_name - end - def test_caller - assert_equal :Message , @builder.infer_type(:caller).class_name - end - def test_caller_reg - assert_equal :Message , @builder.infer_type(:caller_reg).class_name - end - def test_caller_tmp - assert_equal :Message , @builder.infer_type(:caller_tmp).class_name - end - def test_caller_obj - assert_equal :Message , @builder.infer_type(:caller_obj).class_name - end - def test_caller_const - assert_equal :Message , @builder.infer_type(:caller_const).class_name - end - def test_caller_self - assert_equal :Message , @builder.infer_type(:caller_self).class_name - end - def test_caller_1 - assert_equal :Message , @builder.infer_type(:caller_1).class_name - end - def test_message - assert_equal :Message , @builder.infer_type(:message).class_name - end - def test_next_message - assert_equal :Message , @builder.infer_type(:next_message).class_name - end - - end -end