Class: YTLJit::VM::Node::SendNewNode

Inherits:
SendNode show all
Includes:
UnboxedArrayUtil
Defined in:
lib/ytljit/vm_sendnode.rb

Constant Summary

Constants included from AbsArch

AbsArch::AL, AbsArch::BL, AbsArch::CL, AbsArch::DL, AbsArch::FUNC_ARG, AbsArch::FUNC_ARG_YTL, AbsArch::FUNC_FLOAT_ARG, AbsArch::FUNC_FLOAT_ARG_YTL, AbsArch::INDIRECT_BPR, AbsArch::INDIRECT_RETR, AbsArch::INDIRECT_SPR, AbsArch::INDIRECT_TMPR, AbsArch::INDIRECT_TMPR2, AbsArch::INDIRECT_TMPR3

Constants included from SSE

SSE::XMM0, SSE::XMM1, SSE::XMM2, SSE::XMM3, SSE::XMM4, SSE::XMM5, SSE::XMM6, SSE::XMM7

Constants inherited from BaseNode

BaseNode::ESCAPE_LEVEL

Instance Attribute Summary

Attributes inherited from SendNode

#arguments, #class_top, #current_exception_table, #frame_info, #func, #modified_instance_var, #modified_local_var, #next_node, #opt_flag, #result_cache, #seq_no

Attributes included from HaveChildlenMixin

#body

Attributes inherited from BaseNode

#code_space, #debug_info, #element_node_list, #id, #is_escape, #parent, #ti_observee, #ti_observer, #type

Instance Method Summary collapse

Methods included from UnboxedArrayUtil

#compile_array_unboxed, #gen_ref_element, #gen_set_element

Methods included from UnboxedObjectUtil

#compile_object_unboxed

Methods inherited from SendNode

add_special_send_node, #check_signature_changed, #collect_candidate_type, #collect_info, #fill_result_cache, #get_constant_value, get_macro_tab, #get_send_method_node, get_user_defined_method_tab, macro_expand, make_send_node, node, #search_signature

Methods included from SendUtil

#compile_c_fixarg, #compile_c_fixarg_raw, #compile_c_vararg, #compile_ytl, #gen_eval_self, #signature

Methods included from NodeUtil

#search_class_top, #search_end, #search_frame_info, #search_top

Methods included from SendNodeCodeGen

#gen_make_argv

Methods included from CommonCodeGen

#dump_context, #gen_alloca, #gen_call, #gen_save_thepr

Methods included from OptFlagOp

#is_args_blockarg, #is_args_splat, #is_fcall, #is_opt_send, #is_super, #is_tailcall, #is_tailrecursion, #is_vcall

Methods inherited from BaseNode

#add_element_node, #add_element_node_backward, #collect_candidate_type, #collect_info, #decide_type, #decide_type_core, #decide_type_once, #gen_type_inference_proc, #get_constant_value, #inference_type, #marge_element_node, #marge_type, #same_type, #set_escape_node, #set_escape_node_backward, #ti_add_observer, #ti_changed, #ti_del_link, #ti_reset, #ti_update

Methods included from TypeListWithSignature

#add_type, #set_type_list, #type_list, #type_list_initvar

Methods included from Inspect

#inspect_by_graph

Constructor Details

#initialize(parent, func, arguments, op_flag, seqno) ⇒ SendNewNode

Returns a new instance of SendNewNode.



625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
# File 'lib/ytljit/vm_sendnode.rb', line 625

def initialize(parent, func, arguments, op_flag, seqno)
  super
  allocfunc = MethodSelectNode.new(self, :allocate)
  alloc = SendNode.make_send_node(self, allocfunc, 
                                  arguments[0, 3], 0, seqno)
  allocfunc.set_reciever(alloc)
  initfunc = MethodSelectNode.new(self, :initialize)
  initarg = arguments.dup
  initarg[2] = alloc
  init = SendNode.make_send_node(self, initfunc, 
                                 initarg, op_flag, seqno)
  initfunc.set_reciever(init)
  alloc.parent = init
  @initmethod = init
  @allocmethod = alloc
end

Instance Method Details

#collect_candidate_type_regident(context, slf) ⇒ Object



657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
# File 'lib/ytljit/vm_sendnode.rb', line 657

