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
"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
Returns a new instance of Send.
4824
4825
4826
4827
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4824
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.
4822
4823
4824
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4822
def block_iseq
@block_iseq
end
|
#calldata ⇒ Object
Returns the value of attribute calldata.
4822
4823
4824
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4822
def calldata
@calldata
end
|
Instance Method Details
#==(other) ⇒ Object
4845
4846
4847
4848
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4845
def ==(other)
other.is_a?(Send) && other.calldata == calldata &&
other.block_iseq == block_iseq
end
|
#call(vm) ⇒ Object
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4863
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
4841
4842
4843
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4841
def deconstruct_keys(_keys)
{ calldata: calldata, block_iseq: block_iseq }
end
|
#disasm(fmt) ⇒ Object
4829
4830
4831
4832
4833
4834
4835
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4829
def disasm(fmt)
fmt.enqueue(block_iseq) if block_iseq
fmt.instruction(
"send",
[fmt.calldata(calldata), block_iseq&.name || "nil"]
)
end
|
#length ⇒ Object
4850
4851
4852
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4850
def length
3
end
|
#pops ⇒ Object
4854
4855
4856
4857
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4854
def pops
argb = (calldata.flag?(CallData::CALL_ARGS_BLOCKARG) ? 1 : 0)
argb + calldata.argc + 1
end
|
#pushes ⇒ Object
4859
4860
4861
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4859
def pushes
1
end
|
#to_a(_iseq) ⇒ Object
4837
4838
4839
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4837
def to_a(_iseq)
[:send, calldata.to_h, block_iseq&.to_a]
end
|