Implement prototype functions

fixes #8065
This commit is contained in:
Gunnar Beutner 2014-12-12 15:19:23 +01:00
parent 74d92b062a
commit aa38dde1fc
30 changed files with 633 additions and 51 deletions

View File

@ -23,13 +23,13 @@ mkclass_target(streamlogger.ti streamlogger.thpp)
mkclass_target(sysloglogger.ti sysloglogger.thpp)
set(base_SOURCES
application.cpp application-version.cpp application.thpp array.cpp console.cpp context.cpp
convert.cpp debuginfo.cpp dictionary.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
application.cpp application-version.cpp application.thpp array.cpp array-script.cpp boolean.cpp boolean-script.cpp console.cpp context.cpp
convert.cpp debuginfo.cpp dictionary.cpp dictionary-script.cpp dynamicobject.cpp dynamicobject.thpp dynamictype.cpp
exception.cpp fifo.cpp filelogger.cpp filelogger.thpp initialize.cpp json.cpp logger.cpp logger.thpp
netstring.cpp networkstream.cpp object.cpp primitivetype.cpp process.cpp
netstring.cpp networkstream.cpp number.cpp number-script.cpp object.cpp object-script.cpp primitivetype.cpp process.cpp
ringbuffer.cpp scripterror.cpp scriptfunction.cpp scriptfunctionwrapper.cpp scriptsignal.cpp
scriptutils.cpp scriptvariable.cpp serializer.cpp socket.cpp stacktrace.cpp
statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp
statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp string-script.cpp
sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp thinmutex.cpp threadpool.cpp timer.cpp
tlsstream.cpp tlsutility.cpp type.cpp unixsocket.cpp utility.cpp value.cpp
value-operators.cpp workqueue.cpp

93
lib/base/array-script.cpp Normal file
View File

@ -0,0 +1,93 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "base/array.hpp"
#include "base/scriptfunction.hpp"
#include "base/scriptfunctionwrapper.hpp"
#include "config/vmframe.hpp"
using namespace icinga;
static double ArrayLen(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
return self->GetLength();
}
static void ArraySet(int index, const Value& value)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
self->Set(index, value);
}
static void ArrayAdd(const Value& value)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
self->Add(value);
}
static void ArrayRemove(int index)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
self->Remove(index);
}
static bool ArrayContains(const Value& value)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
return self->Contains(value);
}
static void ArrayClear(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
self->Clear();
}
static void ArrayClone(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Array::Ptr self = static_cast<Array::Ptr>(vframe->Self);
self->ShallowClone();
}
Object::Ptr Array::GetPrototype(void)
{
static Dictionary::Ptr prototype;
if (!prototype) {
prototype = new Dictionary();
prototype->Set("len", new ScriptFunction(WrapScriptFunction(ArrayLen)));
prototype->Set("set", new ScriptFunction(WrapScriptFunction(ArraySet)));
prototype->Set("add", new ScriptFunction(WrapScriptFunction(ArrayAdd)));
prototype->Set("remove", new ScriptFunction(WrapScriptFunction(ArrayRemove)));
prototype->Set("contains", new ScriptFunction(WrapScriptFunction(ArrayContains)));
prototype->Set("clear", new ScriptFunction(WrapScriptFunction(ArrayClear)));
prototype->Set("clone", new ScriptFunction(WrapScriptFunction(ArrayClone)));
}
return prototype;
}

View File

@ -21,11 +21,12 @@
#include "base/objectlock.hpp"
#include "base/debug.hpp"
#include "base/primitivetype.hpp"
#include "base/dictionary.hpp"
#include <boost/foreach.hpp>
using namespace icinga;
REGISTER_PRIMITIVE_TYPE(Array);
REGISTER_PRIMITIVE_TYPE(Array, Array::GetPrototype());
/**
* Restrieves a value from an array.

View File

@ -65,6 +65,8 @@ public:
void CopyTo(const Array::Ptr& dest) const;
Array::Ptr ShallowClone(void) const;
static Object::Ptr GetPrototype(void);
private:
std::vector<Value> m_Data; /**< The data for the array. */
};

View File