def collect_candidate_type_regident(context, slf)
  slfnode = @arguments[2]
  cursig = context.to_signature

  if slf.ruby_type.is_a?(Class) then
    @is_escape = search_class_top.is_escape
    @allocmethod.is_escape = @is_escape
    case slfnode
    when ConstantRefNode
      context = @initmethod.collect_candidate_type(context)
      clstop = slfnode.value_node
      tt = nil
      case clstop
      when ClassTopNode
        tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
        
      when LiteralNode
        tt = RubyType::BaseType.from_ruby_class(clstop.value)

      else
        raise "Unkown node type in constant #{slfnode.value_node.class}"
      end

      clt =  ClassTopNode.get_class_top_node(tt.ruby_type_raw)
      if context.options[:compile_array_as_uboxed] and
          @is_escape and @is_escape != :global_export and
          (clt and  !clt.body.is_a?(DummyNode)) then
        tt = tt.to_unbox
      elsif type_list(cursig)[0].include?(tt.to_unbox) then
        type_list(cursig)[0] = []
      end

      # set element type
      if tt.ruby_type == Range then
        tt.args = @arguments[3..-1]
        add_element_node(tt, cursig, @arguments[3], [0], context)
        add_element_node(tt, cursig, @arguments[4], [1], context)

      elsif tt.ruby_type == Array then
        if context.options[:compile_array_as_uboxed] and
            @element_node_list.size > 1 and
              @element_node_list[1..-1].all? {|e|
                e[3]
              } and 
            @is_escape and @is_escape != :global_export then
          tt = tt.to_unbox
        end
        if @arguments[4] then
          siz = @arguments[3].get_constant_value
          if siz and false then
            # Here is buggy yet Fix me
            siz[0].times do |i|
              add_element_node(tt, cursig, @arguments[4], [i], context)
            end
          else
            add_element_node(tt, cursig, @arguments[4], nil, context)
          end
        end
      end

      add_type(cursig, tt)
    else
      raise "Unkonwn node type #{@arguments[2].class} "
    end
  end
  context
end

#compile(context) ⇒ Object



753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
# File 'lib/ytljit/vm_sendnode.rb', line 753

def compile(context)
  rtype = @arguments[2].decide_type_once(context.to_signature)
  rrtype = rtype.ruby_type
  if rrtype.is_a?(Class) then
    ctype = decide_type_once(context.to_signature)
    crtype = ctype.ruby_type
    if @is_escape != :global_export and 
        crtype == Range then
      return compile_range(context)
      
    elsif crtype == Array and
        !ctype.boxed and 
        @is_escape != :global_export then
      return compile_array_unboxed(context)

    elsif @initmethod.func.calling_convention(context) then
      context = @initmethod.compile(context)

    else
      # initialize method not defined
      context = @allocmethod.compile(context)
    end
    context.ret_node = self
    @body.compile(context)
  else
    super
  end
end

#compile_range(context) ⇒ Object



725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
# File 'lib/ytljit/vm_sendnode.rb', line 725

def compile_range(context)
  context = gen_alloca(context, 3)
  asm = context.assembler
  breg = context.ret_reg
  
  off = 0
  sig = context.to_signature
  [3, 4, 5].each do |no|
    context = @arguments[no].compile(context)
    rtype = @arguments[no].decide_type_once(sig)
    context = rtype.gen_unboxing(context)
    dst = OpIndirect.new(breg, off)
    asm.with_retry do
      if context.ret_reg.is_a?(OpRegistor) then
        asm.mov(dst, context.ret_reg)
      else
        asm.mov(TMPR, context.ret_reg)
        asm.mov(dst, TMPR)
      end
    end
    off = off + AsmType::MACHINE_WORD.size
  end
  
  context.ret_reg = breg
  context.ret_node = self
  context
end

#debug_info=(val) ⇒ Object



642
643
644
645
646
# File 'lib/ytljit/vm_sendnode.rb', line 642

def debug_info=(val)
  @initmethod.debug_info = val
  @allocmethod.debug_info = val
  @debug_info = val
end

#traverse_childlen {|@func| ... } ⇒ Object

Yields:



648
649
650
651
652
653
654
655
# File 'lib/ytljit/vm_sendnode.rb', line 648

def traverse_childlen
  @arguments.each do |arg|
    yield arg
  end
  yield @func
  yield @initmethod
  yield @body
end