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