@ -0,0 +1,46 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "base/boolean.hpp"
#include "base/convert.hpp"
#include "base/scriptfunction.hpp"
#include "base/scriptfunctionwrapper.hpp"
#include "config/vmframe.hpp"
using namespace icinga;
static String BooleanToString(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
bool self = vframe->Self;
return self ? "true" : "false";
}
Object::Ptr Boolean::GetPrototype(void)
{
static Dictionary::Ptr prototype;
if (!prototype) {
prototype = new Dictionary();
prototype->Set("to_string", new ScriptFunction(WrapScriptFunction(BooleanToString)));
}
return prototype;
}

26
lib/base/boolean.cpp Normal file
View File

@ -0,0 +1,26 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "base/boolean.hpp"
#include "base/primitivetype.hpp"
using namespace icinga;
REGISTER_BUILTIN_TYPE(Boolean, Boolean::GetPrototype());

44
lib/base/boolean.hpp Normal file
View File

@ -0,0 +1,44 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef BOOLEAN_H
#define BOOLEAN_H
#include "base/i2-base.hpp"
#include "base/object.hpp"
namespace icinga {
class Value;
/**
* Boolean class.
*/
class I2_BASE_API Boolean
{
public:
static Object::Ptr GetPrototype(void);
private:
Boolean(void);
};
}
#endif /* BOOLEAN_H */

View File

@ -0,0 +1,77 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "base/dictionary.hpp"
#include "base/scriptfunction.hpp"
#include "base/scriptfunctionwrapper.hpp"
#include "config/vmframe.hpp"
using namespace icinga;
static double DictionaryLen(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
return self->GetLength();
}
static void DictionarySet(const String& key, const Value& value)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
self->Set(key, value);
}
static void DictionaryRemove(const String& key)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
self->Remove(key);
}
static bool DictionaryContains(const String& key)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
return self->Contains(key);
}
static void DictionaryClone(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Dictionary::Ptr self = static_cast<Dictionary::Ptr>(vframe->Self);
self->ShallowClone();
}
Object::Ptr Dictionary::GetPrototype(void)
{
static Dictionary::Ptr prototype;
if (!prototype) {
prototype = new Dictionary();
prototype->Set("len", new ScriptFunction(WrapScriptFunction(DictionaryLen)));
prototype->Set("set", new ScriptFunction(WrapScriptFunction(DictionarySet)));
prototype->Set("remove", new ScriptFunction(WrapScriptFunction(DictionaryRemove)));
prototype->Set("contains", new ScriptFunction(WrapScriptFunction(DictionaryContains)));
prototype->Set("clone", new ScriptFunction(WrapScriptFunction(DictionaryClone)));
}
return prototype;
}

View File

@ -25,7 +25,7 @@
using namespace icinga;
REGISTER_PRIMITIVE_TYPE(Dictionary);
REGISTER_PRIMITIVE_TYPE(Dictionary, Dictionary::GetPrototype());
/**
* Compares dictionary keys using the less operator.

View File

@ -64,6 +64,8 @@ public:
void CopyTo(const Dictionary::Ptr& dest) const;
Dictionary::Ptr ShallowClone(void) const;
static Object::Ptr GetPrototype(void);
private:
std::map<String, Value> m_Data; /**< The data for the dictionary. */
};

View File

@ -0,0 +1,46 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "base/number.hpp"
#include "base/convert.hpp"
#include "base/scriptfunction.hpp"
#include "base/scriptfunctionwrapper.hpp"
#include "config/vmframe.hpp"
using namespace icinga;
static String NumberToString(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
double self = vframe->Self;
return Convert::ToString(self);
}
Object::Ptr Number::GetPrototype(void)
{
static Dictionary::Ptr prototype;
if (!prototype) {
prototype = new Dictionary();
prototype->Set("to_string", new ScriptFunction(WrapScriptFunction(NumberToString)));
}
return prototype;
}

26
lib/base/number.cpp Normal file
View File

@ -0,0 +1,26 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "base/number.hpp"
#include "base/primitivetype.hpp"
using namespace icinga;
REGISTER_BUILTIN_TYPE(Number, Number::GetPrototype());

