Пример #1
0
ExpressionResult SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
{
	if (frame.Sandboxed)
		BOOST_THROW_EXCEPTION(ScriptError("Assignments are not allowed in sandbox mode.", m_DebugInfo));

	DebugHint *psdhint = dhint;

	Value parent;
	String index;

	if (!m_Operand1->GetReference(frame, true, &parent, &index, &psdhint))
		BOOST_THROW_EXCEPTION(ScriptError("Expression cannot be assigned to.", m_DebugInfo));

	ExpressionResult operand2 = m_Operand2->Evaluate(frame, dhint);
	CHECK_RESULT(operand2);

	if (m_Op != OpSetLiteral) {
		Value object = VMOps::GetField(parent, index, frame.Sandboxed, m_DebugInfo);

		switch (m_Op) {
			case OpSetAdd:
				operand2 = object + operand2;
				break;
			case OpSetSubtract:
				operand2 = object - operand2;
				break;
			case OpSetMultiply:
				operand2 = object * operand2;
				break;
			case OpSetDivide:
				operand2 = object / operand2;
				break;
			case OpSetModulo:
				operand2 = object % operand2;
				break;
			case OpSetXor:
				operand2 = object ^ operand2;
				break;
			case OpSetBinaryAnd:
				operand2 = object & operand2;
				break;
			case OpSetBinaryOr:
				operand2 = object | operand2;
				break;
			default:
				VERIFY(!"Invalid opcode.");
		}
	}

	VMOps::SetField(parent, index, operand2.GetValue(), m_DebugInfo);

	if (psdhint) {
		psdhint->AddMessage("=", m_DebugInfo);

		if (psdhint != dhint)
			delete psdhint;
	}

	return Empty;
}
Пример #2
0
bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const
{
	Value vparent;
	String vindex;
	DebugHint *psdhint = NULL;
	bool free_psd = false;

	if (dhint)
		psdhint = *dhint;

	if (frame.Sandboxed)
		init_dict = false;

	if (m_Operand1->GetReference(frame, init_dict, &vparent, &vindex, &psdhint)) {
		if (init_dict) {
			Value old_value =  VMOps::GetField(vparent, vindex, frame.Sandboxed, m_Operand1->GetDebugInfo());

			if (old_value.IsEmpty() && !old_value.IsString())
				VMOps::SetField(vparent, vindex, new Dictionary(), m_Operand1->GetDebugInfo());
		}

		*parent = VMOps::GetField(vparent, vindex, frame.Sandboxed, m_DebugInfo);
		free_psd = true;
	} else {
		ExpressionResult operand1 = m_Operand1->Evaluate(frame);
		*parent = operand1.GetValue();
	}

	ExpressionResult operand2 = m_Operand2->Evaluate(frame);
	*index = operand2.GetValue();

	if (dhint) {
		if (psdhint)
			*dhint = new DebugHint(psdhint->GetChild(*index));
		else
			*dhint = NULL;
	}

	if (free_psd)
		delete psdhint;

	return true;
}
Пример #3
0
/**
 * Commits the configuration item by creating a ConfigObject
 * object.
 *
 * @returns The ConfigObject that was created/updated.
 */
