message = arguments[2];
}
- if (message.IsString())
+ if (message.IsString() || !message.IsObjectType<Array>() && !message.IsObjectType<Dictionary>())
::Log(severity, facility, message);
else
::Log(severity, facility, JsonEncode(message));
static void ExecuteExpression(Expression *expression)
{
- Dictionary::Ptr context = new Dictionary();
-
try {
- expression->Evaluate(context);
+ VMFrame frame;
+ expression->Evaluate(frame);
} catch (const ConfigError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
ApplyRule::ApplyRule(const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm,
- const DebugInfo& di, const Object::Ptr& scope)
+ const DebugInfo& di, const Dictionary::Ptr& scope)
: m_TargetType(targetType), m_Name(name), m_Expression(expression), m_Filter(filter), m_FKVar(fkvar),
m_FVVar(fvvar), m_FTerm(fterm), m_DebugInfo(di), m_Scope(scope), m_HasMatches(false)
{ }
return m_DebugInfo;
}
-Object::Ptr ApplyRule::GetScope(void) const
+Dictionary::Ptr ApplyRule::GetScope(void) const
{
return m_Scope;
}
void ApplyRule::AddRule(const String& sourceType, const String& targetType, const String& name,
const boost::shared_ptr<Expression>& expression, const boost::shared_ptr<Expression>& filter, const String& fkvar,
- const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Object::Ptr& scope)
+ const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Dictionary::Ptr& scope)
{
m_Rules[sourceType].push_back(ApplyRule(targetType, name, expression, filter, fkvar, fvvar, fterm, di, scope));
}
-bool ApplyRule::EvaluateFilter(const Object::Ptr& scope) const
+bool ApplyRule::EvaluateFilter(VMFrame& frame) const
{
- return m_Filter->Evaluate(scope).ToBool();
+ return m_Filter->Evaluate(frame).ToBool();
}
void ApplyRule::RegisterType(const String& sourceType, const std::vector<String>& targetTypes)
String GetFVVar(void) const;
boost::shared_ptr<Expression> GetFTerm(void) const;
DebugInfo GetDebugInfo(void) const;
- Object::Ptr GetScope(void) const;
+ Dictionary::Ptr GetScope(void) const;
void AddMatch(void);
bool HasMatches(void) const;
- bool EvaluateFilter(const Object::Ptr& scope) const;
+ bool EvaluateFilter(VMFrame& frame) const;
static void AddRule(const String& sourceType, const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
- const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Object::Ptr& scope);
+ const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm, const DebugInfo& di, const Dictionary::Ptr& scope);
static std::vector<ApplyRule>& GetRules(const String& type);
static void RegisterType(const String& sourceType, const std::vector<String>& targetTypes);
String m_FVVar;
boost::shared_ptr<Expression> m_FTerm;
DebugInfo m_DebugInfo;
- Object::Ptr m_Scope;
+ Dictionary::Ptr m_Scope;
bool m_HasMatches;
static TypeMap m_Types;
ApplyRule(const String& targetType, const String& name, const boost::shared_ptr<Expression>& expression,
const boost::shared_ptr<Expression>& filter, const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm,
- const DebugInfo& di, const Object::Ptr& scope);
+ const DebugInfo& di, const Dictionary::Ptr& scope);
};
}
true { yylval->num = 1; return T_NUMBER; }
false { yylval->num = 0; return T_NUMBER; }
const return T_CONST;
+local return T_LOCAL;
+use return T_USE;
apply return T_APPLY;
to return T_TO;
where return T_WHERE;
icinga::TypeSpecifier type;
std::vector<String> *slist;
std::vector<Expression *> *elist;
+ std::pair<String, Expression *> *cvitem;
+ std::map<String, Expression *> *cvlist;
}
%token T_NEWLINE "new-line"
%token T_GREATER_THAN "> (T_GREATER_THAN)"
%token T_CONST "const (T_CONST)"
+%token T_LOCAL "local (T_LOCAL)"
+%token T_USE "use (T_USE)"
%token <type> T_TYPE_DICTIONARY "dictionary (T_TYPE_DICTIONARY)"
%token <type> T_TYPE_ARRAY "array (T_TYPE_ARRAY)"
%token <type> T_TYPE_NUMBER "number (T_TYPE_NUMBER)"
%type <expr> apply
%type <expr> optional_rterm
%type <text> target_type_specifier
+%type <cvlist> use_specifier
+%type <cvlist> use_specifier_items
+%type <cvitem> use_specifier_item
%left T_LOGICAL_OR
%left T_LOGICAL_AND
static std::stack<TypeRuleList::Ptr> m_RuleLists;
static ConfigType::Ptr m_Type;
-static Dictionary::Ptr m_ModuleScope;
-
static std::stack<bool> m_Apply;
static std::stack<bool> m_ObjectAssign;
static std::stack<bool> m_SeenAssign;
Expression *ConfigCompiler::Compile(void)
{
- m_ModuleScope = new Dictionary();
-
m_Abstract = std::stack<bool>();
m_RuleLists = std::stack<TypeRuleList::Ptr>();
m_Type.reset();
constant: T_CONST identifier T_SET rterm sep
{
- ScriptVariable::Ptr sv = ScriptVariable::Set($2, $4->Evaluate(m_ModuleScope));
+ VMFrame frame;
+ ScriptVariable::Ptr sv = ScriptVariable::Set($2, $4->Evaluate(frame));
free($2);
delete $4;
m_Assign.push(NULL);
m_Ignore.push(NULL);
}
- object_declaration identifier rterm rterm_scope
+ object_declaration identifier rterm use_specifier rterm_scope
{
m_ObjectAssign.pop();
String type = $3;
free($3);
- DictExpression *exprl = dynamic_cast<DictExpression *>($5);
+ DictExpression *exprl = dynamic_cast<DictExpression *>($6);
exprl->MakeInline();
bool seen_assign = m_SeenAssign.top();
filter = assign;
}
- $$ = new ObjectExpression(abstract, type, $4, filter, context->GetZone(), exprl, DebugInfoRange(@2, @5));
+ $$ = new ObjectExpression(abstract, type, $4, filter, context->GetZone(), $5, exprl, DebugInfoRange(@2, @5));
}
;
}
;
-lterm: indexer combined_set_op rterm
+lterm: T_LOCAL indexer combined_set_op rterm
+ {
+ $$ = new SetExpression(*$2, $3, $4, true, DebugInfoRange(@1, @4));
+ delete $2;
+ }
+ | indexer combined_set_op rterm
{
- $$ = new SetExpression(*$1, $2, $3, DebugInfoRange(@1, @3));
+ $$ = new SetExpression(*$1, $2, $3, false, DebugInfoRange(@1, @3));
delete $1;
}
| T_INCLUDE rterm sep
{
- $$ = context->HandleInclude($2->Evaluate(m_ModuleScope), false, DebugInfoRange(@1, @2));
+ VMFrame frame;
+ $$ = context->HandleInclude($2->Evaluate(frame), false, DebugInfoRange(@1, @2));
delete $2;
}
| T_INCLUDE T_STRING_ANGLE
}
| T_INCLUDE_RECURSIVE rterm
{
- $$ = context->HandleIncludeRecursive($2->Evaluate(m_ModuleScope), "*.conf", DebugInfoRange(@1, @2));
+ VMFrame frame;
+ $$ = context->HandleIncludeRecursive($2->Evaluate(frame), "*.conf", DebugInfoRange(@1, @2));
delete $2;
}
| T_INCLUDE_RECURSIVE rterm ',' rterm
{
- $$ = context->HandleIncludeRecursive($2->Evaluate(m_ModuleScope), $4->Evaluate(m_ModuleScope), DebugInfoRange(@1, @4));
+ VMFrame frame;
+ $$ = context->HandleIncludeRecursive($2->Evaluate(frame), $4->Evaluate(frame), DebugInfoRange(@1, @4));
delete $2;
delete $4;
}
| T_IMPORT rterm
{
- Expression *avar = new VariableExpression("type", DebugInfoRange(@1, @2));
- $$ = new ImportExpression(avar, $2, DebugInfoRange(@1, @2));
+ $$ = new ImportExpression($2, DebugInfoRange(@1, @2));
}
| T_ASSIGN T_WHERE rterm
{
{
std::vector<Expression *> vname;
vname.push_back(MakeLiteral("__result"));
- $$ = new SetExpression(vname, OpSetLiteral, $2, DebugInfoRange(@1, @2));
+ $$ = new SetExpression(vname, OpSetLiteral, $2, false, DebugInfoRange(@1, @2));
}
| apply
{
| rterm T_MINUS rterm { MakeRBinaryOp<SubtractExpression>(&$$, $1, $3, @1, @3); }
| rterm T_MULTIPLY rterm { MakeRBinaryOp<MultiplyExpression>(&$$, $1, $3, @1, @3); }
| rterm T_DIVIDE_OP rterm { MakeRBinaryOp<DivideExpression>(&$$, $1, $3, @1, @3); }
- | T_FUNCTION identifier '(' identifier_items ')' rterm_scope
+ | T_FUNCTION identifier '(' identifier_items ')' use_specifier rterm_scope
{
- DictExpression *aexpr = dynamic_cast<DictExpression *>($6);
+ DictExpression *aexpr = dynamic_cast<DictExpression *>($7);
aexpr->MakeInline();
- $$ = new FunctionExpression($2, *$4, aexpr, DebugInfoRange(@1, @6));
+ $$ = new FunctionExpression($2, *$4, $6, aexpr, DebugInfoRange(@1, @6));
free($2);
delete $4;
}
- | T_FUNCTION '(' identifier_items ')' rterm_scope
+ | T_FUNCTION '(' identifier_items ')' use_specifier rterm_scope
{
- DictExpression *aexpr = dynamic_cast<DictExpression *>($5);
+ DictExpression *aexpr = dynamic_cast<DictExpression *>($6);
aexpr->MakeInline();
- $$ = new FunctionExpression("", *$3, aexpr, DebugInfoRange(@1, @5));
+ $$ = new FunctionExpression("", *$3, $5, aexpr, DebugInfoRange(@1, @5));
delete $3;
}
| T_SIGNAL identifier T_SET_ADD rterm
}
;
+use_specifier: /* empty */
+ {
+ $$ = NULL;
+ }
+ | T_USE '(' use_specifier_items ')'
+ {
+ $$ = $3;
+ }
+ ;
+
+use_specifier_items: use_specifier_item
+ {
+ $$ = new std::map<String, Expression *>();
+ $$->insert(*$1);
+ delete $1;
+ }
+ | use_specifier_items ',' use_specifier_item
+ {
+ $$ = $1;
+ $$->insert(*$3);
+ delete $3;
+ }
+ ;
+
+use_specifier_item: identifier
+ {
+ $$ = new std::pair<String, Expression *>($1, new VariableExpression($1, @1));
+ }
+ | identifier T_SET rterm
+ {
+ $$ = new std::pair<String, Expression *>($1, $3);
+ }
+ ;
+
apply_for_specifier: /* empty */
| T_APPLY_FOR '(' identifier T_FOLLOWS identifier T_IN rterm ')'
{
m_FVVar.push("");
m_FTerm.push(NULL);
}
- T_APPLY identifier optional_rterm apply_for_specifier target_type_specifier rterm
+ T_APPLY identifier optional_rterm apply_for_specifier target_type_specifier use_specifier rterm
{
m_Apply.pop();
BOOST_THROW_EXCEPTION(ConfigError("'apply' target type '" + target + "' is invalid") << errinfo_debuginfo(DebugInfoRange(@2, @5)));
}
- DictExpression *exprl = dynamic_cast<DictExpression *>($7);
+ DictExpression *exprl = dynamic_cast<DictExpression *>($8);
exprl->MakeInline();
// assign && !ignore
Expression *fterm = m_FTerm.top();
m_FTerm.pop();
- $$ = new ApplyExpression(type, target, $4, filter, fkvar, fvvar, fterm, exprl, DebugInfoRange(@2, @5));
+ $$ = new ApplyExpression(type, target, $4, filter, fkvar, fvvar, fterm, $7, exprl, DebugInfoRange(@2, @7));
}
;
ConfigItem::ConfigItem(const String& type, const String& name,
bool abstract, const boost::shared_ptr<Expression>& exprl,
const boost::shared_ptr<Expression>& filter,
- const DebugInfo& debuginfo, const Object::Ptr& scope,
+ const DebugInfo& debuginfo, const Dictionary::Ptr& scope,
const String& zone)
: m_Type(type), m_Name(name), m_Abstract(abstract),
m_Expression(exprl), m_Filter(filter),
return m_DebugInfo;
}
-Object::Ptr ConfigItem::GetScope(void) const
+Dictionary::Ptr ConfigItem::GetScope(void) const
{
return m_Scope;
}
dobj->SetDebugInfo(m_DebugInfo);
dobj->SetTypeName(m_Type);
dobj->SetZone(m_Zone);
-
- Dictionary::Ptr locals = new Dictionary();
- locals->Set("__parent", m_Scope);
-
- dobj->SetParentScope(locals);
- locals.reset();
-
dobj->SetName(m_Name);
DebugHint debugHints;
try {
- m_Expression->Evaluate(dobj, &debugHints);
+ VMFrame frame(dobj);
+ frame.Locals = m_Scope;
+ m_Expression->Evaluate(frame, &debugHints);
} catch (const ConfigError& ex) {
const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
const boost::shared_ptr<Expression>& exprl,
const boost::shared_ptr<Expression>& filter,
const DebugInfo& debuginfo,
- const Object::Ptr& scope, const String& zone);
+ const Dictionary::Ptr& scope, const String& zone);
String GetType(void) const;
String GetName(void) const;
void Register(void);
DebugInfo GetDebugInfo(void) const;
- Object::Ptr GetScope(void) const;
+ Dictionary::Ptr GetScope(void) const;
String GetZone(void) const;
boost::shared_ptr<Expression> m_Expression;
boost::shared_ptr<Expression> m_Filter;
DebugInfo m_DebugInfo; /**< Debug information. */
- Object::Ptr m_Scope; /**< variable scope. */
+ Dictionary::Ptr m_Scope; /**< variable scope. */
String m_Zone; /**< The zone. */
DynamicObject::Ptr m_Object;
m_Abstract = abstract;
}
-void ConfigItemBuilder::SetScope(const Object::Ptr& scope)
+void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
{
m_Scope = scope;
}
indexer.push_back(new LiteralExpression("templates"));
exprs.push_back(new SetExpression(indexer, OpSetAdd,
- new LiteralExpression(templateArray), m_DebugInfo));
+ new LiteralExpression(templateArray), false, m_DebugInfo));
DictExpression *dexpr = new DictExpression(m_Expressions, m_DebugInfo);
dexpr->MakeInline();
void SetType(const String& type);
void SetName(const String& name);
void SetAbstract(bool abstract);
- void SetScope(const Object::Ptr& scope);
+ void SetScope(const Dictionary::Ptr& scope);
void SetZone(const String& zone);
void AddExpression(Expression *expr);
std::vector<Expression *> m_Expressions; /**< Expressions for this item. */
boost::shared_ptr<Expression> m_Filter; /**< Filter expression. */
DebugInfo m_DebugInfo; /**< Debug information. */
- Object::Ptr m_Scope; /**< variable scope. */
+ Dictionary::Ptr m_Scope; /**< variable scope. */
String m_Zone; /**< The zone. */
};
<< " String name = (";
m_Name->GenerateCode(definitions, df);
df << ");" << "\n"
- << " String type = (";
- m_Type->GenerateCode(definitions, df);
- df << ");" << "\n"
+ << " String type = VMOps::GetField(context, \"type\");" << "\n"
<< "\n"
<< " ConfigItem::Ptr item = ConfigItem::GetObject(type, name);" << "\n"
<< "\n"
Expression::~Expression(void)
{ }
-Value Expression::Evaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value Expression::Evaluate(VMFrame& frame, DebugHint *dhint) const
{
try {
#ifdef _DEBUG
<< "Executing:\n" << msgbuf.str();*/
#endif /* _DEBUG */
- return DoEvaluate(context, dhint);
+ return DoEvaluate(frame, dhint);
} catch (const std::exception& ex) {
if (boost::get_error_info<boost::errinfo_nested_exception>(ex))
throw;
: m_Value(value)
{ }
-Value LiteralExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value LiteralExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
return m_Value;
}
return m_DebugInfo;
}
-Value VariableExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value VariableExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return VMOps::Variable(context, m_Variable);
+ return VMOps::Variable(frame, m_Variable);
}
-Value NegateExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value NegateExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return ~(long)m_Operand->Evaluate(context);
+ return ~(long)m_Operand->Evaluate(frame);
}
-Value LogicalNegateExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value LogicalNegateExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return !m_Operand->Evaluate(context).ToBool();
+ return !m_Operand->Evaluate(frame).ToBool();
}
-Value AddExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value AddExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) + m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) + m_Operand2->Evaluate(frame);
}
-Value SubtractExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value SubtractExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) - m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) - m_Operand2->Evaluate(frame);
}
-Value MultiplyExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value MultiplyExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) * m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) * m_Operand2->Evaluate(frame);
}
-Value DivideExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value DivideExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) / m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) / m_Operand2->Evaluate(frame);
}
-Value BinaryAndExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value BinaryAndExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) & m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) & m_Operand2->Evaluate(frame);
}
-Value BinaryOrExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value BinaryOrExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) | m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) | m_Operand2->Evaluate(frame);
}
-Value ShiftLeftExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value ShiftLeftExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) << m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) << m_Operand2->Evaluate(frame);
}
-Value ShiftRightExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value ShiftRightExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) >> m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) >> m_Operand2->Evaluate(frame);
}
-Value EqualExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value EqualExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) == m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) == m_Operand2->Evaluate(frame);
}
-Value NotEqualExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value NotEqualExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) != m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) != m_Operand2->Evaluate(frame);
}
-Value LessThanExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value LessThanExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) < m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) < m_Operand2->Evaluate(frame);
}
-Value GreaterThanExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value GreaterThanExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) > m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) > m_Operand2->Evaluate(frame);
}
-Value LessThanOrEqualExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value LessThanOrEqualExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) <= m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) <= m_Operand2->Evaluate(frame);
}
-Value GreaterThanOrEqualExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value GreaterThanOrEqualExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context) >= m_Operand2->Evaluate(context);
+ return m_Operand1->Evaluate(frame) >= m_Operand2->Evaluate(frame);
}
-Value InExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value InExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- Value right = m_Operand2->Evaluate(context);
+ Value right = m_Operand2->Evaluate(frame);
if (right.IsEmpty())
return false;
else if (!right.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right)));
- Value left = m_Operand1->Evaluate(context);
+ Value left = m_Operand1->Evaluate(frame);
Array::Ptr arr = right;
return arr->Contains(left);
}
-Value NotInExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value NotInExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- Value right = m_Operand2->Evaluate(context);
+ Value right = m_Operand2->Evaluate(frame);
if (right.IsEmpty())
return false;
else if (!right.IsObjectType<Array>())
BOOST_THROW_EXCEPTION(ConfigError("Invalid right side argument for 'in' operator: " + JsonEncode(right)));
- Value left = m_Operand1->Evaluate(context);
+ Value left = m_Operand1->Evaluate(frame);
Array::Ptr arr = right;
return !arr->Contains(left);
}
-Value LogicalAndExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value LogicalAndExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context).ToBool() && m_Operand2->Evaluate(context).ToBool();
+ return m_Operand1->Evaluate(frame).ToBool() && m_Operand2->Evaluate(frame).ToBool();
}
-Value LogicalOrExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value LogicalOrExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Operand1->Evaluate(context).ToBool() || m_Operand2->Evaluate(context).ToBool();
+ return m_Operand1->Evaluate(frame).ToBool() || m_Operand2->Evaluate(frame).ToBool();
}
-Value FunctionCallExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value FunctionCallExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- Value funcName = m_FName->Evaluate(context);
+ Value funcName = m_FName->Evaluate(frame);
std::vector<Value> arguments;
BOOST_FOREACH(Expression *arg, m_Args) {
- arguments.push_back(arg->Evaluate(context));
+ arguments.push_back(arg->Evaluate(frame));
}
- return VMOps::FunctionCall(context, funcName, arguments);
+ return VMOps::FunctionCall(frame, funcName, arguments);
}
-Value ArrayExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value ArrayExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
Array::Ptr result = new Array();
BOOST_FOREACH(Expression *aexpr, m_Expressions) {
- result->Add(aexpr->Evaluate(context));
+ result->Add(aexpr->Evaluate(frame));
}
return result;
}
-Value DictExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value DictExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- Dictionary::Ptr result = new Dictionary();
+ VMFrame *dframe;
+ VMFrame rframe;
- result->Set("__parent", context);
+ if (!m_Inline) {
+ dframe = &rframe;
+ rframe.Locals = frame.Locals;
+ rframe.Self = new Dictionary();
+ } else {
+ dframe = &frame;
+ }
BOOST_FOREACH(Expression *aexpr, m_Expressions) {
- Object::Ptr acontext = m_Inline ? context : result;
- aexpr->Evaluate(acontext, dhint);
-
- if (VMOps::HasField(acontext, "__result"))
- break;
+ aexpr->Evaluate(*dframe, dhint);
}
- Dictionary::Ptr xresult = result->ShallowClone();
- xresult->Remove("__parent");
- return xresult;
+ return dframe->Self;
}
-Value SetExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value SetExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
DebugHint *psdhint = dhint;
DebugHint sdhint;
for (Array::SizeType i = 0; i < m_Indexer.size(); i++) {
Expression *indexExpr = m_Indexer[i];
- String tempindex = indexExpr->Evaluate(context, dhint);
+ String tempindex = indexExpr->Evaluate(frame, dhint);
if (psdhint) {
sdhint = psdhint->GetChild(tempindex);
}
if (i == 0)
- parent = context;
+ parent = m_Local ? frame.Locals : frame.Self;
else
parent = object;
break;
}
- object = VMOps::Indexer(context, parent, tempindex);
+ object = VMOps::Indexer(frame, parent, tempindex);
if (i != m_Indexer.size() - 1 && object.IsEmpty()) {
object = new Dictionary();
}
}
- Value right = m_Operand2->Evaluate(context, dhint);
+ Value right = m_Operand2->Evaluate(frame, dhint);
if (m_Op != OpSetLiteral) {
Expression *lhs = MakeLiteral(object);
switch (m_Op) {
case OpSetAdd:
- right = AddExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint);
+ right = AddExpression(lhs, rhs, m_DebugInfo).Evaluate(frame, dhint);
break;
case OpSetSubtract:
- right = SubtractExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint);
+ right = SubtractExpression(lhs, rhs, m_DebugInfo).Evaluate(frame, dhint);
break;
case OpSetMultiply:
- right = MultiplyExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint);
+ right = MultiplyExpression(lhs, rhs, m_DebugInfo).Evaluate(frame, dhint);
break;
case OpSetDivide:
- right = DivideExpression(lhs, rhs, m_DebugInfo).Evaluate(context, dhint);
+ right = DivideExpression(lhs, rhs, m_DebugInfo).Evaluate(frame, dhint);
break;
default:
VERIFY(!"Invalid opcode.");
return right;
}
-Value IndexerExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value IndexerExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return VMOps::Indexer(context, m_Operand1->Evaluate(context), m_Operand2->Evaluate(context));
+ return VMOps::Indexer(frame, m_Operand1->Evaluate(frame), m_Operand2->Evaluate(frame));
}
-Value ImportExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value ImportExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- Value type = m_Type->Evaluate(context);
- Value name = m_Name->Evaluate(context);
+ String type = VMOps::GetField(frame.Self, "type");
+ Value name = m_Name->Evaluate(frame);
ConfigItem::Ptr item = ConfigItem::GetObject(type, name);
if (!item)
BOOST_THROW_EXCEPTION(ConfigError("Import references unknown template: '" + name + "'"));
- item->GetExpression()->Evaluate(context, dhint);
+ item->GetExpression()->Evaluate(frame, dhint);
return Empty;
}
-Value FunctionExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value FunctionExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return VMOps::NewFunction(context, m_Name, m_Args, m_Expression);
+ return VMOps::NewFunction(frame, m_Name, m_Args, m_ClosedVars, m_Expression);
}
-Value SlotExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value SlotExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return VMOps::NewSlot(context, m_Signal, m_Slot->Evaluate(context));
+ return VMOps::NewSlot(frame, m_Signal, m_Slot->Evaluate(frame));
}
-Value ApplyExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value ApplyExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return VMOps::NewApply(context, m_Type, m_Target, m_Name->Evaluate(context), m_Filter, m_FKVar, m_FVVar, m_FTerm, m_Expression, m_DebugInfo);
+ return VMOps::NewApply(frame, m_Type, m_Target, m_Name->Evaluate(frame), m_Filter,
+ m_FKVar, m_FVVar, m_FTerm, m_ClosedVars, m_Expression, m_DebugInfo);
}
-Value ObjectExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value ObjectExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
String name;
if (m_Name)
- name = m_Name->Evaluate(context, dhint);
+ name = m_Name->Evaluate(frame, dhint);
- return VMOps::NewObject(context, m_Abstract, m_Type, name, m_Filter, m_Zone,
- m_Expression, m_DebugInfo);
+ return VMOps::NewObject(frame, m_Abstract, m_Type, name, m_Filter, m_Zone,
+ m_ClosedVars, m_Expression, m_DebugInfo);
}
-Value ForExpression::DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+Value ForExpression::DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- Value value = m_Value->Evaluate(context, dhint);
+ Value value = m_Value->Evaluate(frame, dhint);
- return VMOps::For(context, m_FKVar, m_FVVar, m_Value->Evaluate(context), m_Expression, m_DebugInfo);
+ return VMOps::For(frame, m_FKVar, m_FVVar, m_Value->Evaluate(frame), m_Expression, m_DebugInfo);
}
#define EXPRESSION_H
#include "config/i2-config.hpp"
+#include "config/vmframe.hpp"
#include "base/debuginfo.hpp"
#include "base/array.hpp"
#include "base/dictionary.hpp"
public:
virtual ~Expression(void);
- Value Evaluate(const Object::Ptr& context, DebugHint *dhint = NULL) const;
+ Value Evaluate(VMFrame& frame, DebugHint *dhint = NULL) const;
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const = 0;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const = 0;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fp) const = 0;
virtual const DebugInfo& GetDebugInfo(void) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Expression->DoEvaluate(context, dhint);
+ return m_Expression->DoEvaluate(frame, dhint);
}
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fp) const
class I2_CONFIG_API NativeExpression : public Expression
{
public:
- typedef Value (*Callback)(const Object::Ptr& context);
+ typedef Value (*Callback)(VMFrame& frame);
NativeExpression(Callback callback)
: m_Callback(callback)
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const
{
- return m_Callback(context);
+ return m_Callback(frame);
}
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fp) const
LiteralExpression(const Value& value = Value());
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fp) const;
private:
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
}
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
public:
}
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
void MakeInline(void);
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
class I2_CONFIG_API SetExpression : public DebuggableExpression
{
public:
- SetExpression(const std::vector<Expression *>& indexer, CombinedSetOp op, Expression *operand2, const DebugInfo& debugInfo = DebugInfo())
- : DebuggableExpression(debugInfo), m_Op(op), m_Indexer(indexer), m_Operand2(operand2)
+ SetExpression(const std::vector<Expression *>& indexer, CombinedSetOp op, Expression *operand2, bool local, const DebugInfo& debugInfo = DebugInfo())
+ : DebuggableExpression(debugInfo), m_Op(op), m_Indexer(indexer), m_Operand2(operand2), m_Local(local)
{ }
~SetExpression(void)
}
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
CombinedSetOp m_Op;
std::vector<Expression *> m_Indexer;
Expression *m_Operand2;
+ bool m_Local;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
};
class I2_CONFIG_API ImportExpression : public DebuggableExpression
{
public:
- ImportExpression(Expression *type, Expression *name, const DebugInfo& debugInfo = DebugInfo())
- : DebuggableExpression(debugInfo), m_Type(type), m_Name(name)
+ ImportExpression(Expression *name, const DebugInfo& debugInfo = DebugInfo())
+ : DebuggableExpression(debugInfo), m_Name(name)
{ }
~ImportExpression(void)
{
- delete m_Type;
delete m_Name;
}
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
- Expression *m_Type;
Expression *m_Name;
};
class I2_CONFIG_API FunctionExpression : public DebuggableExpression
{
public:
- FunctionExpression(const String& name, const std::vector<String>& args, Expression *expression, const DebugInfo& debugInfo = DebugInfo())
- : DebuggableExpression(debugInfo), m_Name(name), m_Args(args), m_Expression(expression)
+ FunctionExpression(const String& name, const std::vector<String>& args,
+ std::map<String, Expression *> *closedVars, Expression *expression, const DebugInfo& debugInfo = DebugInfo())
+ : DebuggableExpression(debugInfo), m_Name(name), m_Args(args), m_ClosedVars(closedVars), m_Expression(expression)
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
String m_Name;
std::vector<String> m_Args;
+ std::map<String, Expression *> *m_ClosedVars;
boost::shared_ptr<Expression> m_Expression;
};
{ }
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
public:
ApplyExpression(const String& type, const String& target, Expression *name,
Expression *filter, const String& fkvar, const String& fvvar,
- Expression *fterm, Expression *expression, const DebugInfo& debugInfo = DebugInfo())
+ Expression *fterm, std::map<String, Expression *> *closedVars,
+ Expression *expression, const DebugInfo& debugInfo = DebugInfo())
: DebuggableExpression(debugInfo), m_Type(type), m_Target(target),
m_Name(name), m_Filter(filter), m_FKVar(fkvar), m_FVVar(fvvar),
- m_FTerm(fterm), m_Expression(expression)
+ m_FTerm(fterm), m_ClosedVars(closedVars), m_Expression(expression)
{ }
~ApplyExpression(void)
}
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
String m_FKVar;
String m_FVVar;
boost::shared_ptr<Expression> m_FTerm;
+ std::map<String, Expression *> *m_ClosedVars;
boost::shared_ptr<Expression> m_Expression;
};
-
+
class I2_CONFIG_API ObjectExpression : public DebuggableExpression
{
public:
- ObjectExpression(bool abstract, const String& type, Expression *name, Expression *filter, const String& zone, Expression *expression, const DebugInfo& debugInfo = DebugInfo())
- : DebuggableExpression(debugInfo), m_Abstract(abstract), m_Type(type), m_Name(name), m_Filter(filter), m_Zone(zone), m_Expression(expression)
+ ObjectExpression(bool abstract, const String& type, Expression *name, Expression *filter,
+ const String& zone, std::map<String, Expression *> *closedVars,
+ Expression *expression, const DebugInfo& debugInfo = DebugInfo())
+ : DebuggableExpression(debugInfo), m_Abstract(abstract), m_Type(type),
+ m_Name(name), m_Filter(filter), m_Zone(zone), m_ClosedVars(closedVars), m_Expression(expression)
{ }
~ObjectExpression(void)
}
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
Expression *m_Name;
boost::shared_ptr<Expression> m_Filter;
String m_Zone;
+ std::map<String, Expression *> *m_ClosedVars;
boost::shared_ptr<Expression> m_Expression;
};
}
protected:
- virtual Value DoEvaluate(const Object::Ptr& context, DebugHint *dhint) const;
+ virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const;
virtual void GenerateCode(DefinitionMap& definitions, std::ostream& fpg) const;
private:
--- /dev/null
+/******************************************************************************
+* 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 VMFRAME_H
+#define VMFRAME_H
+
+#include "config/i2-config.hpp"
+#include "base/dictionary.hpp"
+
+namespace icinga
+{
+
+struct VMFrame
+{
+ Dictionary::Ptr Locals;
+ Object::Ptr Self;
+ Value Result;
+
+ VMFrame(void)
+ : Locals(new Dictionary()), Self(Locals)
+ { }
+
+ VMFrame(const Object::Ptr& self)
+ : Locals(new Dictionary()), Self(self)
+ { }
+};
+
+}
+
+#endif /* VMOPS_H */
class VMOps
{
public:
- static inline Value Variable(const Object::Ptr& context, const String& name)
+ static inline Value Variable(VMFrame& frame, const String& name)
{
- Object::Ptr scope = context;
+ if (name == "this")
+ return frame.Self;
- while (scope) {
- if (HasField(scope, name))
- return GetField(scope, name);
-
- scope = GetField(scope, "__parent");
- }
-
- return ScriptVariable::Get(name);
+ if (frame.Locals && frame.Locals->Contains(name))
+ return frame.Locals->Get(name);
+ else if (frame.Locals != frame.Self && HasField(frame.Self, name))
+ return GetField(frame.Self, name);
+ else
+ return ScriptVariable::Get(name);
}
- static inline Value FunctionCall(const Object::Ptr& context, const Value& funcName, const std::vector<Value>& arguments)
+ static inline Value FunctionCall(VMFrame& frame, const Value& funcName, const std::vector<Value>& arguments)
{
ScriptFunction::Ptr func;
return func->Invoke(arguments);
}
- static inline Value Indexer(const Object::Ptr& context, const Value& value, const String& index)
+ static inline Value Indexer(VMFrame& frame, const Value& value, const String& index)
{
if (value.IsObjectType<Dictionary>()) {
Dictionary::Ptr dict = value;
}
}
- static inline Value NewFunction(const Object::Ptr& context, const String& name, const std::vector<String>& args, const boost::shared_ptr<Expression>& expression)
+ static inline Value NewFunction(VMFrame& frame, const String& name, const std::vector<String>& args,
+ std::map<String, Expression *> *closedVars, const boost::shared_ptr<Expression>& expression)
{
- ScriptFunction::Ptr func = new ScriptFunction(boost::bind(&FunctionWrapper, _1, args, expression, context));
+ ScriptFunction::Ptr func = new ScriptFunction(boost::bind(&FunctionWrapper, _1, args,
+ EvaluateClosedVars(frame, closedVars), expression));
if (!name.IsEmpty())
ScriptFunction::Register(name, func);
return func;
}
- static inline Value NewSlot(const Object::Ptr& context, const String& signal, const Value& slot)
+ static inline Value NewSlot(VMFrame& frame, const String& signal, const Value& slot)
{
ScriptSignal::Ptr sig = ScriptSignal::GetByName(signal);
return Empty;
}
- static inline Value NewApply(const Object::Ptr& context, const String& type, const String& target, const String& name, const boost::shared_ptr<Expression>& filter,
- const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm,
+ static inline Value NewApply(VMFrame& frame, const String& type, const String& target, const String& name, const boost::shared_ptr<Expression>& filter,
+ const String& fkvar, const String& fvvar, const boost::shared_ptr<Expression>& fterm, std::map<String, Expression *> *closedVars,
const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
{
- ApplyRule::AddRule(type, target, name, expression, filter, fkvar, fvvar, fterm, debugInfo, context);
+ ApplyRule::AddRule(type, target, name, expression, filter, fkvar,
+ fvvar, fterm, debugInfo, EvaluateClosedVars(frame, closedVars));
return Empty;
}
- static inline Value NewObject(const Object::Ptr& context, bool abstract, const String& type, const String& name, const boost::shared_ptr<Expression>& filter,
- const String& zone, const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
+ static inline Value NewObject(VMFrame& frame, bool abstract, const String& type, const String& name, const boost::shared_ptr<Expression>& filter,
+ const String& zone, std::map<String, Expression *> *closedVars, const boost::shared_ptr<Expression>& expression, const DebugInfo& debugInfo = DebugInfo())
{
ConfigItemBuilder::Ptr item = new ConfigItemBuilder(debugInfo);
item->AddExpression(new OwnedExpression(expression));
item->SetAbstract(abstract);
- item->SetScope(context);
+ item->SetScope(EvaluateClosedVars(frame, closedVars));
item->SetZone(zone);
item->SetFilter(filter);
item->Compile()->Register();
return Empty;
}
- static inline Value For(const Object::Ptr& context, const String& fkvar, const String& fvvar, const Value& value, Expression *expression, const DebugInfo& debugInfo = DebugInfo())
+ static inline Value For(VMFrame& frame, const String& fkvar, const String& fvvar, const Value& value, Expression *expression, const DebugInfo& debugInfo = DebugInfo())
{
if (value.IsObjectType<Array>()) {
if (!fvvar.IsEmpty())
ObjectLock olock(arr);
BOOST_FOREACH(const Value& value, arr) {
- Dictionary::Ptr xcontext = new Dictionary();
- xcontext->Set("__parent", context);
- xcontext->Set(fkvar, value);
-
- expression->Evaluate(xcontext);
+ frame.Locals->Set(fkvar, value);
+ expression->Evaluate(frame);
}
- }
- else if (value.IsObjectType<Dictionary>()) {
+ } else if (value.IsObjectType<Dictionary>()) {
if (fvvar.IsEmpty())
BOOST_THROW_EXCEPTION(ConfigError("Cannot use array iterator for dictionary.") << errinfo_debuginfo(debugInfo));
ObjectLock olock(dict);
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
- Dictionary::Ptr xcontext = new Dictionary();
- xcontext->Set("__parent", context);
- xcontext->Set(fkvar, kv.first);
- xcontext->Set(fvvar, kv.second);
-
- expression->Evaluate(xcontext);
+ frame.Locals->Set(fkvar, kv.first);
+ frame.Locals->Set(fvvar, kv.second);
+ expression->Evaluate(frame);
}
}
else
private:
static inline Value FunctionWrapper(const std::vector<Value>& arguments,
- const std::vector<String>& funcargs, const boost::shared_ptr<Expression>& expr, const Object::Ptr& scope)
+ const std::vector<String>& funcargs, const Dictionary::Ptr& closedVars, const boost::shared_ptr<Expression>& expr)
{
if (arguments.size() < funcargs.size())
BOOST_THROW_EXCEPTION(ConfigError("Too few arguments for function"));
- Dictionary::Ptr context = new Dictionary();
- context->Set("__parent", scope);
+ VMFrame frame;
+
+ if (closedVars)
+ closedVars->CopyTo(frame.Locals);
for (std::vector<Value>::size_type i = 0; i < std::min(arguments.size(), funcargs.size()); i++)
- context->Set(funcargs[i], arguments[i]);
+ frame.Locals->Set(funcargs[i], arguments[i]);
- expr->Evaluate(context);
- return context->Get("__result");
+ expr->Evaluate(frame);
+ return frame.Result;
}
- static void SlotWrapper(const Value& funcName, const std::vector<Value>& arguments)
+ static inline void SlotWrapper(const Value& funcName, const std::vector<Value>& arguments)
{
ScriptFunction::Ptr func;
func->Invoke(arguments);
}
+
+ static inline Dictionary::Ptr EvaluateClosedVars(VMFrame& frame, std::map<String, Expression *> *closedVars)
+ {
+ Dictionary::Ptr locals;
+
+ if (closedVars) {
+ locals = new Dictionary();
+
+ typedef std::pair<String, Expression *> ClosedVar;
+ BOOST_FOREACH(const ClosedVar& cvar, *closedVars) {
+ locals->Set(cvar.first, cvar.second->Evaluate(frame));
+ }
+ }
+
+ return locals;
+ }
};
}
ApplyRule::RegisterType("Dependency", targets);
}
-void Dependency::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
+void Dependency::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, VMFrame& frame, const ApplyRule& rule)
{
DebugInfo di = rule.GetDebugInfo();
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di);
builder->SetType("Dependency");
builder->SetName(name);
- builder->SetScope(locals);
+ builder->SetScope(frame.Locals);
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
- builder->AddExpression(new SetExpression(MakeIndexer("parent_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
- builder->AddExpression(new SetExpression(MakeIndexer("child_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("parent_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), false, di));
+ builder->AddExpression(new SetExpression(MakeIndexer("child_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), false, di));
if (service)
- builder->AddExpression(new SetExpression(MakeIndexer("child_service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("child_service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), false, di));
String zone = checkable->GetZone();
if (!zone.IsEmpty())
- builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), false, di));
builder->AddExpression(new OwnedExpression(rule.GetExpression()));
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
- Dictionary::Ptr locals = new Dictionary();
- locals->Set("__parent", rule.GetScope());
- locals->Set("host", host);
+ VMFrame frame;
+ if (rule.GetScope())
+ rule.GetScope()->CopyTo(frame.Locals);
+ frame.Locals->Set("host", host);
if (service)
- locals->Set("service", service);
+ frame.Locals->Set("service", service);
- if (!rule.EvaluateFilter(locals))
+ if (!rule.EvaluateFilter(frame))
return false;
Value vinstances;
if (rule.GetFTerm()) {
- vinstances = rule.GetFTerm()->Evaluate(locals);
+ vinstances = rule.GetFTerm()->Evaluate(frame);
} else {
Array::Ptr instances = new Array();
instances->Add("");
String name = rule.GetName();
if (!rule.GetFKVar().IsEmpty()) {
- locals->Set(rule.GetFKVar(), instance);
+ frame.Locals->Set(rule.GetFKVar(), instance);
name += instance;
}
- EvaluateApplyRuleInstance(checkable, name, locals, rule);
+ EvaluateApplyRuleInstance(checkable, name, frame, rule);
}
} else if (vinstances.IsObjectType<Dictionary>()) {
if (rule.GetFVVar().IsEmpty())
ObjectLock olock(dict);
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
- locals->Set(rule.GetFKVar(), kv.first);
- locals->Set(rule.GetFVVar(), kv.second);
+ frame.Locals->Set(rule.GetFKVar(), kv.first);
+ frame.Locals->Set(rule.GetFVVar(), kv.second);
- EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, locals, rule);
+ EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, frame, rule);
}
}
{
class ApplyRule;
+class VMFrame;
class Host;
class Service;
Checkable::Ptr m_Parent;
Checkable::Ptr m_Child;
- static void EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
+ static void EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, VMFrame& frame, const ApplyRule& rule);
static bool EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule);
};
CONTEXT("Evaluating rule for group '" + group_name + "'");
- Dictionary::Ptr locals = new Dictionary();
- locals->Set("__parent", group->GetScope());
- locals->Set("host", host);
+ VMFrame frame;
+ if (group->GetScope())
+ group->GetScope()->CopyTo(frame.Locals);
+ frame.Locals->Set("host", host);
- if (!group->GetFilter()->Evaluate(locals))
+ if (!group->GetFilter()->Evaluate(frame))
return false;
Log(LogDebug, "HostGroup")
ApplyRule::RegisterType("Notification", targets);
}
-void Notification::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
+void Notification::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, VMFrame& frame, const ApplyRule& rule)
{
DebugInfo di = rule.GetDebugInfo();
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di);
builder->SetType("Notification");
builder->SetName(name);
- builder->SetScope(locals);
+ builder->SetScope(frame.Locals);
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
- builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), false, di));
if (service)
- builder->AddExpression(new SetExpression(MakeIndexer("service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), false, di));
String zone = checkable->GetZone();
if (!zone.IsEmpty())
- builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), false, di));
builder->AddExpression(new OwnedExpression(rule.GetExpression()));
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
- Dictionary::Ptr locals = new Dictionary();
- locals->Set("__parent", rule.GetScope());
- locals->Set("host", host);
+ VMFrame frame;
+ if (rule.GetScope())
+ rule.GetScope()->CopyTo(frame.Locals);
+ frame.Locals->Set("host", host);
if (service)
- locals->Set("service", service);
+ frame.Locals->Set("service", service);
- if (!rule.EvaluateFilter(locals))
+ if (!rule.EvaluateFilter(frame))
return false;
Value vinstances;
if (rule.GetFTerm()) {
- vinstances = rule.GetFTerm()->Evaluate(locals);
+ vinstances = rule.GetFTerm()->Evaluate(frame);
} else {
Array::Ptr instances = new Array();
instances->Add("");
String name = rule.GetName();
if (!rule.GetFKVar().IsEmpty()) {
- locals->Set(rule.GetFKVar(), instance);
+ frame.Locals->Set(rule.GetFKVar(), instance);
name += instance;
}
- EvaluateApplyRuleInstance(checkable, name, locals, rule);
+ EvaluateApplyRuleInstance(checkable, name, frame, rule);
}
} else if (vinstances.IsObjectType<Dictionary>()) {
if (rule.GetFVVar().IsEmpty())
ObjectLock olock(dict);
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
- locals->Set(rule.GetFKVar(), kv.first);
- locals->Set(rule.GetFVVar(), kv.second);
+ frame.Locals->Set(rule.GetFKVar(), kv.first);
+ frame.Locals->Set(rule.GetFVVar(), kv.second);
- EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, locals, rule);
+ EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, frame, rule);
}
}
class NotificationCommand;
class Checkable;
class ApplyRule;
+class VMFrame;
class Host;
class Service;
private:
void ExecuteNotificationHelper(NotificationType type, const User::Ptr& user, const CheckResult::Ptr& cr, bool force, const String& author = "", const String& text = "");
- static void EvaluateApplyRuleInstance(const intrusive_ptr<Checkable>& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
+ static void EvaluateApplyRuleInstance(const intrusive_ptr<Checkable>& checkable, const String& name, VMFrame& frame, const ApplyRule& rule);
static bool EvaluateApplyRule(const intrusive_ptr<Checkable>& checkable, const ApplyRule& rule);
};
ApplyRule::RegisterType("ScheduledDowntime", targets);
}
-void ScheduledDowntime::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
+void ScheduledDowntime::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, VMFrame& frame, const ApplyRule& rule)
{
DebugInfo di = rule.GetDebugInfo();
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di);
builder->SetType("ScheduledDowntime");
builder->SetName(name);
- builder->SetScope(locals);
+ builder->SetScope(frame.Locals);
Host::Ptr host;
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
- builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), false, di));
if (service)
- builder->AddExpression(new SetExpression(MakeIndexer("service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), false, di));
String zone = checkable->GetZone();
- if (!zone.IsEmpty()) {
- builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di));
- }
+ if (!zone.IsEmpty())
+ builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), false, di));
builder->AddExpression(new OwnedExpression(rule.GetExpression()));
Service::Ptr service;
tie(host, service) = GetHostService(checkable);
- Dictionary::Ptr locals = new Dictionary();
- locals->Set("__parent", rule.GetScope());
- locals->Set("host", host);
+ VMFrame frame;
+ if (rule.GetScope())
+ rule.GetScope()->CopyTo(frame.Locals);
+ frame.Locals->Set("host", host);
if (service)
- locals->Set("service", service);
+ frame.Locals->Set("service", service);
- if (!rule.EvaluateFilter(locals))
+ if (!rule.EvaluateFilter(frame))
return false;
Value vinstances;
if (rule.GetFTerm()) {
- vinstances = rule.GetFTerm()->Evaluate(locals);
+ vinstances = rule.GetFTerm()->Evaluate(frame);
} else {
Array::Ptr instances = new Array();
instances->Add("");
String name = rule.GetName();
if (!rule.GetFKVar().IsEmpty()) {
- locals->Set(rule.GetFKVar(), instance);
+ frame.Locals->Set(rule.GetFKVar(), instance);
name += instance;
}
- EvaluateApplyRuleInstance(checkable, name, locals, rule);
+ EvaluateApplyRuleInstance(checkable, name, frame, rule);
}
} else if (vinstances.IsObjectType<Dictionary>()) {
if (rule.GetFVVar().IsEmpty())
ObjectLock olock(dict);
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
- locals->Set(rule.GetFKVar(), kv.first);
- locals->Set(rule.GetFVVar(), kv.second);
+ frame.Locals->Set(rule.GetFKVar(), kv.first);
+ frame.Locals->Set(rule.GetFVVar(), kv.second);
- EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, locals, rule);
+ EvaluateApplyRuleInstance(checkable, rule.GetName() + kv.first, frame, rule);
}
}
{
class ApplyRule;
+class VMFrame;
class Host;
class Service;
std::pair<double, double> FindNextSegment(void);
void CreateNextDowntime(void);
- static void EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
+ static void EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, VMFrame& frame, const ApplyRule& rule);
static bool EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule);
};
ApplyRule::RegisterType("Service", targets);
}
-void Service::EvaluateApplyRuleInstance(const Host::Ptr& host, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule)
+void Service::EvaluateApplyRuleInstance(const Host::Ptr& host, const String& name, VMFrame& frame, const ApplyRule& rule)
{
DebugInfo di = rule.GetDebugInfo();
ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di);
builder->SetType("Service");
builder->SetName(name);
- builder->SetScope(locals);
+ builder->SetScope(frame.Locals);
- builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), false, di));
- builder->AddExpression(new SetExpression(MakeIndexer("name"), OpSetLiteral, MakeLiteral(name), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("name"), OpSetLiteral, MakeLiteral(name), false, di));
String zone = host->GetZone();
if (!zone.IsEmpty())
- builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di));
+ builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), false, di));
builder->AddExpression(new OwnedExpression(rule.GetExpression()));
msgbuf << "Evaluating 'apply' rule (" << di << ")";
CONTEXT(msgbuf.str());
- Dictionary::Ptr locals = new Dictionary();
- locals->Set("__parent", rule.GetScope());
- locals->Set("host", host);
+ VMFrame frame;
+ if (rule.GetScope())
+ rule.GetScope()->CopyTo(frame.Locals);
+ frame.Locals->Set("host", host);
- if (!rule.EvaluateFilter(locals))
+ if (!rule.EvaluateFilter(frame))
return false;
Value vinstances;
if (rule.GetFTerm()) {
- vinstances = rule.GetFTerm()->Evaluate(locals);
+ vinstances = rule.GetFTerm()->Evaluate(frame);
} else {
Array::Ptr instances = new Array();
instances->Add("");
String name = rule.GetName();
if (!rule.GetFKVar().IsEmpty()) {
- locals->Set(rule.GetFKVar(), instance);
+ frame.Locals->Set(rule.GetFKVar(), instance);
name += instance;
}
- EvaluateApplyRuleInstance(host, name, locals, rule);
+ EvaluateApplyRuleInstance(host, name, frame, rule);
}
} else if (vinstances.IsObjectType<Dictionary>()) {
if (rule.GetFVVar().IsEmpty())
ObjectLock olock(dict);
BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
- locals->Set(rule.GetFKVar(), kv.first);
- locals->Set(rule.GetFVVar(), kv.second);
+ frame.Locals->Set(rule.GetFKVar(), kv.first);
+ frame.Locals->Set(rule.GetFVVar(), kv.second);
- EvaluateApplyRuleInstance(host, rule.GetName() + kv.first, locals, rule);
+ EvaluateApplyRuleInstance(host, rule.GetName() + kv.first, frame, rule);
}
}
private:
Host::Ptr m_Host;
- static void EvaluateApplyRuleInstance(const Host::Ptr& host, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule);
+ static void EvaluateApplyRuleInstance(const Host::Ptr& host, const String& name, VMFrame& frame, const ApplyRule& rule);
static bool EvaluateApplyRule(const Host::Ptr& host, const ApplyRule& rule);
};
Host::Ptr host = service->GetHost();
- Dictionary::Ptr locals = new Dictionary();
- locals->Set("__parent", group->GetScope());
- locals->Set("host", host);
- locals->Set("service", service);
+ VMFrame frame;
+ if (group->GetScope())
+ group->GetScope()->CopyTo(frame.Locals);
+ frame.Locals->Set("host", host);
+ frame.Locals->Set("service", service);
- if (!group->GetFilter()->Evaluate(locals))
+ if (!group->GetFilter()->Evaluate(frame))
return false;
Log(LogDebug, "ServiceGroup")
CONTEXT("Evaluating rule for group '" + group_name + "'");
- Dictionary::Ptr locals = new Dictionary();
- locals->Set("__parent", group->GetScope());
- locals->Set("user", user);
+ VMFrame frame;
+ if (group->GetScope())
+ group->GetScope()->CopyTo(frame.Locals);
+ frame.Locals->Set("user", user);
- if (!group->GetFilter()->Evaluate(locals))
+ if (!group->GetFilter()->Evaluate(frame))
return false;
Log(LogDebug, "UserGroup")