using namespace icinga;
-REGISTER_PRIMITIVE_TYPE(Function, Function::GetPrototype());
+REGISTER_PRIMITIVE_TYPE_NOINST(Function, Function::GetPrototype());
Function::Function(const Callback& function)
: m_Callback(function)
using namespace icinga;
-PrimitiveType::PrimitiveType(const String& name)
- : m_Name(name)
+PrimitiveType::PrimitiveType(const String& name, const ObjectFactory& factory)
+ : m_Name(name), m_Factory(factory)
{ }
String PrimitiveType::GetName(void) const
ObjectFactory PrimitiveType::GetFactory(void) const
{
- return NULL;
+ return m_Factory;
}
class I2_BASE_API PrimitiveType : public Type
{
public:
- PrimitiveType(const String& name);
+ PrimitiveType(const String& name, const ObjectFactory& factory = ObjectFactory());
virtual String GetName(void) const;
virtual Type::Ptr GetBaseType(void) const;
private:
String m_Name;
+ ObjectFactory m_Factory;
};
#define REGISTER_BUILTIN_TYPE(type, prototype) \
INITIALIZE_ONCE_WITH_PRIORITY(RegisterBuiltinType, 15); \
} } }
-#define REGISTER_PRIMITIVE_TYPE(type, prototype) \
+#define REGISTER_PRIMITIVE_TYPE_FACTORY(type, prototype, factory) \
namespace { namespace UNIQUE_NAME(prt) { namespace prt ## type { \
void RegisterPrimitiveType(void) \
{ \
- icinga::Type::Ptr t = new PrimitiveType(#type); \
+ icinga::Type::Ptr t = new PrimitiveType(#type, factory);\
t->SetPrototype(prototype); \
icinga::Type::Register(t); \
type::TypeInstance = t; \
} } } \
DEFINE_TYPE_INSTANCE(type)
+#define REGISTER_PRIMITIVE_TYPE(type, prototype) \
+ REGISTER_PRIMITIVE_TYPE_FACTORY(type, prototype, DefaultObjectFactory<type>)
+
+#define REGISTER_PRIMITIVE_TYPE_NOINST(type, prototype) \
+ REGISTER_PRIMITIVE_TYPE_FACTORY(type, prototype, NULL)
+
}
#endif /* PRIMITIVETYPE_H */
vfunc = vfuncres.GetValue();
}
+ if (vfunc.IsObjectType<Type>()) {
+ if (m_Args.empty())
+ return VMOps::ConstructorCall(vfunc, m_DebugInfo);
+ else if (m_Args.size() == 1) {
+ ExpressionResult argres = m_Args[0]->Evaluate(frame);
+ CHECK_RESULT(argres);
+
+ return VMOps::CopyConstructorCall(vfunc, argres.GetValue(), m_DebugInfo);
+ } else
+ BOOST_THROW_EXCEPTION(ScriptError("Too many arguments for constructor.", m_DebugInfo));
+ }
+
if (!vfunc.IsObjectType<Function>())
BOOST_THROW_EXCEPTION(ScriptError("Argument is not a callable object.", m_DebugInfo));
return ScriptGlobal::Get(name);
}
+ static inline Value CopyConstructorCall(const Type::Ptr& type, const Value& value, const DebugInfo& debugInfo = DebugInfo())
+ {
+ if (type->GetName() == "String")
+ return Convert::ToString(value);
+ else if (type->GetName() == "Number")
+ return Convert::ToDouble(value);
+ else if (type->GetName() == "Boolean")
+ return Convert::ToBool(value);
+ else if (!type->IsAssignableFrom(value.GetReflectionType()))
+ BOOST_THROW_EXCEPTION(ScriptError("Invalid cast: Tried to cast object of type '" + value.GetReflectionType()->GetName() + "' to type '" + type->GetName() + "'", debugInfo));
+ else
+ return value;
+ }
+
+ static inline Value ConstructorCall(const Type::Ptr& type, const DebugInfo& debugInfo = DebugInfo())
+ {
+ if (type->GetName() == "String")
+ return "";
+ else if (type->GetName() == "Number")
+ return 0;
+ else if (type->GetName() == "Boolean")
+ return false;
+ else {
+ Object::Ptr object = type->Instantiate();
+
+ if (!object)
+ BOOST_THROW_EXCEPTION(ScriptError("Failed to instantiate object of type '" + type->GetName() + "'", debugInfo));
+
+ return object;
+ }
+ }
+
static inline Value FunctionCall(ScriptFrame& frame, const Value& self, const Function::Ptr& func, const std::vector<Value>& arguments)
{
boost::shared_ptr<ScriptFrame> vframe;