Class: SyntaxTree::YARV::ExpandArray

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

Overview

### Summary

expandarray looks at the top of the stack, and if the value is an array it replaces it on the stack with number elements of the array, or nil if the elements are missing.

### Usage

~~~ruby x, = [true, false, nil] ~~~

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(number, flags) ⇒ ExpandArray



1297
1298
1299
1300
# File 'lib/syntax_tree/yarv/instructions.rb', line 1297

def initialize(number, flags)
  @number = number
  @flags = flags
end

Instance Attribute Details

#flagsObject (readonly)

Returns the value of attribute flags.



1295
1296
1297
# File 'lib/syntax_tree/yarv/instructions.rb', line 1295

def flags
  @flags
end

#numberObject (readonly)

Returns the value of attribute number.



1295
1296
1297
# File 'lib/syntax_tree/yarv/instructions.rb', line 1295

def number
  @number
end

Instance Method Details

#call(vm) ⇒ Object



1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
# File 'lib/syntax_tree/yarv/instructions.rb', line 1326

def call(vm)
  object = vm.pop
  object =
    if Array === object
      object.dup
    elsif object.respond_to?(:to_ary, true)
      object.to_ary
    else
      [object]
    end

  splat_flag = flags & 0x01 > 0
  postarg_flag = flags & 0x02 > 0

  if number == 0 && splat_flag == 0
    # no space left on stack
  elsif postarg_flag
    values = []

    if number > object.size
      (number - object.size).times { values.push(nil) }
    end
    [number, object.size].min.times { values.push(object.pop) }
    values.push(object.to_a) if splat_flag

    values.each { |item| vm.push(item) }
  else
    values = []

    [number, object.size].min.times { values.push(object.shift) }
    if number > values.size
      (number - values.size).times { values.push(nil) }
    end
    values.push(object.to_a) if splat_flag

    values.reverse_each { |item| vm.push(item) }
  end
end

#canonicalObject



1322
1323
1324
# File 'lib/syntax_tree/yarv/instructions.rb', line 1322

def canonical
  self
end

#disasm(fmt) ⇒ Object



1302
1303
1304
# File 'lib/syntax_tree/yarv/instructions.rb', line 1302

def disasm(fmt)
  fmt.instruction("expandarray", [fmt.object(number), fmt.object(flags)])
end

#lengthObject



1310
1311
1312
# File 'lib/syntax_tree/yarv/instructions.rb', line 1310

def length
  3
end

#popsObject



1314
1315
1316
# File 'lib/syntax_tree/yarv/instructions.rb', line 1314

def pops
  1
end

#pushesObject



1318
1319
1320
# File 'lib/syntax_tree/yarv/instructions.rb', line 1318

def pushes
  number
end

#to_a(_iseq) ⇒ Object



1306
1307
1308
# File 'lib/syntax_tree/yarv/instructions.rb', line 1306

def to_a(_iseq)
  [:expandarray, number, flags]
end