ConfigObject::Ptr ConfigItem::Commit(bool discard)
{
#ifdef I2_DEBUG
	Log(LogDebug, "ConfigItem")
	    << "Commit called for ConfigItem Type=" << GetType() << ", Name=" << GetName();
#endif /* I2_DEBUG */

	/* Make sure the type is valid. */
	Type::Ptr type = Type::GetByName(GetType());
	ASSERT(type && ConfigObject::TypeInstance->IsAssignableFrom(type));

	if (IsAbstract())
		return ConfigObject::Ptr();

	ConfigObject::Ptr dobj = static_pointer_cast<ConfigObject>(type->Instantiate());

	dobj->SetDebugInfo(m_DebugInfo);
	dobj->SetZoneName(m_Zone);
	dobj->SetPackage(m_Package);
	dobj->SetName(m_Name);

	DebugHint debugHints;

	ScriptFrame frame(dobj);
	if (m_Scope)
		m_Scope->CopyTo(frame.Locals);
	try {
		m_Expression->Evaluate(frame, &debugHints);
	} catch (const std::exception& ex) {
		if (m_IgnoreOnError) {
			Log(LogWarning, "ConfigObject")
			    << "Ignoring config object '" << m_Name << "' of type '" << m_Type << "' due to errors: " << DiagnosticInformation(ex);

			return ConfigObject::Ptr();
		}

		throw;
	}

	if (discard)
		m_Expression.reset();

	String item_name;
	String short_name = dobj->GetShortName();

	if (!short_name.IsEmpty()) {
		item_name = short_name;
		dobj->SetName(short_name);
	} else
		item_name = m_Name;

	String name = item_name;

	NameComposer *nc = dynamic_cast<NameComposer *>(type.get());

	if (nc) {
		name = nc->MakeName(name, dobj);

		if (name.IsEmpty())
			BOOST_THROW_EXCEPTION(std::runtime_error("Could not determine name for object"));
	}

	if (name != item_name)
		dobj->SetShortName(item_name);

	dobj->SetName(name);

	try {
		dobj->OnConfigLoaded();
	} catch (const std::exception& ex) {
		if (m_IgnoreOnError) {
			Log(LogWarning, "ConfigObject")
			    << "Ignoring config object '" << m_Name << "' of type '" << m_Type << "' due to errors: " << DiagnosticInformation(ex);

			return ConfigObject::Ptr();
		}

		throw;
	}

	Dictionary::Ptr persistentItem = new Dictionary();

	persistentItem->Set("type", GetType());
	persistentItem->Set("name", GetName());
	persistentItem->Set("properties", Serialize(dobj, FAConfig));

	Dictionary::Ptr dhint = debugHints.ToDictionary();
	persistentItem->Set("debug_hints", dhint);

	Array::Ptr di = new Array();
	di->Add(m_DebugInfo.Path);
	di->Add(m_DebugInfo.FirstLine);
	di->Add(m_DebugInfo.FirstColumn);
	di->Add(m_DebugInfo.LastLine);
	di->Add(m_DebugInfo.LastColumn);
	persistentItem->Set("debug_info", di);

	try {
		DefaultValidationUtils utils;
		dobj->Validate(FAConfig, utils);
	} catch (ValidationError& ex) {
		if (m_IgnoreOnError) {
			Log(LogWarning, "ConfigObject")
			    << "Ignoring config object '" << m_Name << "' of type '" << m_Type << "' due to errors: " << DiagnosticInformation(ex);

			return ConfigObject::Ptr();
		}

		ex.SetDebugHint(dhint);
		throw;
	}

	ConfigCompilerContext::GetInstance()->WriteObject(persistentItem);
	persistentItem.reset();

	dhint.reset();

	dobj->Register();

	m_Object = dobj;

	return dobj;
}
Пример #4
0
/**
 * Commits the configuration item by creating a DynamicObject
 * object.
 *
 * @returns The DynamicObject that was created/updated.
 */
DynamicObject::Ptr ConfigItem::Commit(bool discard)
{
	ASSERT(!OwnsLock());

#ifdef _DEBUG
	Log(LogDebug, "ConfigItem")
	    << "Commit called for ConfigItem Type=" << GetType() << ", Name=" << GetName();
#endif /* _DEBUG */

	/* Make sure the type is valid. */
	Type::Ptr type = Type::GetByName(GetType());
	ASSERT(type && Type::GetByName("DynamicObject")->IsAssignableFrom(type));

	if (IsAbstract())
		return DynamicObject::Ptr();

	DynamicObject::Ptr dobj = static_pointer_cast<DynamicObject>(type->Instantiate());

	dobj->SetDebugInfo(m_DebugInfo);
	dobj->SetTypeName(m_Type);
	dobj->SetZone(m_Zone);

	Dictionary::Ptr locals = new Dictionary();
	locals->Set("__parent", m_Scope);
	m_Scope.reset();

	dobj->SetParentScope(locals);
	locals.reset();

	dobj->SetName(m_Name);

	DebugHint debugHints;

	try {
		m_Expression->Evaluate(dobj, &debugHints);
	} catch (const ConfigError& ex) {
		const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
		ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
	} catch (const std::exception& ex) {
		ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
	}

	if (discard)
		m_Expression.reset();

	dobj->SetParentScope(Object::Ptr());

	String name = m_Name;

	NameComposer *nc = dynamic_cast<NameComposer *>(type.get());

	if (nc) {
		name = nc->MakeName(m_Name, dobj);

		if (name.IsEmpty())
			BOOST_THROW_EXCEPTION(std::runtime_error("Could not determine name for object"));
	}

	if (name != m_Name)
		dobj->SetShortName(m_Name);

	dobj->SetName(name);

	Dictionary::Ptr attrs = Serialize(dobj, FAConfig);

	Dictionary::Ptr persistentItem = new Dictionary();

	persistentItem->Set("type", GetType());
	persistentItem->Set("name", GetName());
	persistentItem->Set("properties", attrs);
	persistentItem->Set("debug_hints", debugHints.ToDictionary());

	ConfigCompilerContext::GetInstance()->WriteObject(persistentItem);
	persistentItem.reset();

	ConfigType::Ptr ctype = ConfigType::GetByName(GetType());

	if (!ctype)
		ConfigCompilerContext::GetInstance()->AddMessage(false, "No validation type found for object '" + GetName() + "' of type '" + GetType() + "'");
	else {
		TypeRuleUtilities utils;

		try {
			attrs->Remove("name");
			ctype->ValidateItem(GetName(), attrs, GetDebugInfo(), &utils);
		} catch (const ConfigError& ex) {
			const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
			ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
		} catch (const std::exception& ex) {
			ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
		}
	}

	dobj->Register();

	m_Object = dobj;

	return dobj;
}