44
lib/base/number.hpp Normal file
View File

@ -0,0 +1,44 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#ifndef NUMBER_H
#define NUMBER_H
#include "base/i2-base.hpp"
#include "base/object.hpp"
namespace icinga {
class Value;
/**
* Number class.
*/
class I2_BASE_API Number
{
public:
static Object::Ptr GetPrototype(void);
private:
Number(void);
};
}
#endif /* NUMBER_H */

View File

@ -0,0 +1,46 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "base/object.hpp"
#include "base/dictionary.hpp"
#include "base/scriptfunction.hpp"
#include "base/scriptfunctionwrapper.hpp"
#include "config/vmframe.hpp"
using namespace icinga;
static String ObjectToString(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
Object::Ptr self = static_cast<Object::Ptr>(vframe->Self);
return self->ToString();
}
Object::Ptr Object::GetPrototype(void)
{
static Dictionary::Ptr prototype;
if (!prototype) {
prototype = new Dictionary();
prototype->Set("to_string", new ScriptFunction(WrapScriptFunction(ObjectToString)));
}
return prototype;
}

View File

@ -19,12 +19,24 @@
#include "base/object.hpp"
#include "base/value.hpp"
#include "base/dictionary.hpp"
#include "base/primitivetype.hpp"
#include "base/utility.hpp"
using namespace icinga;
REGISTER_PRIMITIVE_TYPE(Object);
static Object::Ptr GetObjectPrototype(void)
{
static Dictionary::Ptr prototype;
if (!prototype) {
prototype = new Dictionary();
}
return prototype;
}
REGISTER_PRIMITIVE_TYPE(Object, GetObjectPrototype());
/**
* Default constructor for the Object class.

View File

@ -104,6 +104,8 @@ public:
void InflateMutex(void);
static Object::Ptr GetPrototype(void);
private:
Object(const Object& other);
Object& operator=(const Object& rhs);

View File

@ -18,12 +18,10 @@
******************************************************************************/
#include "base/primitivetype.hpp"
#include "base/dictionary.hpp"
using namespace icinga;
REGISTER_BUILTIN_TYPE(Number);
REGISTER_BUILTIN_TYPE(Boolean);
PrimitiveType::PrimitiveType(const String& name)
: m_Name(name)
{ }

View File

