void StrongForEachStatement::eval(VariableEnvironment &env) const { if (env.isGotoing()) return; ENTER_STMT; LvalExpression* lvalSource = m_source->cast<LvalExpression>(); Variant source(lvalSource ? ref(lvalSource->lval(env)) : ref(m_source->eval(env))); source.escalate(true); Variant vTemp; if (m_key) { Variant kTemp; for (MutableArrayIter iter = source.begin(&kTemp, vTemp, env.currentContext()); iter.advance();) { m_key->set(env, kTemp); m_value->set(env, ref(vTemp)); 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 (MutableArrayIter iter = source.begin(NULL, vTemp, env.currentContext()); iter.advance();) { m_value->set(env, ref(vTemp)); if (!m_body) continue; EVAL_STMT_HANDLE_GOTO_BEGIN(restart2); EVAL_STMT_HANDLE_BREAK(m_body, env); EVAL_STMT_HANDLE_GOTO_END(restart2); } } }
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 TryStatement::eval(VariableEnvironment &env) const { if (env.isGotoing()) return; ENTER_STMT; try { EVAL_STMT_HANDLE_GOTO_BEGIN(restart1); m_body->eval(env); EVAL_STMT_HANDLE_GOTO_END(restart1); } catch (Object e) { for (vector<CatchBlockPtr>::const_iterator it = m_catches.begin(); it != m_catches.end(); ++it) { if ((*it)->match(e)) { if ((*it)->body()) { env.get(String((*it)->vname())) = e; EVAL_STMT_HANDLE_GOTO_BEGIN(restart2); EVAL_STMT((*it)->body(), env); EVAL_STMT_HANDLE_GOTO_END(restart2); } return; } } throw e; } }
Variant PhpFile::eval(LVariableTable *vars) { NestedVariableEnvironment env(vars, *this); DECLARE_THREAD_INFO_NOINIT EvalFrameInjection fi(empty_string, m_profName.c_str(), env, m_tree->loc()->file, NULL, FrameInjection::PseudoMain); try { EVAL_STMT_HANDLE_GOTO_BEGIN(restart); m_tree->eval(env); EVAL_STMT_HANDLE_GOTO_END(restart); } catch (GotoException &e) { throw FatalErrorException(0, "Unable to reach goto label %s", env.getGoto().c_str()); } if (env.isReturning()) { return env.getRet(); } else if (env.isBreaking()) { throw FatalErrorException("Cannot break/continue out of a file"); } return true; }
void SwitchStatement::eval(VariableEnvironment &env) const { bool gotoing = false; if (env.isGotoing()) { if (env.isLimitedGoto()) return; gotoing = true; } ENTER_STMT; Variant source, *srcPtr; if (!gotoing) { if (!m_simpleVar) { source = m_source->eval(env); srcPtr = &source; } else { m_source->cast<VariableExpression>()->weakLval(env, srcPtr); } } bool matched = false; vector<CaseStatementPtr>::const_iterator defaultPos = m_cases.end(); EVAL_STMT_HANDLE_GOTO_BEGIN(restart); for (vector<CaseStatementPtr>::const_iterator iter = m_cases.begin(); iter != m_cases.end(); ++iter) { if (!gotoing) { if ((*iter)->isDefault()) { defaultPos = iter; } else if (!matched && (*iter)->match(env, *srcPtr)) { matched = true; } } if (gotoing || matched) { EVAL_STMT_HANDLE_BREAK_CONT(*iter, env); } } if (!gotoing && !matched && defaultPos != m_cases.end()) { for (; defaultPos != m_cases.end(); ++defaultPos) { EVAL_STMT_HANDLE_BREAK_CONT(*defaultPos, env); } } EVAL_STMT_HANDLE_GOTO_END(restart); }
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:; }