Class: Rubinius::ToolSet.current::TS::AST::Send

Inherits:
Node
  • Object
show all
Defined in:
lib/rubinius/ast/sends.rb

Instance Attribute Summary collapse

Attributes inherited from Node

#line

Instance Method Summary collapse

Methods inherited from Node

#ascii_graph, #attributes, #children, match_arguments?, match_send?, #new_block_generator, #new_generator, #node_name, #or_bytecode, #pos, #set_child, transform, #transform, transform_comment, transform_kind, transform_kind=, transform_name, #visit, #walk

Constructor Details

#initialize(line, receiver, name, privately = false, vcall_style = false) ⇒ Send

Returns a new instance of Send.



8
9
10
11
12
13
14
15
# File 'lib/rubinius/ast/sends.rb', line 8

def initialize(line, receiver, name, privately=false, vcall_style=false)
  @line = line
  @receiver = receiver
  @name = name
  @privately = privately
  @block = nil
  @vcall_style = vcall_style
end

Instance Attribute Details

#blockObject

Returns the value of attribute block.



6
7
8
# File 'lib/rubinius/ast/sends.rb', line 6

def block
  @block
end

#nameObject

Returns the value of attribute name.



6
7
8
# File 'lib/rubinius/ast/sends.rb', line 6

def name
  @name
end

#privatelyObject

Returns the value of attribute privately.



6
7
8
# File 'lib/rubinius/ast/sends.rb', line 6

def privately
  @privately
end

#receiverObject

Returns the value of attribute receiver.



6
7
8
# File 'lib/rubinius/ast/sends.rb', line 6

def receiver
  @receiver
end

#variableObject

Returns the value of attribute variable.



6
7
8
# File 'lib/rubinius/ast/sends.rb', line 6

def variable
  @variable
end

#vcall_styleObject

Returns the value of attribute vcall_style.



6
7
8
# File 'lib/rubinius/ast/sends.rb', line 6

def vcall_style
  @vcall_style
end

Instance Method Details

#arguments_sexpObject



110
111
112
113
114
115
116
# File 'lib/rubinius/ast/sends.rb', line 110

def arguments_sexp
  return nil if @vcall_style

  sexp = [:arglist]
  sexp << @block.to_sexp if @block.kind_of? BlockPass
  sexp
end

#bytecode(g) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/rubinius/ast/sends.rb', line 23

def bytecode(g)
  pos(g)

  if @vcall_style and reference = check_local_reference(g)
    return reference.get_bytecode(g)
  end

  @receiver.bytecode(g)

  if @block
    @block.bytecode(g)
    g.send_with_block @name, 0, @privately
  elsif @vcall_style
    g.send_vcall @name
  else
    g.send @name, 0, @privately
  end
end

#check_local_reference(g) ⇒ Object



17
18
19
20
21
# File 'lib/rubinius/ast/sends.rb', line 17

def check_local_reference(g)
  if @receiver.kind_of? Self and g.state.check_for_locals
    g.state.scope.search_local(@name)
  end
end

#defined(g) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/rubinius/ast/sends.rb', line 67

def defined(g)
  if @block.kind_of? For
    @block.defined(g)
    return
  end

  if @vcall_style and check_local_reference(g)
    g.push_literal "local-variable"
    return
  end

  f = g.new_label
  done = g.new_label

  @receiver.value_defined(g, f)

  g.push_literal @name

  if @vcall_style or @privately
    g.push :true
    g.send :__respond_to_p__, 2
  else
    g.push_self
    g.invoke_primitive :vm_check_callable, 3
  end
  g.gif f
  g.push_literal "method"
  g.goto done

  f.set!
  g.push :nil

  done.set!
end

#receiver_sexpObject



106
107
108
# File 'lib/rubinius/ast/sends.rb', line 106

def receiver_sexp
  @privately ? nil : @receiver.to_sexp
end

#sexp_nameObject



102
103
104
# File 'lib/rubinius/ast/sends.rb', line 102

def sexp_name
  :call
end

#to_sexpObject



118
119
120
121
122
123
124
125
126
127
128
# File 'lib/rubinius/ast/sends.rb', line 118

def to_sexp
  sexp = [sexp_name, receiver_sexp, @name, arguments_sexp]
  case @block
  when For
    @block.to_sexp.insert 1, @receiver.to_sexp
  when Iter
    @block.to_sexp.insert 1, sexp
  else
    sexp
  end
end

#value_defined(g, f) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rubinius/ast/sends.rb', line 42

def value_defined(g, f)
  # Save the current exception into a stack local
  g.push_exception_state
  outer_exc_state = g.new_stack_local
  g.set_stack_local outer_exc_state
  g.pop

  ok = g.new_label
  ex = g.new_label
  g.setup_unwind ex, RescueType

  bytecode(g)

  g.pop_unwind
  g.goto ok

  ex.set!
  g.clear_exception
  g.push_stack_local outer_exc_state
  g.restore_exception_state
  g.goto f

  ok.set!
end