]> granicus.if.org Git - icinga2/commitdiff
Allow anonymous functions to be garbage-collected.
authorGunnar Beutner <gunnar@beutner.name>
Wed, 2 Apr 2014 07:04:17 +0000 (09:04 +0200)
committerGunnar Beutner <gunnar@beutner.name>
Wed, 2 Apr 2014 15:27:04 +0000 (17:27 +0200)
Fixes #5921

lib/base/dynamicobject.cpp
lib/base/scriptfunction.cpp
lib/base/scriptfunction.h
lib/config/aexpression.cpp

index 11be09821ccff299c5cc5e2311811f9e2cf76bc5..929870b3ced9557a94340adca24b04a864b7a4e7 100644 (file)
@@ -233,15 +233,21 @@ Value DynamicObject::InvokeMethod(const String& method,
        if (!methods)
                BOOST_THROW_EXCEPTION(std::invalid_argument("Method '" + method + "' does not exist."));
 
-       String funcName = methods->Get(method);
+       Value funcName = methods->Get(method);
 
        if (funcName.IsEmpty())
                BOOST_THROW_EXCEPTION(std::invalid_argument("Method '" + method + "' does not exist."));
 
-       ScriptFunction::Ptr func = ScriptFunctionRegistry::GetInstance()->GetItem(funcName);
+       ScriptFunction::Ptr func;
 
-       if (!func)
-               BOOST_THROW_EXCEPTION(std::invalid_argument("Function '" + funcName + "' does not exist."));
+       if (funcName.IsObjectType<ScriptFunction>()) {
+               func = funcName;
+       } else {
+               func = ScriptFunction::GetByName(funcName);
+
+               if (!func)
+                       BOOST_THROW_EXCEPTION(std::invalid_argument("Function '" + String(funcName) + "' does not exist."));
+       }
 
        return func->Invoke(arguments);
 }
index 8b047cc2afacde0a098235746b562036fe72829b..8f392a1f4913310cdc1194d773e1b8e9b85a6d7d 100644 (file)
@@ -35,31 +35,27 @@ Value ScriptFunction::Invoke(const std::vector<Value>& arguments)
 
 ScriptFunction::Ptr ScriptFunction::GetByName(const String& name)
 {
-       return ScriptFunctionRegistry::GetInstance()->GetItem(name);
+       ScriptVariable::Ptr sv = ScriptVariable::GetByName(name);
+
+       if (!sv)
+               return ScriptFunction::Ptr();
+
+       return sv->GetData();
 }
 
-void ScriptFunction::Register(const String& name, const ScriptFunction::Callback& function)
+void ScriptFunction::Register(const String& name, const ScriptFunction::Ptr& function)
 {
-       ScriptVariable::Ptr sv = ScriptVariable::Set(name, name);
+       ScriptVariable::Ptr sv = ScriptVariable::Set(name, function);
        sv->SetConstant(true);
-
-       ScriptFunction::Ptr func = make_shared<ScriptFunction>(function);
-       ScriptFunctionRegistry::GetInstance()->Register(name, func);
 }
 
 void ScriptFunction::Unregister(const String& name)
 {
        ScriptVariable::Unregister(name);
-       ScriptFunctionRegistry::GetInstance()->Unregister(name);
 }
 
 RegisterFunctionHelper::RegisterFunctionHelper(const String& name, const ScriptFunction::Callback& function)
 {
-       ScriptFunction::Register(name, function);
-}
-
-ScriptFunctionRegistry *ScriptFunctionRegistry::GetInstance(void)
-{
-       return Singleton<ScriptFunctionRegistry>::GetInstance();
+       ScriptFunction::Register(name, make_shared<ScriptFunction>(function));
 }
 
index a5bd6a561dfc5f6c996c7e6cdc9d40f791ee946c..a9188c55910ce9b1a84f537927362e1a5324edca 100644 (file)
@@ -48,24 +48,13 @@ public:
        Value Invoke(const std::vector<Value>& arguments);
 
        static ScriptFunction::Ptr GetByName(const String& name);
-       static void Register(const String& name, const ScriptFunction::Callback& function);
+       static void Register(const String& name, const ScriptFunction::Ptr& function);
        static void Unregister(const String& name);
 
 private:
        Callback m_Callback;
 };
 
-/**
- * A registry for script functions.
- *
- * @ingroup base
- */
-class I2_BASE_API ScriptFunctionRegistry : public Registry<ScriptFunctionRegistry, ScriptFunction::Ptr>
-{
-public:
-       static ScriptFunctionRegistry *GetInstance(void);
-};
-
 /**
  * Helper class for registering ScriptFunction implementation classes.
  *
index e666027ee86f75b01b231b29429bdcb58d3dc14c..7f1f51b1950225da2db5214e6a12fba2794571ee 100644 (file)
@@ -248,8 +248,14 @@ Value AExpression::OpLogicalOr(const AExpression *expr, const Dictionary::Ptr& l
 
 Value AExpression::OpFunctionCall(const AExpression *expr, const Dictionary::Ptr& locals)
 {
-       String funcName = expr->EvaluateOperand1(locals);
-       ScriptFunction::Ptr func = ScriptFunction::GetByName(funcName);
+       Value funcName = expr->EvaluateOperand1(locals);
+
+       ScriptFunction::Ptr func;
+
+       if (funcName.IsObjectType<ScriptFunction>())
+               func = funcName;
+       else
+               func = ScriptFunction::GetByName(funcName);
 
        if (!func)
                BOOST_THROW_EXCEPTION(ConfigError("Function '" + funcName + "' does not exist."));
@@ -478,13 +484,13 @@ Value AExpression::OpFunction(const AExpression* expr, const Dictionary::Ptr& lo
        AExpression::Ptr aexpr = left->Get(1);
        String name = left->Get(0);
 
-       if (name.IsEmpty())
-               name = "__lambda" + Utility::NewUniqueID();
-
        Array::Ptr funcargs = expr->m_Operand2;
-       ScriptFunction::Callback callback = boost::bind(&AExpression::FunctionWrapper, _1, funcargs, aexpr, locals);
-       ScriptFunction::Register(name, callback);
-       return name;
+       ScriptFunction::Ptr func = make_shared<ScriptFunction>(boost::bind(&AExpression::FunctionWrapper, _1, funcargs, aexpr, locals));
+
+       if (!name.IsEmpty())
+               ScriptFunction::Register(name, func);
+
+       return func;
 }
 
 Value AExpression::OpApply(const AExpression* expr, const Dictionary::Ptr& locals)
@@ -538,4 +544,4 @@ Value AExpression::OpObject(const AExpression* expr, const Dictionary::Ptr& loca
        item->Compile()->Register();
 
        return Empty;
-}
\ No newline at end of file
+}