void ForEachStatement::eval(VariableEnvironment &env) const {
  if (env.isGotoing()) return;
  ENTER_STMT;
  DECLARE_THREAD_INFO;
  LOOP_COUNTER(1);
  Variant map(m_source->eval(env));
  if (m_key) {
    TempExpressionList *texp = m_key->cast<TempExpressionList>();
    if (texp) {
      for (ArrayIter iter = map.begin(env.currentContext(), true);
           !iter.end(); iter.next()) {
        {
          LOOP_COUNTER_CHECK_INFO(1);
          const Variant &value = iter.second();
          const Variant &key = iter.first();
          TempExpressionHelper helper(texp, env);
          m_value->set(env, value);
          texp->setImpl(env, key);
        }
        if (!m_body) continue;
        EVAL_STMT_HANDLE_GOTO_BEGIN(restart1);
        EVAL_STMT_HANDLE_BREAK(m_body, env);
        EVAL_STMT_HANDLE_GOTO_END(restart1);
      }
    } else {
      for (ArrayIter iter = map.begin(env.currentContext(), true);
           !iter.end(); iter.next()) {
        LOOP_COUNTER_CHECK_INFO(1);
        const Variant &value = iter.second();
        const Variant &key = iter.first();
        m_value->set(env, value);
        m_key->set(env, key);
        if (!m_body) continue;
        EVAL_STMT_HANDLE_GOTO_BEGIN(restart2);
        EVAL_STMT_HANDLE_BREAK(m_body, env);
        EVAL_STMT_HANDLE_GOTO_END(restart2);
      }
    }
  } else {
    for (ArrayIter iter = map.begin(env.currentContext(), true);
         !iter.end(); iter.next()) {
      LOOP_COUNTER_CHECK_INFO(1);
      m_value->set(env, iter.second());
      if (!m_body) continue;
      EVAL_STMT_HANDLE_GOTO_BEGIN(restart3);
      EVAL_STMT_HANDLE_BREAK(m_body, env);
      EVAL_STMT_HANDLE_GOTO_END(restart3);
    }
  }
}
void DoWhileStatement::eval(VariableEnvironment &env) const {
  if (env.isGotoing() && env.isLimitedGoto()) return;
  ENTER_STMT;
  DECLARE_THREAD_INFO;
  LOOP_COUNTER(1);

  do {
    LOOP_COUNTER_CHECK_INFO(1);
    EVAL_STMT_HANDLE_GOTO_BEGIN(restart);
    if (m_body) EVAL_STMT_HANDLE_BREAK(m_body, env);
    EVAL_STMT_HANDLE_GOTO_END(restart);
  } while (m_cond->eval(env));
}
void WhileStatement::eval(VariableEnvironment &env) const {
  DECLARE_THREAD_INFO;

  if (env.isGotoing()) {
    if (env.isLimitedGoto()) return;
    goto body;
  }
  ENTER_STMT;
  LOOP_COUNTER(1);

  begin:
  if (m_cond->eval(env)) {
    body:
    LOOP_COUNTER_CHECK_INFO(1);
    EVAL_STMT_HANDLE_GOTO_BEGIN(restart);
    if (m_body) EVAL_STMT_HANDLE_GOTO(m_body, env);
    EVAL_STMT_HANDLE_GOTO_END(restart);
    goto begin;
  }
  end:;
}