Class: SyntaxTree::YARV::InvokeSuper

Inherits:
Instruction show all
Defined in:
lib/syntax_tree/yarv/instructions.rb

Overview

### Summary

invokesuper is similar to the send instruction, except that it calls the super method. It pops the receiver and arguments off the stack and pushes the return value onto the stack.

### Usage

~~~ruby def foo

super

end ~~~

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Instruction

#branch_targets, #canonical, #falls_through?, #leaves?, #length, #side_effects?

Constructor Details

#initialize(calldata, block_iseq) ⇒ InvokeSuper

Returns a new instance of InvokeSuper.



2085
2086
2087
2088
# File 'lib/syntax_tree/yarv/instructions.rb', line 2085

def initialize(calldata, block_iseq)
  @calldata = calldata
  @block_iseq = block_iseq
end

Instance Attribute Details

#block_iseqObject (readonly)

Returns the value of attribute block_iseq.



2083
2084
2085
# File 'lib/syntax_tree/yarv/instructions.rb', line 2083

def block_iseq
  @block_iseq
end

#calldataObject (readonly)

Returns the value of attribute calldata.



2083
2084
2085
# File 'lib/syntax_tree/yarv/instructions.rb', line 2083

def calldata
  @calldata
end

Instance Method Details

#==(other) ⇒ Object



2106
2107
2108
2109
# File 'lib/syntax_tree/yarv/instructions.rb', line 2106

def ==(other)
  other.is_a?(InvokeSuper) && other.calldata == calldata &&
    other.block_iseq == block_iseq
end

#call(vm) ⇒ Object



2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
# File 'lib/syntax_tree/yarv/instructions.rb', line 2120

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

  method = receiver.method(vm.frame.name).super_method
  vm.push(method.call(*arguments, **keywords, &block))
end

#deconstruct_keys(_keys) ⇒ Object



2102
2103
2104
# File 'lib/syntax_tree/yarv/instructions.rb', line 2102

def deconstruct_keys(_keys)
  { calldata: calldata, block_iseq: block_iseq }
end

#disasm(fmt) ⇒ Object



2090
2091
2092
2093
2094
2095
2096
# File 'lib/syntax_tree/yarv/instructions.rb', line 2090

def disasm(fmt)
  fmt.enqueue(block_iseq) if block_iseq
  fmt.instruction(
    "invokesuper",
    [fmt.calldata(calldata), block_iseq&.name || "nil"]
  )
end

#popsObject



2111
2112
2113
2114
# File 'lib/syntax_tree/yarv/instructions.rb', line 2111

def pops
  argb = (calldata.flag?(CallData::CALL_ARGS_BLOCKARG) ? 1 : 0)
  argb + calldata.argc + 1
end

#pushesObject



2116
2117
2118
# File 'lib/syntax_tree/yarv/instructions.rb', line 2116

def pushes
  1
end

#to_a(_iseq) ⇒ Object



2098
2099
2100
# File 'lib/syntax_tree/yarv/instructions.rb', line 2098

def to_a(_iseq)
  [:invokesuper, calldata.to_h, block_iseq&.to_a]
end