@ -46,21 +46,23 @@ private:
String m_Name;
};
#define REGISTER_BUILTIN_TYPE(type) \
#define REGISTER_BUILTIN_TYPE(type, prototype) \
namespace { namespace UNIQUE_NAME(prt) { namespace prt ## type { \
void RegisterBuiltinType(void) \
{ \
icinga::Type::Ptr t = new PrimitiveType(#type); \
t->SetPrototype(prototype); \
icinga::Type::Register(t); \
} \
INITIALIZE_ONCE(RegisterBuiltinType); \
} } }
#define REGISTER_PRIMITIVE_TYPE(type) \
#define REGISTER_PRIMITIVE_TYPE(type, prototype) \
namespace { namespace UNIQUE_NAME(prt) { namespace prt ## type { \
void RegisterPrimitiveType(void) \
{ \
icinga::Type::Ptr t = new PrimitiveType(#type); \
t->SetPrototype(prototype); \
icinga::Type::Register(t); \
type::TypeInstance = t; \
} \

View File

@ -20,10 +20,22 @@
#include "base/scriptfunction.hpp"
#include "base/scriptvariable.hpp"
#include "base/primitivetype.hpp"
#include "base/dictionary.hpp"
using namespace icinga;
REGISTER_PRIMITIVE_TYPE(ScriptFunction);
static Object::Ptr GetScriptFunctionPrototype(void)
{
static Dictionary::Ptr prototype;
if (!prototype) {
prototype = new Dictionary();
}
return prototype;
}
REGISTER_PRIMITIVE_TYPE(ScriptFunction, GetScriptFunctionPrototype());
ScriptFunction::ScriptFunction(const Callback& function)
: m_Callback(function)

View File

@ -0,0 +1,53 @@
/******************************************************************************
* Icinga 2 *
* Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org) *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software Foundation *
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
******************************************************************************/
#include "base/object.hpp"
#include "base/dictionary.hpp"
#include "base/scriptfunction.hpp"
#include "base/scriptfunctionwrapper.hpp"
#include "config/vmframe.hpp"
using namespace icinga;
static int StringLen(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
String self = vframe->Self;
return self.GetLength();
}
static String StringToString(void)
{
VMFrame *vframe = VMFrame::GetCurrentFrame();
return vframe->Self;
}
Object::Ptr String::GetPrototype(void)
{
static Dictionary::Ptr prototype;
if (!prototype) {
prototype = new Dictionary();
prototype->Set("len", new ScriptFunction(WrapScriptFunction(StringLen)));
prototype->Set("to_string", new ScriptFunction(WrapScriptFunction(StringToString)));
}
return prototype;
}

View File

@ -20,12 +20,13 @@
#include "base/string.hpp"
#include "base/value.hpp"
#include "base/primitivetype.hpp"
#include "base/dictionary.hpp"
#include <boost/algorithm/string/trim.hpp>
#include <ostream>
using namespace icinga;
REGISTER_BUILTIN_TYPE(String);
REGISTER_BUILTIN_TYPE(String, String::GetPrototype());
const String::SizeType String::NPos = std::string::npos;

View File

@ -21,6 +21,7 @@
#define STRING_H
#include "base/i2-base.hpp"
#include "base/object.hpp"
#include <boost/range/iterator.hpp>
#include <string.h>
#include <functional>
@ -246,6 +247,8 @@ public:
static const SizeType NPos;
static Object::Ptr GetPrototype(void);
private:
std::string m_Data;
};

View File

@ -74,3 +74,13 @@ bool Type::IsAssignableFrom(const Type::Ptr& other) const
return false;
}
Object::Ptr Type::GetPrototype(void) const
{
return m_Prototype;
}
void Type::SetPrototype(const Object::Ptr& object)
{
m_Prototype = object;
}

View File

@ -75,11 +75,17 @@ public:
bool IsAbstract(void) const;
Object::Ptr GetPrototype(void) const;
void SetPrototype(const Object::Ptr& object);
static void Register(const Type::Ptr& type);
static Type::Ptr GetByName(const String& name);
protected:
virtual ObjectFactory GetFactory(void) const = 0;
private:
Object::Ptr m_Prototype;
};
template<typename T>

View File

@ -85,3 +85,22 @@ String Value::GetTypeName(void) const
return "Invalid";
}
}
Type::Ptr Value::GetReflectionType(void) const
{
switch (GetType()) {
case ValueEmpty:
return Type::GetByName("Object");
case ValueNumber:
return Type::GetByName("Number");
case ValueBoolean:
return Type::GetByName("Boolean");
case ValueString:
return Type::GetByName("String");
case ValueObject:
return static_cast<Object::Ptr>(*this)->GetReflectionType();
default:
return Type::Ptr();
}
}

View File

@ -234,6 +234,8 @@ public:
String GetTypeName(void) const;
Type::Ptr GetReflectionType(void) const;
private:
boost::variant<boost::blank, double, bool, String, Object::Ptr> m_Value;

View File

