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.
4971
4972
4973
4974
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4971
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.
4969
4970
4971
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4969
def block_iseq
@block_iseq
end
|
#calldata ⇒ Object
Returns the value of attribute calldata.
4969
4970
4971
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4969
def calldata
@calldata
end
|
Instance Method Details
#==(other) ⇒ Object
4992
4993
4994
4995
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4992
def ==(other)
other.is_a?(Send) && other.calldata == calldata &&
other.block_iseq == block_iseq
end
|
#call(vm) ⇒ Object
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 5010
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
4988
4989
4990
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4988
def deconstruct_keys(_keys)
{ calldata: calldata, block_iseq: block_iseq }
end
|
#disasm(fmt) ⇒ Object
4976
4977
4978
4979
4980
4981
4982
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4976
def disasm(fmt)
fmt.enqueue(block_iseq) if block_iseq
fmt.instruction(
"send",
[fmt.calldata(calldata), block_iseq&.name || "nil"]
)
end
|
#length ⇒ Object
4997
4998
4999
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4997
def length
3
end
|
#pops ⇒ Object
5001
5002
5003
5004
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 5001
def pops
argb = (calldata.flag?(CallData::CALL_ARGS_BLOCKARG) ? 1 : 0)
argb + calldata.argc + 1
end
|
#pushes ⇒ Object
5006
5007
5008
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 5006
def pushes
1
end
|
#to_a(_iseq) ⇒ Object
4984
4985
4986
|
# File 'lib/syntax_tree/yarv/instructions.rb', line 4984
def to_a(_iseq)
[:send, calldata.to_h, block_iseq&.to_a]
end
|