Class: CodeTools::AST::Send

Inherits:
Node
  • Object
show all
Defined in:
lib/rubinius/code/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/code/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/code/ast/sends.rb', line 6

def block
  @block
end

#nameObject

Returns the value of attribute name.



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

def name
  @name
end

#privatelyObject

Returns the value of attribute privately.



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

def privately
  @privately
end

#receiverObject

Returns the value of attribute receiver.



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

def receiver
  @receiver
end

#variableObject

Returns the value of attribute variable.



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

def variable
  @variable
end

#vcall_styleObject

Returns the value of attribute vcall_style.



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

def vcall_style
  @vcall_style
end

Instance Method Details

#arguments_sexpObject



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

def arguments_sexp
  sexp = [:arglist]
  sexp << @block.to_sexp if @block
  sexp
end

#bytecode(g, anddot = false) ⇒ Object



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

def bytecode(g, anddot=false)
  pos(g)

  if @vcall_style
    if reference = check_local_reference(g)
      return reference.get_bytecode(g)
    end
  elsif !anddot
    @receiver.bytecode(g)
  end

  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/code/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



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
101
102
# File 'lib/rubinius/code/ast/sends.rb', line 69

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.goto_if_false f
  g.push_literal "method"
  g.goto done

  f.set!
  g.push_nil

  done.set!
end

#receiver_sexpObject



108
109
110
# File 'lib/rubinius/code/ast/sends.rb', line 108

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

#sexp_nameObject



104
105
106
# File 'lib/rubinius/code/ast/sends.rb', line 104

def sexp_name
  :call
end

#to_sexpObject



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

def to_sexp
  case @block
  when For
    n, x, b = @block.to_sexp
    xs = @receiver.to_sexp
    [n, x, xs, b]
  else
    [sexp_name, receiver_sexp, @name, arguments_sexp]
  end
end

#value_defined(g, f) ⇒ Object



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

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