summaryrefslogtreecommitdiffstats
path: root/lib/base/scriptframe.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:34:54 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:34:54 +0000
commit0915b3ef56dfac3113cce55a59a5765dc94976be (patch)
treea8fea11d50b4f083e1bf0f90025ece7f0824784a /lib/base/scriptframe.cpp
parentInitial commit. (diff)
downloadicinga2-0915b3ef56dfac3113cce55a59a5765dc94976be.tar.xz
icinga2-0915b3ef56dfac3113cce55a59a5765dc94976be.zip
Adding upstream version 2.13.6.upstream/2.13.6upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--lib/base/scriptframe.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/lib/base/scriptframe.cpp b/lib/base/scriptframe.cpp
new file mode 100644
index 0000000..8369e55
--- /dev/null
+++ b/lib/base/scriptframe.cpp
@@ -0,0 +1,130 @@
+/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
+
+#include "base/scriptframe.hpp"
+#include "base/scriptglobal.hpp"
+#include "base/namespace.hpp"
+#include "base/exception.hpp"
+#include "base/configuration.hpp"
+
+using namespace icinga;
+
+boost::thread_specific_ptr<std::stack<ScriptFrame *> > ScriptFrame::m_ScriptFrames;
+
+static auto l_InternalNSBehavior = new ConstNamespaceBehavior();
+
+/* Ensure that this gets called with highest priority
+ * and wins against other static initializers in lib/icinga, etc.
+ * LTO-enabled builds will cause trouble otherwise, see GH #6575.
+ */
+INITIALIZE_ONCE_WITH_PRIORITY([]() {
+ Namespace::Ptr globalNS = ScriptGlobal::GetGlobals();
+
+ auto systemNSBehavior = new ConstNamespaceBehavior();
+ systemNSBehavior->Freeze();
+ Namespace::Ptr systemNS = new Namespace(systemNSBehavior);
+ globalNS->SetAttribute("System", new ConstEmbeddedNamespaceValue(systemNS));
+
+ systemNS->SetAttribute("Configuration", new EmbeddedNamespaceValue(new Configuration()));
+
+ auto typesNSBehavior = new ConstNamespaceBehavior();
+ typesNSBehavior->Freeze();
+ Namespace::Ptr typesNS = new Namespace(typesNSBehavior);
+ globalNS->SetAttribute("Types", new ConstEmbeddedNamespaceValue(typesNS));
+
+ auto statsNSBehavior = new ConstNamespaceBehavior();
+ statsNSBehavior->Freeze();
+ Namespace::Ptr statsNS = new Namespace(statsNSBehavior);
+ globalNS->SetAttribute("StatsFunctions", new ConstEmbeddedNamespaceValue(statsNS));
+
+ Namespace::Ptr internalNS = new Namespace(l_InternalNSBehavior);
+ globalNS->SetAttribute("Internal", new ConstEmbeddedNamespaceValue(internalNS));
+}, 1000);
+
+INITIALIZE_ONCE_WITH_PRIORITY([]() {
+ l_InternalNSBehavior->Freeze();
+}, 0);
+
+ScriptFrame::ScriptFrame(bool allocLocals)
+ : Locals(allocLocals ? new Dictionary() : nullptr), Self(ScriptGlobal::GetGlobals()), Sandboxed(false), Depth(0)
+{
+ InitializeFrame();
+}
+
+ScriptFrame::ScriptFrame(bool allocLocals, Value self)
+ : Locals(allocLocals ? new Dictionary() : nullptr), Self(std::move(self)), Sandboxed(false), Depth(0)
+{
+ InitializeFrame();
+}
+
+void ScriptFrame::InitializeFrame()
+{
+ std::stack<ScriptFrame *> *frames = m_ScriptFrames.get();
+
+ if (frames && !frames->empty()) {
+ ScriptFrame *frame = frames->top();
+
+ Sandboxed = frame->Sandboxed;
+ }
+
+ PushFrame(this);
+}
+
+ScriptFrame::~ScriptFrame()
+{
+ ScriptFrame *frame = PopFrame();
+ ASSERT(frame == this);
+
+#ifndef I2_DEBUG
+ (void)frame;
+#endif /* I2_DEBUG */
+}
+
+void ScriptFrame::IncreaseStackDepth()
+{
+ if (Depth + 1 > 300)
+ BOOST_THROW_EXCEPTION(ScriptError("Stack overflow while evaluating expression: Recursion level too deep."));
+
+ Depth++;
+}
+
+void ScriptFrame::DecreaseStackDepth()
+{
+ Depth--;
+}
+
+ScriptFrame *ScriptFrame::GetCurrentFrame()
+{
+ std::stack<ScriptFrame *> *frames = m_ScriptFrames.get();
+
+ ASSERT(!frames->empty());
+ return frames->top();
+}
+
+ScriptFrame *ScriptFrame::PopFrame()
+{
+ std::stack<ScriptFrame *> *frames = m_ScriptFrames.get();
+
+ ASSERT(!frames->empty());
+
+ ScriptFrame *frame = frames->top();
+ frames->pop();
+
+ return frame;
+}
+
+void ScriptFrame::PushFrame(ScriptFrame *frame)
+{
+ std::stack<ScriptFrame *> *frames = m_ScriptFrames.get();
+
+ if (!frames) {
+ frames = new std::stack<ScriptFrame *>();
+ m_ScriptFrames.reset(frames);
+ }
+
+ if (!frames->empty()) {
+ ScriptFrame *parent = frames->top();
+ frame->Depth += parent->Depth;
+ }
+
+ frames->push(frame);
+}