mirror of https://github.com/Icinga/icinga2.git
parent
c29d6a99ac
commit
d3a6277fec
|
@ -652,9 +652,7 @@ lterm: T_LOCAL indexer combined_set_op rterm
|
|||
}
|
||||
| T_RETURN rterm
|
||||
{
|
||||
std::vector<Expression *> vname;
|
||||
vname.push_back(MakeLiteral("__result"));
|
||||
$$ = new SetExpression(vname, OpSetLiteral, $2, false, DebugInfoRange(@1, @2));
|
||||
$$ = new ReturnExpression($2, DebugInfoRange(@1, @2));
|
||||
}
|
||||
| apply
|
||||
{
|
||||
|
|
|
@ -45,6 +45,8 @@ Value Expression::Evaluate(VMFrame& frame, DebugHint *dhint) const
|
|||
#endif /* _DEBUG */
|
||||
|
||||
return DoEvaluate(frame, dhint);
|
||||
} catch (const InterruptExecutionError&) {
|
||||
throw;
|
||||
} catch (const std::exception& ex) {
|
||||
if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
|
||||
throw;
|
||||
|
@ -344,6 +346,11 @@ Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
|||
return right;
|
||||
}
|
||||
|
||||
Value ReturnExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(InterruptExecutionError(m_Operand->Evaluate(frame)));
|
||||
}
|
||||
|
||||
Value IndexerExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
|
||||
{
|
||||
return VMOps::Indexer(frame, m_Indexer);
|
||||
|
|
|
@ -101,6 +101,25 @@ enum CombinedSetOp
|
|||
OpSetDivide
|
||||
};
|
||||
|
||||
class InterruptExecutionError : virtual public std::exception, virtual public boost::exception
|
||||
{
|
||||
public:
|
||||
InterruptExecutionError(const Value& result)
|
||||
: m_Result(result)
|
||||
{ }
|
||||
|
||||
~InterruptExecutionError(void) throw()
|
||||
{ }
|
||||
|
||||
Value GetResult(void) const
|
||||
{
|
||||
return m_Result;
|
||||
}
|
||||
|
||||
private:
|
||||
Value m_Result;
|
||||
};
|
||||
|
||||
typedef std::map<String, String> DefinitionMap;
|
||||
|
||||
/**
|
||||
|
@ -537,6 +556,17 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class I2_CONFIG_API ReturnExpression : public UnaryExpression
|
||||
{
|
||||
public:
|
||||
ReturnExpression(Expression *expression, const DebugInfo& debugInfo = DebugInfo())
|
||||
: UnaryExpression(expression, debugInfo)
|
||||
{ }
|
||||
|
||||
protected:
|
||||
virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
|
||||
};
|
||||
|
||||
class I2_CONFIG_API IndexerExpression : public DebuggableExpression
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -30,7 +30,6 @@ struct VMFrame
|
|||
{
|
||||
Dictionary::Ptr Locals;
|
||||
Object::Ptr Self;
|
||||
Value Result;
|
||||
|
||||
VMFrame(void)
|
||||
: Locals(new Dictionary()), Self(Locals)
|
||||
|
|
|
@ -295,8 +295,14 @@ private:
|
|||
for (std::vector<Value>::size_type i = 0; i < std::min(arguments.size(), funcargs.size()); i++)
|
||||
frame.Locals->Set(funcargs[i], arguments[i]);
|
||||
|
||||
expr->Evaluate(frame);
|
||||
return frame.Result;
|
||||
Value result;
|
||||
try {
|
||||
result = expr->Evaluate(frame);
|
||||
} catch (const InterruptExecutionError& iee) {
|
||||
result = iee.GetResult();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void SlotWrapper(const Value& funcName, const std::vector<Value>& arguments)
|
||||
|
|
|
@ -226,6 +226,14 @@ BOOST_AUTO_TEST_CASE(advanced)
|
|||
|
||||
expr = ConfigCompiler::CompileText("<test>", "a = 3 b = 3");
|
||||
BOOST_CHECK(expr == NULL);
|
||||
|
||||
expr = ConfigCompiler::CompileText("<test>", "__function() { 3 }()");
|
||||
BOOST_CHECK(expr->Evaluate(frame) == 3);
|
||||
delete expr;
|
||||
|
||||
expr = ConfigCompiler::CompileText("<test>", "__function() { __return 3, 5 }()");
|
||||
BOOST_CHECK(expr->Evaluate(frame) == 3);
|
||||
delete expr;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
Loading…
Reference in New Issue