mirror of
https://github.com/Icinga/icinga2.git
synced 2026-04-22 22:59:37 -04:00
Merge d072c6bc22 into a810d6409b
This commit is contained in:
commit
4e69a0315b
2 changed files with 77 additions and 25 deletions
|
|
@ -23,6 +23,15 @@ using namespace icinga;
|
|||
boost::signals2::signal<void (ScriptFrame&, ScriptError *ex, const DebugInfo&)> Expression::OnBreakpoint;
|
||||
boost::thread_specific_ptr<bool> l_InBreakpointHandler;
|
||||
|
||||
RefIndex::RefIndex() : m_Foreign(&m_Own)
|
||||
{ }
|
||||
|
||||
void RefIndex::Set(String own)
|
||||
{
|
||||
m_Own = std::move(own);
|
||||
m_Foreign = &m_Own;
|
||||
}
|
||||
|
||||
Expression::~Expression()
|
||||
{ }
|
||||
|
||||
|
|
@ -64,7 +73,7 @@ ExpressionResult Expression::Evaluate(ScriptFrame& frame, DebugHint *dhint) cons
|
|||
}
|
||||
}
|
||||
|
||||
bool Expression::GetReference(ScriptFrame&, [[maybe_unused]] bool init_dict, [[maybe_unused]] Value* parent, [[maybe_unused]] String* index, DebugHint**) const
|
||||
bool Expression::GetReference(ScriptFrame&, [[maybe_unused]] bool init_dict, [[maybe_unused]] Value *parent, RefIndex*, DebugHint**) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -125,9 +134,9 @@ ExpressionResult VariableExpression::DoEvaluate(ScriptFrame& frame, DebugHint*)
|
|||
BOOST_THROW_EXCEPTION(ScriptError{"Tried to access undefined script variable '" + m_Variable + "'"});
|
||||
}
|
||||
|
||||
bool VariableExpression::GetReference(ScriptFrame& frame, [[maybe_unused]] bool init_dict, Value *parent, String *index, DebugHint **dhint) const
|
||||
bool VariableExpression::GetReference(ScriptFrame& frame, [[maybe_unused]] bool init_dict, Value *parent, RefIndex *index, DebugHint **dhint) const
|
||||
{
|
||||
*index = m_Variable;
|
||||
index->Set(&m_Variable);
|
||||
|
||||
if (frame.Locals && frame.Locals->Contains(m_Variable)) {
|
||||
*parent = frame.Locals;
|
||||
|
|
@ -155,7 +164,7 @@ bool VariableExpression::GetReference(ScriptFrame& frame, [[maybe_unused]] bool
|
|||
ExpressionResult RefExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||
{
|
||||
Value parent;
|
||||
String index;
|
||||
RefIndex index;
|
||||
|
||||
if (!m_Operand->GetReference(frame, false, &parent, &index, &dhint))
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Cannot obtain reference for expression.", m_DebugInfo));
|
||||
|
|
@ -163,7 +172,7 @@ ExpressionResult RefExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint)
|
|||
if (!parent.IsObject())
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Cannot obtain reference for expression because parent is not an object.", m_DebugInfo));
|
||||
|
||||
return new Reference(parent, index);
|
||||
return new Reference(parent, index.Get());
|
||||
}
|
||||
|
||||
ExpressionResult DerefExpression::DoEvaluate(ScriptFrame& frame, DebugHint*) const
|
||||
|
|
@ -180,7 +189,7 @@ ExpressionResult DerefExpression::DoEvaluate(ScriptFrame& frame, DebugHint*) con
|
|||
return ref->Get();
|
||||
}
|
||||
|
||||
bool DerefExpression::GetReference(ScriptFrame& frame, [[maybe_unused]] bool init_dict, Value *parent, String *index, DebugHint**) const
|
||||
bool DerefExpression::GetReference(ScriptFrame& frame, [[maybe_unused]] bool init_dict, Value *parent, RefIndex *index, DebugHint**) const
|
||||
{
|
||||
ExpressionResult operand = m_Operand->Evaluate(frame);
|
||||
if (operand.GetCode() != ResultOK)
|
||||
|
|
@ -193,7 +202,7 @@ bool DerefExpression::GetReference(ScriptFrame& frame, [[maybe_unused]] bool ini
|
|||
}
|
||||
|
||||
*parent = ref->GetParent();
|
||||
*index = ref->GetIndex();
|
||||
index->Set(ref->GetIndex());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -456,10 +465,10 @@ ExpressionResult LogicalOrExpression::DoEvaluate(ScriptFrame& frame, DebugHint*)
|
|||
ExpressionResult FunctionCallExpression::DoEvaluate(ScriptFrame& frame, DebugHint*) const
|
||||
{
|
||||
Value self, vfunc;
|
||||
String index;
|
||||
RefIndex index;
|
||||
|
||||
if (m_FName->GetReference(frame, false, &self, &index))
|
||||
vfunc = VMOps::GetField(self, index, frame.Sandboxed, m_DebugInfo);
|
||||
vfunc = VMOps::GetField(self, index.Get(), frame.Sandboxed, m_DebugInfo);
|
||||
else {
|
||||
ExpressionResult vfuncres = m_FName->Evaluate(frame);
|
||||
CHECK_RESULT(vfuncres);
|
||||
|
|
@ -618,7 +627,7 @@ ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint)
|
|||
DebugHint *psdhint = dhint;
|
||||
|
||||
Value parent;
|
||||
String index;
|
||||
RefIndex index;
|
||||
|
||||
if (!m_Operand1->GetReference(frame, true, &parent, &index, &psdhint))
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Expression cannot be assigned to.", m_DebugInfo));
|
||||
|
|
@ -627,7 +636,7 @@ ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint)
|
|||
CHECK_RESULT(operand2);
|
||||
|
||||
if (m_Op != OpSetLiteral) {
|
||||
Value object = VMOps::GetField(parent, index, frame.Sandboxed, m_DebugInfo);
|
||||
Value object = VMOps::GetField(parent, index.Get(), frame.Sandboxed, m_DebugInfo);
|
||||
|
||||
switch (m_Op) {
|
||||
case OpSetAdd:
|
||||
|
|
@ -659,7 +668,7 @@ ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint)
|
|||
}
|
||||
}
|
||||
|
||||
VMOps::SetField(parent, index, operand2.GetValue(), m_DebugInfo);
|
||||
VMOps::SetField(parent, index.Get(), operand2.GetValue(), m_DebugInfo);
|
||||
|
||||
if (psdhint) {
|
||||
psdhint->AddMessage("=", m_DebugInfo);
|
||||
|
|
@ -747,10 +756,10 @@ ExpressionResult IndexerExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dh
|
|||
return VMOps::GetField(operand1.GetValue(), operand2.GetValue(), frame.Sandboxed, m_DebugInfo);
|
||||
}
|
||||
|
||||
bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const
|
||||
bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, RefIndex *index, DebugHint **dhint) const
|
||||
{
|
||||
Value vparent;
|
||||
String vindex;
|
||||
RefIndex vindex;
|
||||
DebugHint *psdhint = nullptr;
|
||||
bool free_psd = false;
|
||||
|
||||
|
|
@ -767,29 +776,35 @@ bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *
|
|||
|
||||
if (vparent.IsObject()) {
|
||||
Object::Ptr oparent = vparent;
|
||||
has_field = oparent->HasOwnField(vindex);
|
||||
has_field = oparent->HasOwnField(vindex.Get());
|
||||
}
|
||||
|
||||
if (has_field)
|
||||
old_value = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_Operand1->GetDebugInfo());
|
||||
old_value = VMOps::GetField(vparent, vindex.Get(), frame.Sandboxed, m_Operand1->GetDebugInfo());
|
||||
|
||||
if (old_value.IsEmpty() && !old_value.IsString())
|
||||
VMOps::SetField(vparent, vindex, new Dictionary(), m_Operand1->GetDebugInfo());
|
||||
VMOps::SetField(vparent, vindex.Get(), new Dictionary(), m_Operand1->GetDebugInfo());
|
||||
}
|
||||
|
||||
*parent = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_DebugInfo);
|
||||
*parent = VMOps::GetField(vparent, vindex.Get(), frame.Sandboxed, m_DebugInfo);
|
||||
free_psd = true;
|
||||
} else {
|
||||
ExpressionResult operand1 = m_Operand1->Evaluate(frame);
|
||||
*parent = operand1.GetValue();
|
||||
}
|
||||
|
||||
ExpressionResult operand2 = m_Operand2->Evaluate(frame);
|
||||
*index = operand2.GetValue();
|
||||
auto lit (dynamic_cast<LiteralExpression*>(m_Operand2.get()));
|
||||
|
||||
if (lit && lit->GetValue().IsString()) {
|
||||
index->Set(&lit->GetValue().Get<String>());
|
||||
} else {
|
||||
ExpressionResult operand2 = m_Operand2->Evaluate(frame);
|
||||
index->Set(operand2.GetValue());
|
||||
}
|
||||
|
||||
if (dhint) {
|
||||
if (psdhint)
|
||||
*dhint = new DebugHint(psdhint->GetChild(*index));
|
||||
*dhint = new DebugHint(psdhint->GetChild(index->Get()));
|
||||
else
|
||||
*dhint = nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,6 +177,37 @@ private:
|
|||
if (res.GetCode() == ResultBreak) \
|
||||
break; \
|
||||
|
||||
/**
|
||||
* Abstracts a maybe owned String
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
class RefIndex
|
||||
{
|
||||
public:
|
||||
RefIndex();
|
||||
RefIndex(const RefIndex&) = delete;
|
||||
RefIndex(RefIndex&&) = delete;
|
||||
RefIndex& operator=(const RefIndex&) = delete;
|
||||
RefIndex& operator=(RefIndex&&) = delete;
|
||||
|
||||
inline const String& Get() const noexcept
|
||||
{
|
||||
return *m_Foreign;
|
||||
}
|
||||
|
||||
inline void Set(const String* foreign) noexcept
|
||||
{
|
||||
m_Foreign = foreign;
|
||||
}
|
||||
|
||||
void Set(String own);
|
||||
|
||||
private:
|
||||
const String* m_Foreign;
|
||||
String m_Own;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*/
|
||||
|
|
@ -192,7 +223,13 @@ public:
|
|||
Expression& operator=(const Expression&) = delete;
|
||||
|
||||
ExpressionResult Evaluate(ScriptFrame& frame, DebugHint *dhint = nullptr) const;
|
||||
virtual bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint = nullptr) const;
|
||||
|
||||
/**
|
||||
* Caution! On return `*index` may point to a String somewhere in `this` (or subAST).
|
||||
* Keep `this` alive while using `*index`!
|
||||
*/
|
||||
virtual bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, RefIndex *index, DebugHint **dhint = nullptr) const;
|
||||
|
||||
virtual const DebugInfo& GetDebugInfo() const;
|
||||
|
||||
virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const = 0;
|
||||
|
|
@ -311,7 +348,7 @@ public:
|
|||
|
||||
protected:
|
||||
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
|
||||
bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const override;
|
||||
bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, RefIndex *index, DebugHint **dhint) const override;
|
||||
|
||||
private:
|
||||
String m_Variable;
|
||||
|
|
@ -329,7 +366,7 @@ public:
|
|||
|
||||
protected:
|
||||
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
|
||||
bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const override;
|
||||
bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, RefIndex *index, DebugHint **dhint) const override;
|
||||
};
|
||||
|
||||
class RefExpression final : public UnaryExpression
|
||||
|
|
@ -755,7 +792,7 @@ public:
|
|||
|
||||
protected:
|
||||
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
|
||||
bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const override;
|
||||
bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, RefIndex *index, DebugHint **dhint) const override;
|
||||
|
||||
friend void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue