Class: SyntaxTree::YARV::Send
Overview
### Summary
send invokes a method with an optional block. It pops its receiver and the arguments for the method off the stack and pushes the return value onto the stack. It has two arguments: the calldata for the call site and the optional block instruction sequence.
### Usage
~~~ruby “hello”.tap { |i| p i } ~~~
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods inherited from Instruction
#branch_targets, #canonical, #falls_through?, #leaves?, #side_effects?
Constructor Details
#initialize(calldata, block_iseq) ⇒ Send
4870
4871
4872
4873
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4870
def initialize(calldata, block_iseq)
@calldata = calldata
@block_iseq = block_iseq
end
|
Instance Attribute Details
#block_iseq ⇒ Object
Returns the value of attribute block_iseq.
4868
4869
4870
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4868
def block_iseq
@block_iseq
end
|
#calldata ⇒ Object
Returns the value of attribute calldata.
4868
4869
4870
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4868
def calldata
@calldata
end
|
Instance Method Details
#==(other) ⇒ Object
4891
4892
4893
4894
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4891
def ==(other)
other.is_a?(Send) && other.calldata == calldata &&
other.block_iseq == block_iseq
end
|
#call(vm) ⇒ Object
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4909
def call(vm)
block =
if (iseq = block_iseq)
frame = vm.frame
->(*args, **kwargs, &blk) do
vm.run_block_frame(iseq, frame, *args, **kwargs, &blk)
end
elsif calldata.flag?(CallData::CALL_ARGS_BLOCKARG)
vm.pop
end
keywords =
if calldata.kw_arg
calldata.kw_arg.zip(vm.pop(calldata.kw_arg.length)).to_h
else
{}
end
arguments = vm.pop(calldata.argc)
receiver = vm.pop
vm.push(
receiver.__send__(calldata.method, *arguments, **keywords, &block)
)
end
|
#deconstruct_keys(_keys) ⇒ Object
4887
4888
4889
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4887
def deconstruct_keys(_keys)
{ calldata: calldata, block_iseq: block_iseq }
end
|
#disasm(fmt) ⇒ Object
4875
4876
4877
4878
4879
4880
4881
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4875
def disasm(fmt)
fmt.enqueue(block_iseq) if block_iseq
fmt.instruction(
"send",
[fmt.calldata(calldata), block_iseq&.name || "nil"]
)
end
|
#length ⇒ Object
4896
4897
4898
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4896
def length
3
end
|
#pops ⇒ Object
4900
4901
4902
4903
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4900
def pops
argb = (calldata.flag?(CallData::CALL_ARGS_BLOCKARG) ? 1 : 0)
argb + calldata.argc + 1
end
|
#pushes ⇒ Object
4905
4906
4907
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4905
def pushes
1
end
|
#to_a(_iseq) ⇒ Object
4883
4884
4885
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4883
def to_a(_iseq)
[:send, calldata.to_h, block_iseq&.to_a]
end
|