class Opal::Nodes::IterNode

def compile

def compile
  is_lambda! if scope.lambda_definition?
  inline_params = nil
  to_vars = identity = body_code = nil
  in_scope do
    identity = scope.identify!
    add_temp "self = #{identity}.$$s == null ? this : #{identity}.$$s"
    inline_params = process(inline_args)
    compile_arity_check
    body_code = stmt(returned_body)
    to_vars = scope.to_vars
    line body_code
    if scope.catch_return
      unshift "try {\n"
      line '} catch ($returner) { if ($returner === Opal.returner) { return $returner.$v }'
      push ' throw $returner; }'
    end
  end
  unshift to_vars
  if await_encountered
    unshift "(#{identity} = async function(", inline_params, '){'
  else
    unshift "(#{identity} = function(", inline_params, '){'
  end
  push "}, #{identity}.$$s = self,"
  push " #{identity}.$$brk = $brk," if contains_break?
  push " #{identity}.$$arity = #{arity},"
  if compiler.arity_check?
    push " #{identity}.$$parameters = #{parameters_code},"
  end
  # MRI expands a passed argument if the block:
  # 1. takes a single argument that is an array
  # 2. has more that one argument
  # With a few exceptions:
  # 1. mlhs arg: if a block takes |(a, b)| argument
  # 2. trailing ',' in the arg list (|a, |)
  # This flag on the method indicates that a block has a top level mlhs argument
  # which means that we have to expand passed array explicitly in runtime.
  if has_top_level_mlhs_arg?
    push " #{identity}.$$has_top_level_mlhs_arg = true,"
  end
  if has_trailing_comma_in_args?
    push " #{identity}.$$has_trailing_comma_in_args = true,"
  end
  push " #{identity})"
end