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.



2196
2197
2198
2199
# File 'lib/syntax_tree/yarv/instructions.rb', line 2196

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.



2194
2195
2196
# File 'lib/syntax_tree/yarv/instructions.rb', line 2194

def block_iseq
  @block_iseq
end

#calldataObject (readonly)

Returns the value of attribute calldata.



2194
2195
2196
# File 'lib/syntax_tree/yarv/instructions.rb', line 2194

def calldata
  @calldata
end

Instance Method Details

#==(other) ⇒ Object



2217
2218
2219
2220
# File 'lib/syntax_tree/yarv/instructions.rb', line 2217

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

#call(vm) ⇒ Object



2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
# File 'lib/syntax_tree/yarv/instructions.rb', line 2231

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



2213
2214
2215
# File 'lib/syntax_tree/yarv/instructions.rb', line 2213

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

#disasm(fmt) ⇒ Object



2201
2202
2203
2204
2205
2206
2207
# File 'lib/syntax_tree/yarv/instructions.rb', line 2201

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

#popsObject



2222
2223
2224
2225
# File 'lib/syntax_tree/yarv/instructions.rb', line 2222

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

#pushesObject



2227
2228
2229
# File 'lib/syntax_tree/yarv/instructions.rb', line 2227

def pushes
  1
end

#to_a(_iseq) ⇒ Object



2209
2210
2211
# File 'lib/syntax_tree/yarv/instructions.rb', line 2209

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