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.



2143
2144
2145
2146
# File 'lib/syntax_tree/yarv/instructions.rb', line 2143

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.



2141
2142
2143
# File 'lib/syntax_tree/yarv/instructions.rb', line 2141

def block_iseq
  @block_iseq
end

#calldataObject (readonly)

Returns the value of attribute calldata.



2141
2142
2143
# File 'lib/syntax_tree/yarv/instructions.rb', line 2141

def calldata
  @calldata
end

Instance Method Details

#==(other) ⇒ Object



2164
2165
2166
2167
# File 'lib/syntax_tree/yarv/instructions.rb', line 2164

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

#call(vm) ⇒ Object



2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
# File 'lib/syntax_tree/yarv/instructions.rb', line 2178

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



2160
2161
2162
# File 'lib/syntax_tree/yarv/instructions.rb', line 2160

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

#disasm(fmt) ⇒ Object



2148
2149
2150
2151
2152
2153
2154
# File 'lib/syntax_tree/yarv/instructions.rb', line 2148

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

#popsObject



2169
2170
2171
2172
# File 'lib/syntax_tree/yarv/instructions.rb', line 2169

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

#pushesObject



2174
2175
2176
# File 'lib/syntax_tree/yarv/instructions.rb', line 2174

def pushes
  1
end

#to_a(_iseq) ⇒ Object



2156
2157
2158
# File 'lib/syntax_tree/yarv/instructions.rb', line 2156

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