@ -224,18 +224,13 @@ Value LogicalOrExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
Value FunctionCallExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
Object::Ptr self;
Value funcName;
Value self, funcName;
if (!m_IName.empty()) {
Value result = m_IName[0]->Evaluate(frame);
if (m_IName.size() == 2) {
if (!result.IsObject())
BOOST_THROW_EXCEPTION(ScriptError("Tried to invoke method on something that is not an Object.", GetDebugInfo()));
if (m_IName.size() == 2)
self = result;
}
for (int i = 1; i < m_IName.size(); i++) {
if (result.IsEmpty())
@ -244,12 +239,8 @@ Value FunctionCallExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
Value index = m_IName[i]->Evaluate(frame);
result = VMOps::GetField(result, index, GetDebugInfo());
if (i == m_IName.size() - 2) {
if (!result.IsObject())
BOOST_THROW_EXCEPTION(ScriptError("Tried to invoke method on something that is not an Object.", GetDebugInfo()));
if (i == m_IName.size() - 2)
self = result;
}
}
funcName = result;
@ -336,9 +327,12 @@ Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
psdhint = &sdhint;
}
if (i == 0)
parent = m_Local ? frame.Locals : frame.Self;
else
if (i == 0) {
if (m_Local)
parent = frame.Locals;
else
parent = frame.Self;
} else
parent = object;
if (i == m_Indexer.size() - 1) {

View File

@ -30,7 +30,7 @@ namespace icinga
struct VMFrame
{
Dictionary::Ptr Locals;
Object::Ptr Self;
Value Self;
VMFrame *NextFrame;
VMFrame(void)
@ -40,7 +40,7 @@ struct VMFrame
SetCurrentFrame(this);
}
VMFrame(const Object::Ptr& self)
VMFrame(const Value& self)
: Locals(new Dictionary()), Self(self)
{
NextFrame = GetCurrentFrame();

View File

@ -52,13 +52,13 @@ public:
if (frame.Locals && frame.Locals->Contains(name))
return frame.Locals->Get(name);
else if (frame.Locals != frame.Self && HasField(frame.Self, name))
else if (frame.Self.IsObject() && frame.Locals != static_cast<Object::Ptr>(frame.Self) && HasField(frame.Self, name))
return GetField(frame.Self, name, debugInfo);
else
return ScriptVariable::Get(name);
}
static inline Value FunctionCall(VMFrame& frame, const Object::Ptr& self, const Value& funcName, const std::vector<Value>& arguments)
static inline Value FunctionCall(VMFrame& frame, const Value& self, const Value& funcName, const std::vector<Value>& arguments)
{
ScriptFunction::Ptr func;
@ -72,7 +72,7 @@ public:
boost::shared_ptr<VMFrame> vframe;
if (self)
if (!self.IsEmpty())
vframe = boost::make_shared<VMFrame>(self); /* passes self to the callee using a TLS variable */
else
vframe = boost::make_shared<VMFrame>();
@ -232,30 +232,49 @@ public:
}
}
static inline Value GetPrototypeField(const Value& context, const String& field, const DebugInfo& debugInfo = DebugInfo())
{
Type::Ptr type = context.GetReflectionType();
do {
Object::Ptr object = type->GetPrototype();
if (HasField(object, field))
return GetField(object, field);
type = type->GetBaseType();
} while (type);
return Empty;
}
static inline Value GetField(const Value& context, const String& field, const DebugInfo& debugInfo = DebugInfo())
{
if (context.IsString()) {
String str = context;
int index = Convert::ToLong(field);
if (index < 0 || index >= str.GetLength())
BOOST_THROW_EXCEPTION(ScriptError("Index is out of bounds", debugInfo));
return String(1, str[index]);
}
if (!context.IsObject())
BOOST_THROW_EXCEPTION(ScriptError("Tried to access invalid field '" + field + "' on object of type '" + context.GetTypeName() + "'", debugInfo));
return GetPrototypeField(context, field);
Object::Ptr object = context;
Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(object);
if (dict)
return dict->Get(field);
if (dict) {
if (dict->Contains(field))
return dict->Get(field);
else
return GetPrototypeField(context, field);
}
Array::Ptr arr = dynamic_pointer_cast<Array>(object);
if (arr) {
int index = Convert::ToLong(field);
int index;
try {
index = Convert::ToLong(field);
} catch (...) {
return GetPrototypeField(context, field);
}
return arr->Get(index);
}
@ -267,7 +286,7 @@ public:
int fid = type->GetFieldId(field);
if (fid == -1)
return Empty;
return GetPrototypeField(context, field);
return object->GetField(fid);
}

View File

@ -294,10 +294,6 @@ BOOST_AUTO_TEST_CASE(advanced)
expr = ConfigCompiler::CompileText("<test>", "7 & 15 > 6");
BOOST_CHECK(expr->Evaluate(frame));
delete expr;
expr = ConfigCompiler::CompileText("<test>", "s = \"test\"; s[2]");
BOOST_CHECK(expr->Evaluate(frame) == "s");
delete expr;
}
BOOST_AUTO_TEST_SUITE_END()