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