class SyntaxTree::YARV::VM
def setup_arguments(iseq, args, kwargs, block)
def setup_arguments(iseq, args, kwargs, block) locals = [*args] local_index = 0 start_label = nil # First, set up all of the leading arguments. These are positional and # required arguments at the start of the argument list. if (lead_num = iseq.argument_options[:lead_num]) lead_num.times do local_set(local_index, 0, locals.shift) local_index += 1 end end # Next, set up all of the optional arguments. The opt array contains # the labels that the frame should start at if the optional is # present. The last element of the array is the label that the frame # should start at if all of the optional arguments are present. if (opt = iseq.argument_options[:opt]) opt[0...-1].each do |label| if locals.empty? start_label = label break else local_set(local_index, 0, locals.shift) local_index += 1 end start_label = opt.last if start_label.nil? end end # If there is a splat argument, then we'll set that up here. It will # grab up all of the remaining positional arguments. if (rest_start = iseq.argument_options[:rest_start]) if (post_start = iseq.argument_options[:post_start]) length = post_start - rest_start local_set(local_index, 0, locals[0...length]) locals = locals[length..] else local_set(local_index, 0, locals.dup) locals.clear end local_index += 1 end # Next, set up any post arguments. These are positional arguments that # come after the splat argument. if (post_num = iseq.argument_options[:post_num]) post_num.times do local_set(local_index, 0, locals.shift) local_index += 1 end end if (keyword_option = iseq.argument_options[:keyword]) # First, set up the keyword bits array. keyword_bits = keyword_option.map do |config| kwargs.key?(config.is_a?(Array) ? config[0] : config) end iseq.local_table.locals.each_with_index do |local, index| # If this is the keyword bits local, then set it appropriately. if local.name.is_a?(Integer) local_set(index, 0, keyword_bits) next end # First, find the configuration for this local in the keywords # list if it exists. name = local.name config = keyword_option.find do |keyword| keyword.is_a?(Array) ? keyword[0] == name : keyword == name end # If the configuration doesn't exist, then the local is not a # keyword local. next unless config if !config.is_a?(Array) # required keyword local_set(index, 0, kwargs.fetch(name)) elsif !config[1].nil? # optional keyword with embedded default value local_set(index, 0, kwargs.fetch(name, config[1])) else # optional keyword with expression default value local_set(index, 0, kwargs[name]) end end end local_set(local_index, 0, block) if iseq.argument_options[:block_start] start_label end