/***********************************************************************
THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY
DEVELOPER: Zihan Chen(vczh)
***********************************************************************/
#include "VlppGlrParser.h"
#include "VlppReflection.h"
#include "VlppOS.h"
#include "Vlpp.h"
#include "VlppRegex.h"

/***********************************************************************
.\WFRUNTIMEINSTRUCTION.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Workflow::Runtime

Interfaces:
**********************************************************************/

#ifndef VCZH_WORKFLOW_RUNTIME_WFRUNTIMEINSTRUCTION
#define VCZH_WORKFLOW_RUNTIME_WFRUNTIMEINSTRUCTION


namespace vl
{
	namespace workflow
	{
		namespace runtime
		{

/***********************************************************************
Instruction
***********************************************************************/

			enum class WfInsCode
			{
				// Instruction			// param				: <Stack-Pattern> -> <Stack-Pattern> in the order of <bottom ---- top>
				Nop,					//						: () -> ()															;
				LoadValue,				// value				: () -> Value														;
				LoadFunction,			// function				: () -> Value														; push the function index
				LoadException,			// 						: () -> Value														;
				LoadLocalVar,			// variable				: () -> Value														;
				LoadCapturedVar,		// variable				: () -> Value														;
				LoadGlobalVar,			// variable				: () -> Value														;
				LoadMethodInfo,			// IMethodInfo*			: () -> IMethodInfo*												;
				LoadMethodClosure,		// IMethodInfo*			: Value-this -> <function>											;
				LoadClosureContext,		//						: () -> <closure-context>											; load the current closure context
				StoreLocalVar,			// variable				: Value -> ()														;
				StoreCapturedVar,		// variable				: Value -> ()														;
				StoreGlobalVar,			// variable				: Value -> ()														;
				Duplicate,				// count				: () -> Value														; copy stack[stack.Count()-1-count]
				Pop,					//						: Value -> ()														;
				Return,					//						: Value -> Value													; (exit function)
				NewArray,				// count				: Value-count, ..., Value-1 -> <array>								; {1 2 3} -> <3 2 1>
				NewList,				// count				: Value-count, ..., Value-1 -> <array>								; {1 2 3} -> <3 2 1>
				NewObservableList,		// count				: Value-count, ..., Value-1 -> <observable-list>					; {1 2 3} -> <3 2 1>
				NewDictionary,			// count				: Value-count*2, ..., Value-1 -> <map>								; {1:2 3:4} -> <3 4 1 2>
				CreateClosureContext,	// count				: Value-1, ..., Value-count -> <closure-context>					;
				CreateClosure,			//						: <closure-context>, Value-function-index -> <closure>				;
				CreateInterface,		// IMethodInfo*, count	: <closure-context>, Value-count, ..., Value-1 -> <map>				; {"Get":a "Set":b} -> new TInterface(InterfaceProxy^)
				CreateRange,			// I1248/U1248			: Value-begin, Value-end -> <enumerable>							;
				CreateStruct,			// flag, typeDescriptor	: () -> Value														;
				DeleteRawPtr,			//						: Value -> ()														;
				ConvertToType,			// flag, typeDescriptor	: Value -> Value													;
				TryConvertToType,		// flag, typeDescriptor	: Value -> Value													;
				TestType,				// flag, typeDescriptor	: Value -> <bool>													;
				GetType,				//						: Value -> <ITypeDescriptor*>										;
				Jump,					// label				: () -> ()															;
				JumpIf,					// label				: <bool> -> ()														;
				Invoke,					// function, count		: Value-1, ..., Value-n -> Value									;
				InvokeWithContext,		// function, count		: Value-1, ..., Value-n -> Value									;
				GetProperty,			// IPropertyInfo*		: Value-this -> Value												;
				SetProperty,			// IPropertyInfo*		: Value, Value-this -> ()											;
				UpdateProperty,			// IPropertyInfo*		: Value-this, Value -> Value-this									;
				InvokeProxy,			// count				: Value-1, ..., Value-n, Value-this -> Value						;
				InvokeMethod,			// IMethodInfo*, count	: Value-1, ..., Value-n, Value-this -> Value						;
				InvokeEvent,			// IEventInfo*, count	: Value-1, ..., Value-n, Value-this -> <null>						;
				InvokeBaseCtor,			// IMethodInfo*, count	: Value-1, ..., Value-n, Value-this -> <null>						;
				AttachEvent,			// IEventInfo*			: Value-this, <function> -> <Listener>								;
				DetachEvent,			// IEventInfo*			: Value-this, <Listener> -> bool									;
				InstallTry,				// label				: () -> ()															;
				UninstallTry,			// count				: () -> ()															;
				RaiseException,			// 						: Value -> ()														; (trap)
				TestElementInSet,		//						: Value-element, Value-set -> bool									;
				CompareLiteral,			// I48/U48/F48/S		: Value, Value -> <int>												;
				CompareReference,		// 						: Value, Value -> <bool>											;
				CompareValue,			// 						: Value, Value -> <bool>											;
				OpNot,					// B/I1248/U1248		: Value -> Value													;
				OpPositive,				// I1248/U1248			: Value -> Value													;
				OpNegative,				// I1248				: Value -> Value													;
				OpConcat,				// 						: <string>, <string> -> <string>									;
				OpExp,					// I48/U48/F48			: Value, Value -> Value												;
				OpAdd,					// I48/U48/F48			: Value, Value -> Value												;
				OpSub,					// I48/U48/F48			: Value, Value -> Value												;
				OpMul,					// I48/U48/F48			: Value, Value -> Value												;
				OpDiv,					// I48/U48/F48			: Value, Value -> Value												;
				OpMod,					// I48/U48				: Value, Value -> Value												;
				OpShl,					// I48/U48				: Value, Value -> Value												;
				OpShr,					// I48/U48				: Value, Value -> Value												;
				OpXor,					// B/I1248/U1248		: <bool>, <bool> -> <bool>											;
				OpAnd,					// B/I1248/U1248		: <bool>, <bool> -> <bool>											;
				OpOr,					// B/I1248/U1248		: <bool>, <bool> -> <bool>											;
				OpLT,					// 						: <int> -> <bool>													;
				OpGT,					// 						: <int> -> <bool>													;
				OpLE,					// 						: <int> -> <bool>													;
				OpGE,					// 						: <int> -> <bool>													;
				OpEQ,					// 						: <int> -> <bool>													;
				OpNE,					// 						: <int> -> <bool>													;
			};

#define INSTRUCTION_CASES(APPLY, APPLY_VALUE, APPLY_FUNCTION, APPLY_FUNCTION_COUNT, APPLY_VARIABLE, APPLY_COUNT, APPLY_FLAG_TYPEDESCRIPTOR, APPLY_PROPERTY, APPLY_METHOD, APPLY_METHOD_COUNT, APPLY_EVENT, APPLY_EVENT_COUNT, APPLY_LABEL, APPLY_TYPE)\
			APPLY(Nop)\
			APPLY_VALUE(LoadValue)\
			APPLY_FUNCTION(LoadFunction)\
			APPLY(LoadException)\
			APPLY_VARIABLE(LoadLocalVar)\
			APPLY_VARIABLE(LoadCapturedVar)\
			APPLY_VARIABLE(LoadGlobalVar)\
			APPLY_METHOD(LoadMethodInfo)\
			APPLY_METHOD(LoadMethodClosure)\
			APPLY(LoadClosureContext)\
			APPLY_VARIABLE(StoreLocalVar)\
			APPLY_VARIABLE(StoreCapturedVar)\
			APPLY_VARIABLE(StoreGlobalVar)\
			APPLY_COUNT(Duplicate)\
			APPLY(Pop)\
			APPLY(Return)\
			APPLY_COUNT(NewArray)\
			APPLY_COUNT(NewList)\
			APPLY_COUNT(NewObservableList)\
			APPLY_COUNT(NewDictionary)\
			APPLY_COUNT(CreateClosureContext)\
			APPLY(CreateClosure)\
			APPLY_METHOD_COUNT(CreateInterface)\
			APPLY_TYPE(CreateRange)\
			APPLY_FLAG_TYPEDESCRIPTOR(CreateStruct)\
			APPLY(DeleteRawPtr)\
			APPLY_FLAG_TYPEDESCRIPTOR(ConvertToType)\
			APPLY_FLAG_TYPEDESCRIPTOR(TryConvertToType)\
			APPLY_FLAG_TYPEDESCRIPTOR(TestType)\
			APPLY(GetType)\
			APPLY_LABEL(Jump)\
			APPLY_LABEL(JumpIf)\
			APPLY_FUNCTION_COUNT(Invoke)\
			APPLY_FUNCTION_COUNT(InvokeWithContext)\
			APPLY_PROPERTY(GetProperty)\
			APPLY_PROPERTY(SetProperty)\
			APPLY_PROPERTY(UpdateProperty)\
			APPLY_COUNT(InvokeProxy)\
			APPLY_METHOD_COUNT(InvokeMethod)\
			APPLY_EVENT_COUNT(InvokeEvent)\
			APPLY_METHOD_COUNT(InvokeBaseCtor)\
			APPLY_EVENT(AttachEvent)\
			APPLY_EVENT(DetachEvent)\
			APPLY_LABEL(InstallTry)\
			APPLY_COUNT(UninstallTry)\
			APPLY(RaiseException)\
			APPLY(TestElementInSet)\
			APPLY_TYPE(CompareLiteral)\
			APPLY(CompareReference)\
			APPLY(CompareValue)\
			APPLY_TYPE(OpNot)\
			APPLY_TYPE(OpPositive)\
			APPLY_TYPE(OpNegative)\
			APPLY(OpConcat)\
			APPLY_TYPE(OpExp)\
			APPLY_TYPE(OpAdd)\
			APPLY_TYPE(OpSub)\
			APPLY_TYPE(OpMul)\
			APPLY_TYPE(OpDiv)\
			APPLY_TYPE(OpMod)\
			APPLY_TYPE(OpShl)\
			APPLY_TYPE(OpShr)\
			APPLY_TYPE(OpXor)\
			APPLY_TYPE(OpAnd)\
			APPLY_TYPE(OpOr)\
			APPLY(OpLT)\
			APPLY(OpGT)\
			APPLY(OpLE)\
			APPLY(OpGE)\
			APPLY(OpEQ)\
			APPLY(OpNE)\

			enum class WfInsType
			{
				Bool,
				I1,
				I2,
				I4,
				I8,
				U1,
				U2,
				U4,
				U8,
				F4,
				F8,
				String,
				Unknown,
			};

			struct WfRuntimeValue
			{
				// U8 with ITypeDescriptor* -> enum
				// Unknown with ITypeDescriptor* -> type
				// Unknown -> Null
				WfInsType											type = WfInsType::Unknown;
				reflection::description::ITypeDescriptor*			typeDescriptor = nullptr;
				WString												stringValue;
				union
				{
					bool											boolValue;
					vint8_t											i1Value;
					vint16_t										i2Value;
					vint32_t										i4Value;
					vint64_t										i8Value;
					vuint8_t										u1Value;
					vuint16_t										u2Value;
					vuint32_t										u4Value;
					vuint64_t										u8Value = 0;
					float											f4Value;
					double											f8Value;
				};

				WfRuntimeValue() {}
				WfRuntimeValue(bool value) : type(WfInsType::Bool), boolValue(value) {}
				WfRuntimeValue(vint8_t value) : type(WfInsType::I1), i1Value(value) {}
				WfRuntimeValue(vint16_t value) : type(WfInsType::I2), i2Value(value) {}
				WfRuntimeValue(vint32_t value) : type(WfInsType::I4), i4Value(value) {}
				WfRuntimeValue(vint64_t value) : type(WfInsType::I8), i8Value(value) {}
				WfRuntimeValue(vuint8_t value) : type(WfInsType::U1), u1Value(value) {}
				WfRuntimeValue(vuint16_t value) : type(WfInsType::U2), u2Value(value) {}
				WfRuntimeValue(vuint32_t value) : type(WfInsType::U4), u4Value(value) {}
				WfRuntimeValue(vuint64_t value) : type(WfInsType::U8), u8Value(value) {}
				WfRuntimeValue(float value) : type(WfInsType::F4), f4Value(value) {}
				WfRuntimeValue(double value) : type(WfInsType::F8), f8Value(value) {}
				WfRuntimeValue(WString value) : type(WfInsType::String), stringValue(value) {}
				WfRuntimeValue(vuint64_t value, reflection::description::ITypeDescriptor* enumType)
					: type(WfInsType::U8), typeDescriptor(enumType), u8Value(value) {}
				WfRuntimeValue(reflection::description::ITypeDescriptor* td)
					: type(WfInsType::Unknown), typeDescriptor(td) {}
			};

			struct WfInstruction
			{
				WfInsCode											code = WfInsCode::Nop;
				WfRuntimeValue										valueParameter;
				vint												countParameter = 0;
				union
				{
					struct
					{
						reflection::description::Value::ValueType		flagParameter;
						reflection::description::ITypeDescriptor*		typeDescriptorParameter;
					};
					WfInsType											typeParameter;
					vint												indexParameter;
					reflection::description::IPropertyInfo*				propertyParameter;
					reflection::description::IMethodInfo*				methodParameter;
					reflection::description::IEventInfo*				eventParameter;
				};

				WfInstruction();

				#define CTOR(NAME)						static WfInstruction NAME();
				#define CTOR_VALUE(NAME)				static WfInstruction NAME(const WfRuntimeValue& value);
				#define CTOR_FUNCTION(NAME)				static WfInstruction NAME(vint function);
				#define CTOR_FUNCTION_COUNT(NAME)		static WfInstruction NAME(vint function, vint count);
				#define CTOR_VARIABLE(NAME)				static WfInstruction NAME(vint variable);
				#define CTOR_COUNT(NAME)				static WfInstruction NAME(vint count);
				#define CTOR_FLAG_TYPEDESCRIPTOR(NAME)	static WfInstruction NAME(reflection::description::Value::ValueType flag, reflection::description::ITypeDescriptor* typeDescriptor);
				#define CTOR_PROPERTY(NAME)				static WfInstruction NAME(reflection::description::IPropertyInfo* propertyInfo);
				#define CTOR_METHOD(NAME)				static WfInstruction NAME(reflection::description::IMethodInfo* methodInfo);
				#define CTOR_METHOD_COUNT(NAME)			static WfInstruction NAME(reflection::description::IMethodInfo* methodInfo, vint count);
				#define CTOR_EVENT(NAME)				static WfInstruction NAME(reflection::description::IEventInfo* eventInfo);
				#define CTOR_EVENT_COUNT(NAME)			static WfInstruction NAME(reflection::description::IEventInfo* eventInfo, vint count);
				#define CTOR_LABEL(NAME)				static WfInstruction NAME(vint label);
				#define CTOR_TYPE(NAME)					static WfInstruction NAME(WfInsType type);

				INSTRUCTION_CASES(
					CTOR,
					CTOR_VALUE,
					CTOR_FUNCTION,
					CTOR_FUNCTION_COUNT,
					CTOR_VARIABLE,
					CTOR_COUNT,
					CTOR_FLAG_TYPEDESCRIPTOR,
					CTOR_PROPERTY,
					CTOR_METHOD,
					CTOR_METHOD_COUNT,
					CTOR_EVENT,
					CTOR_EVENT_COUNT,
					CTOR_LABEL,
					CTOR_TYPE)

				#undef CTOR
				#undef CTOR_VALUE
				#undef CTOR_FUNCTION
				#undef CTOR_FUNCTION_COUNT
				#undef CTOR_VARIABLE
				#undef CTOR_COUNT
				#undef CTOR_FLAG_TYPEDESCRIPTOR
				#undef CTOR_PROPERTY
				#undef CTOR_METHOD
				#undef CTOR_METHOD_COUNT
				#undef CTOR_EVENT
				#undef CTOR_EVENT_COUNT
				#undef CTOR_LABEL
				#undef CTOR_TYPE
			};
		}
	}
}

#endif


/***********************************************************************
.\WFRUNTIMETYPEDESCRIPTOR.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Workflow::Runtime

Interfaces:
**********************************************************************/

#ifndef VCZH_WORKFLOW_RUNTIME_WFRUNTIMETYPEDESCRIPTOR
#define VCZH_WORKFLOW_RUNTIME_WFRUNTIMETYPEDESCRIPTOR


namespace vl
{
	namespace workflow
	{
		namespace typeimpl
		{
			class WfClassInstance;
			class WfInterfaceInstance;
		}
	}

	namespace reflection
	{
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
#define DEFINE_DESCRIPTION(TYPE)\
		template<>\
		class Description<workflow::typeimpl::TYPE> : public virtual DescriptableObject\
		{\
		private:\
			description::ITypeDescriptor*				associatedTypeDescriptor;\
		public:\
			Description(description::ITypeDescriptor* _associatedTypeDescriptor)\
				:associatedTypeDescriptor(_associatedTypeDescriptor)\
			{\
				typeDescriptor = &associatedTypeDescriptor;\
			}\
		};\

		DEFINE_DESCRIPTION(WfClassInstance)
		DEFINE_DESCRIPTION(WfInterfaceInstance)

#undef DEFINE_DESCRIPTION
#endif
	}

	namespace workflow
	{
		namespace runtime
		{
			class WfRuntimeGlobalContext;
		}

		namespace typeimpl
		{
			class WfCustomType;
			class WfTypeImpl;

/***********************************************************************
Method
***********************************************************************/

			class WfMethodProxy : public Object, public virtual reflection::description::IValueFunctionProxy
			{
				typedef reflection::description::IMethodInfo				IMethodInfo;
				typedef reflection::description::IValueReadonlyList			IValueReadonlyList;
				typedef reflection::description::Value						Value;
			protected:
				Value									thisObject;
				IMethodInfo*							methodInfo;

			public:
				WfMethodProxy(const Value& _thisObject, IMethodInfo* _methodInfo);
				~WfMethodProxy();
				
				Value									Invoke(Ptr<IValueReadonlyList> arguments)override;
			};

			class WfMethodBase : public reflection::description::MethodInfoImpl
			{
				friend class WfCustomType;
				typedef reflection::description::ITypeInfo					ITypeInfo;
			protected:
				typedef reflection::description::Value						Value;
				runtime::WfRuntimeGlobalContext*		globalContext = nullptr;
				
				Value									CreateFunctionProxyInternal(const Value& thisObject)override;
				void									SetGlobalContext(runtime::WfRuntimeGlobalContext* _globalContext);
			public:
				WfMethodBase(bool isStatic);
				~WfMethodBase();

				ICpp*									GetCpp()override;
				runtime::WfRuntimeGlobalContext*		GetGlobalContext();
				void									SetReturn(Ptr<ITypeInfo> type);
			};

			class WfStaticMethod : public WfMethodBase
			{
				typedef reflection::description::Value						Value;
			protected:

				Value									InvokeInternal(const Value& thisObject, collections::Array<Value>& arguments)override;
			public:
				vint									functionIndex = -1;

				WfStaticMethod();
			};

/***********************************************************************
Class Method
***********************************************************************/

			class WfClassConstructor : public WfMethodBase
			{
				typedef reflection::description::Value						Value;
				typedef reflection::description::ITypeInfo					ITypeInfo;
			protected:

				Value									InvokeInternal(const Value& thisObject, collections::Array<Value>& arguments)override;
			public:
				vint									functionIndex = -1;

				WfClassConstructor(Ptr<ITypeInfo> type);

				void									InvokeBaseCtor(const Value& thisObject, collections::Array<Value>& arguments);
			};

			class WfClassMethod : public WfMethodBase
			{
				typedef reflection::description::Value						Value;
			protected:

				Value									InvokeInternal(const Value& thisObject, collections::Array<Value>& arguments)override;
			public:
				vint									functionIndex = -1;

				WfClassMethod();
			};

/***********************************************************************
Interface Method
***********************************************************************/

			class WfInterfaceConstructor : public WfMethodBase
			{
				typedef reflection::description::Value						Value;
				typedef reflection::description::ITypeInfo					ITypeInfo;
			protected:

				Value									InvokeInternal(const Value& thisObject, collections::Array<Value>& arguments)override;
			public:
				WfInterfaceConstructor(Ptr<ITypeInfo> type);
			};

			class WfInterfaceMethod : public WfMethodBase
			{
				typedef reflection::description::Value						Value;
			protected:

				Value									InvokeInternal(const Value& thisObject, collections::Array<Value>& arguments)override;
			public:
				WfInterfaceMethod();
			};

/***********************************************************************
Event
***********************************************************************/

			class WfEvent : public reflection::description::EventInfoImpl
			{
				typedef reflection::description::ITypeDescriptor			ITypeDescriptor;
				typedef reflection::description::ITypeInfo					ITypeInfo;
				typedef reflection::description::IEventHandler				IEventHandler;
				typedef reflection::description::IValueFunctionProxy		IValueFunctionProxy;
				typedef reflection::description::IValueReadonlyList			IValueReadonlyList;
				typedef reflection::description::Value						Value;

				class EventHandlerImpl : public Object, public IEventHandler
				{
				public:
					bool								isAttached = true;
					Ptr<IValueFunctionProxy>			proxy;

					EventHandlerImpl(Ptr<IValueFunctionProxy> _proxy)
						:proxy(_proxy)
					{
					}

					bool IsAttached()override
					{
						return isAttached;
					}
				};

				typedef collections::Group<WfEvent*, Ptr<EventHandlerImpl>>	EventHandlerGroup;
				class EventRecord : public Object
				{
				public:
					EventHandlerGroup					handlers;
				};

				static const wchar_t*					EventRecordInternalPropertyName;
			protected:

				Ptr<EventRecord>						GetEventRecord(DescriptableObject* thisObject, bool createIfNotExist);
				Ptr<IEventHandler>						AttachInternal(DescriptableObject* thisObject, Ptr<IValueFunctionProxy> handler)override;
				bool									DetachInternal(DescriptableObject* thisObject, Ptr<IEventHandler> handler)override;
				void									InvokeInternal(DescriptableObject* thisObject, Ptr<IValueReadonlyList> arguments)override;
				Ptr<ITypeInfo>							GetHandlerTypeInternal()override;
			public:
				WfEvent(ITypeDescriptor* ownerTypeDescriptor, const WString& name);
				~WfEvent();

				ICpp*									GetCpp()override;
				void									SetHandlerType(Ptr<ITypeInfo> typeInfo);
			};

/***********************************************************************
Field
***********************************************************************/

			class WfField : public reflection::description::FieldInfoImpl
			{
				typedef reflection::description::ITypeDescriptor			ITypeDescriptor;
				typedef reflection::description::ITypeInfo					ITypeInfo;
				typedef reflection::description::Value						Value;
				typedef collections::Dictionary<WfField*, Value>			FieldValueMap;

				class FieldRecord : public Object
				{
				public:
					FieldValueMap						values;
				};

				static const wchar_t*					FieldRecordInternalPropertyName;
			protected:
				
				Ptr<FieldRecord>						GetFieldRecord(DescriptableObject* thisObject, bool createIfNotExist);
				Value									GetValueInternal(const Value& thisObject)override;
				void									SetValueInternal(Value& thisObject, const Value& newValue)override;
			public:
				WfField(ITypeDescriptor* ownerTypeDescriptor, const WString& name);
				~WfField();

				ICpp*									GetCpp()override;
				void									SetReturn(Ptr<ITypeInfo> typeInfo);
			};

			class WfStructField : public reflection::description::FieldInfoImpl
			{
				typedef reflection::description::ITypeDescriptor			ITypeDescriptor;
				typedef reflection::description::ITypeInfo					ITypeInfo;
				typedef reflection::description::Value						Value;
			protected:

				Value									GetValueInternal(const Value& thisObject)override;
				void									SetValueInternal(Value& thisObject, const Value& newValue)override;
			public:
				WfStructField(ITypeDescriptor* ownerTypeDescriptor, const WString& name);
				~WfStructField();

				ICpp*									GetCpp()override;
				void									SetReturn(Ptr<ITypeInfo> typeInfo);
			};

/***********************************************************************
Property
***********************************************************************/

			class WfProperty : public reflection::description::PropertyInfoImpl
			{
				typedef reflection::description::ITypeDescriptor			ITypeDescriptor;
				typedef reflection::description::MethodInfoImpl				MethodInfoImpl;
				typedef reflection::description::EventInfoImpl				EventInfoImpl;
			public:
				WfProperty(ITypeDescriptor* ownerTypeDescriptor, const WString& name);
				~WfProperty();

				void									SetGetter(MethodInfoImpl* value);
				void									SetSetter(MethodInfoImpl* value);
				void									SetValueChangedEvent(EventInfoImpl* value);
			};

/***********************************************************************
Custom Type
***********************************************************************/

			struct WfTypeInfoContent : reflection::description::TypeInfoContent
			{
				WString								workflowTypeName;

				WfTypeInfoContent(const WString& _workflowTypeName);
			};

			template<typename TBase>
			class WfCustomTypeBase : private WfTypeInfoContent, public TBase
			{
			public:
				WfCustomTypeBase(reflection::description::TypeDescriptorFlags typeDescriptorFlags, const WString& typeName)
					:WfTypeInfoContent(typeName)
					, TBase(typeDescriptorFlags, this)
				{
				}

				const WString& GetTypeName() override
				{
					// TypeDescriptorImplBase::GetTypeName returns WString(this->typeName, false)
					// which is this->workflowTypeName.Obj()
					// will become a dangling pointer after this type is unloaded
					return workflowTypeName;
				}
			};

			class WfCustomType : public WfCustomTypeBase<reflection::description::TypeDescriptorImpl>
			{
			protected:
				typedef reflection::description::TypeDescriptorFlags		TypeDescriptorFlags;
				typedef reflection::description::ITypeDescriptor			ITypeDescriptor;
				typedef reflection::description::ITypeInfo					ITypeInfo;
				typedef reflection::description::IMethodGroupInfo			IMethodGroupInfo;
				typedef collections::List<ITypeDescriptor*>					TypeDescriptorList;

			protected:
				runtime::WfRuntimeGlobalContext*		globalContext = nullptr;
				bool									baseTypeExpanded = false;
				TypeDescriptorList						expandedBaseTypes;
				
				void									SetGlobalContext(runtime::WfRuntimeGlobalContext* _globalContext, IMethodGroupInfo* group);
				void									SetGlobalContext(runtime::WfRuntimeGlobalContext* _globalContext);
				void									LoadInternal()override;
			public:
				WfCustomType(TypeDescriptorFlags typeDescriptorFlags, const WString& typeName);
				~WfCustomType();
				
				runtime::WfRuntimeGlobalContext*		GetGlobalContext();
				const TypeDescriptorList&				GetExpandedBaseTypes();

				void									AddBaseType(ITypeDescriptor* type);
				void									AddMember(const WString& name, Ptr<WfMethodBase> value);
				void									AddMember(Ptr<WfClassConstructor> value);
				void									AddMember(Ptr<WfInterfaceConstructor> value);
				void									AddMember(Ptr<WfField> value);
				void									AddMember(Ptr<WfProperty> value);
				void									AddMember(Ptr<WfEvent> value);
			};

			class WfClass : public WfCustomType
			{
				friend class WfTypeImpl;
			public:
				vint									destructorFunctionIndex = -1;

				WfClass(const WString& typeName);
				~WfClass();
			};

			class WfInterface : public WfCustomType
			{
				friend class WfTypeImpl;
			public:
				WfInterface(const WString& typeName);
				~WfInterface();
			};

			class WfStruct : public WfCustomTypeBase<reflection::description::ValueTypeDescriptorBase>
			{
				using FieldMap = collections::Dictionary<WString, Ptr<WfStructField>>;
				using IPropertyInfo = reflection::description::IPropertyInfo;
				using IValueType = reflection::description::IValueType;
				using IBoxedValue = reflection::description::IBoxedValue;

			protected:
				class WfValueType : public Object, public virtual IValueType
				{
					using Value = reflection::description::Value;

				protected:
					WfStruct*							owner;

				public:
					WfValueType(WfStruct* _owner);

					Value								CreateDefault()override;
				};

			protected:
				FieldMap								fields;

			public:
				WfStruct(const WString& typeName);
				~WfStruct();

				vint									GetPropertyCount()override;
				IPropertyInfo*							GetProperty(vint index)override;
				bool									IsPropertyExists(const WString& name, bool inheritable)override;
				IPropertyInfo*							GetPropertyByName(const WString& name, bool inheritable)override;

				void									AddMember(Ptr<WfStructField> value);
			};

			class WfEnum : public WfCustomTypeBase<reflection::description::ValueTypeDescriptorBase>
			{
				using EnumItemMap = collections::Dictionary<WString, vuint64_t>;
				using IValueType = reflection::description::IValueType;
				using IBoxedValue = reflection::description::IBoxedValue;
				using IEnumType = reflection::description::IEnumType;
				using Value = reflection::description::Value;

			protected:
				class WfValueType : public Object, public virtual IValueType
				{
				protected:
					WfEnum*							owner;

				public:
					WfValueType(WfEnum* _owner);

					Value								CreateDefault()override;
				};

				class WfEnumType : public Object, public virtual IEnumType
				{
				protected:
					WfEnum*								owner;

				public:
					WfEnumType(WfEnum* _owner);

					bool								IsFlagEnum()override;
					vint								GetItemCount()override;
					WString								GetItemName(vint index)override;
					vuint64_t							GetItemValue(vint index)override;
					vint								IndexOfItem(WString name)override;
					Value								ToEnum(vuint64_t value)override;
					vuint64_t							FromEnum(const Value& value)override;
				};

			protected:
				EnumItemMap								enumItems;

			public:
				WfEnum(bool isFlags, const WString& typeName);
				~WfEnum();

				void									AddEnumItem(const WString& name, vuint64_t value);
			};

/***********************************************************************
Instance
***********************************************************************/

			class WfClassInstance : public Object, public reflection::Description<WfClassInstance>
			{
				typedef reflection::description::ITypeDescriptor			ITypeDescriptor;
				typedef reflection::description::Value						Value;
			protected:
				WfClass*								classType = nullptr;

			public:
				WfClassInstance(ITypeDescriptor* _typeDescriptor);
				~WfClassInstance();

				void									InstallBaseObject(ITypeDescriptor* td, Value& value);
			};

			class WfInterfaceInstance : public Object, public reflection::IDescriptable, public reflection::Description<WfInterfaceInstance>
			{
				typedef reflection::description::ITypeDescriptor			ITypeDescriptor;
				typedef reflection::description::IMethodInfo				IMethodInfo;
				typedef reflection::description::IValueInterfaceProxy		IValueInterfaceProxy;
			protected:
				Ptr<IValueInterfaceProxy>				proxy;

			public:
				WfInterfaceInstance(ITypeDescriptor* _typeDescriptor, Ptr<IValueInterfaceProxy> _proxy, collections::List<IMethodInfo*>& baseCtors);
				~WfInterfaceInstance();

				Ptr<IValueInterfaceProxy>				GetProxy();
			};

			class WfStructInstance : public Object, public reflection::description::IBoxedValue
			{
				using FieldValueMap = collections::Dictionary<WfStructField*, reflection::description::Value>;

			public:
				reflection::description::ITypeDescriptor*		typeDescriptor = nullptr;
				FieldValueMap									fieldValues;

				WfStructInstance(reflection::description::ITypeDescriptor* _typeDescriptor);

				reflection::description::PredefinedBoxableType	GetBoxableType() override;
				Ptr<IBoxedValue>								Copy() override;
				CompareResult									ComparePrimitive(Ptr<IBoxedValue> boxedValue) override;
			};

			class WfEnumInstance : public Object, public reflection::description::IBoxedValue
			{
			public:
				reflection::description::ITypeDescriptor*		typeDescriptor = nullptr;
				vuint64_t										value = 0;

				WfEnumInstance(reflection::description::ITypeDescriptor* _typeDescriptor);

				reflection::description::PredefinedBoxableType	GetBoxableType() override;
				Ptr<IBoxedValue>								Copy() override;
				CompareResult									ComparePrimitive(Ptr<IBoxedValue> boxedValue) override;
			};

/***********************************************************************
Plugin
***********************************************************************/

			class WfTypeImpl : public Object, public reflection::description::ITypeLoader, public reflection::Description<WfTypeImpl>
			{
			protected:
				runtime::WfRuntimeGlobalContext*		globalContext = nullptr;

			public:
				collections::List<Ptr<WfClass>>			classes;
				collections::List<Ptr<WfInterface>>		interfaces;
				collections::List<Ptr<WfStruct>>		structs;
				collections::List<Ptr<WfEnum>>			enums;
				
				runtime::WfRuntimeGlobalContext*		GetGlobalContext();
				void									SetGlobalContext(runtime::WfRuntimeGlobalContext* _globalContext);
				void									Load(reflection::description::ITypeManager* manager)override;
				void									Unload(reflection::description::ITypeManager* manager)override;
			};
		}
	}
}

#endif


/***********************************************************************
.\WFRUNTIMEASSEMBLY.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Workflow::Runtime

Interfaces:
**********************************************************************/

#ifndef VCZH_WORKFLOW_RUNTIME_WFRUNTIMEASSEMBLY
#define VCZH_WORKFLOW_RUNTIME_WFRUNTIMEASSEMBLY


namespace vl
{
	namespace workflow
	{
		namespace runtime
		{

/***********************************************************************
Assembly
***********************************************************************/

			/// <summary>Representing a compiled function.</summary>
			class WfAssemblyFunction : public Object
			{
			public:
				/// <summary>Name of the function.</summary>
				WString												name;
				/// <summary>Argument names of the function. This index is for accessing [F:vl.workflow.runtime.WfRuntimeVariableContext.variables] in [F:vl.workflow.runtime.WfRuntimeCallStackInfo.arguments] when debugging.</summary>
				collections::List<WString>							argumentNames;
				/// <summary>Captured variable names of the function. This index is for accessing [F:vl.workflow.runtime.WfRuntimeVariableContext.variables] in [F:vl.workflow.runtime.WfRuntimeCallStackInfo.captured] when debugging.</summary>
				collections::List<WString>							capturedVariableNames;
				/// <summary>Local variable names of the function. This index is for accessing [F:vl.workflow.runtime.WfRuntimeVariableContext.variables] in [F:vl.workflow.runtime.WfRuntimeCallStackInfo.localVariables] when debugging.</summary>
				collections::List<WString>							localVariableNames;
				/// <summary>First instruction index of the function. This index is for accessing [F:vl.workflow.runtime.WfAssembly.instructions].</summary>
				vint												firstInstruction = -1;
				/// <summary>Last instruction index of the function. This index is for accessing [F:vl.workflow.runtime.WfAssembly.instructions].</summary>
				vint												lastInstruction = -1;
			};

			/// <summary>Representing debug informations.</summary>
			class WfInstructionDebugInfo : public Object
			{
			public:

				/// <summary>Module codes.</summary>
				collections::List<WString>							moduleCodes;				// codeIndex -> code
				/// <summary>Mapping information from every instruction to code. Use[F:vl.parsing.ParsingTextRange.codeIndex] for accessing <see cref="moduleCodes"/>.</summary>
				collections::List<glr::ParsingTextRange>			instructionCodeMapping;		// instruction -> range
				/// <summary>Mapping information from every row in codes to instructions. Value of the key is (codeIndex, row).</summary>
				collections::Group<Tuple<vint, vint>, vint>			codeInstructionMapping;		// (codeIndex, row) -> instruction [generated]

				void												Initialize();
			};

			/// <summary>Representing metadata errors during loading an assembly.</summary>
			class WfAssemblyLoadErrors
			{
			public:
				/// <summary>All unresolvable types.</summary>
				collections::List<WString>							unresolvedTypes;

				/// <summary>All duplicated types. Types are shared in the process, there is no isolation between assemblies.</summary>
				collections::List<WString>							duplicatedTypes;

				/// <summary>All unresolvable members in resolved types.</summary>
				collections::List<WString>							unresolvedMembers;
			};

			/// <summary>Representing a Workflow assembly.</summary>
			class WfAssembly : public Object, public reflection::Description<WfAssembly>
			{
			public:
				/// <summary>Debug informations using the module code.</summary>
				Ptr<WfInstructionDebugInfo>							insBeforeCodegen;
				/// <summary>Debug informations using the module code from generated syntax trees from the final compiling pass.</summary>
				Ptr<WfInstructionDebugInfo>							insAfterCodegen;
				/// <summary>Global variable names. This index is for accessing [F:vl.workflow.runtime.WfRuntimeVariableContext.variables] in [F:vl.workflow.runtime.WfRuntimeCallStackInfo.global] when debugging.</summary>
				collections::List<WString>							variableNames;
				/// <summary>Mapping from function names to function indexes for accessing <see cref="functions"/>.</summary>
				collections::Group<WString, vint>					functionByName;
				/// <summary>Functions.</summary>
				collections::List<Ptr<WfAssemblyFunction>>			functions;
				/// <summary>Instructions.</summary>
				collections::List<WfInstruction>					instructions;
				/// <summary>Custom types.</summary>
				Ptr<typeimpl::WfTypeImpl>							typeImpl;

				/// <summary>Create an empty assembly.</summary>
				WfAssembly();
				
				void												Initialize();

				/// <summary>Deserialize an assembly.</summary>
				/// <returns>The deserialized assembly. Returns null if there are errors.</returns>
				/// <param name="input">Serialized binary data.</param>
				/// <param name="errors">Errors during loading an assembly.</param>
				static Ptr<WfAssembly>								Deserialize(stream::IStream& input, WfAssemblyLoadErrors& errors);

				/// <summary>Serialize an assembly.</summary>
				/// <param name="output">Serialized binary data.</param>
				void												Serialize(stream::IStream& output);
			};
		}
	}
}

#endif


/***********************************************************************
.\WFRUNTIMECONSTRUCTIONS.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Workflow::Runtime

Interfaces:
**********************************************************************/

#ifndef VCZH_WORKFLOW_RUNTIME_WFRUNTIMECONSTRUCTIONS
#define VCZH_WORKFLOW_RUNTIME_WFRUNTIMECONSTRUCTIONS


#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA

namespace vl
{
	namespace workflow
	{
		namespace runtime
		{
			class WfRuntimeGlobalContext;
			class WfRuntimeVariableContext;
			
/***********************************************************************
Range
***********************************************************************/

			template<typename T>
			class WfRuntimeRange : public Object, public reflection::description::IValueEnumerable
			{
			protected:
				T						begin;
				T						end;

				class Enumerator : public Object, public reflection::description::IValueEnumerator
				{
				protected:
					T					begin;
					T					end;
					T					current;
				public:
					Enumerator(T _begin, T _end)
						:begin(_begin), end(_end), current(_begin - 1)
					{
					}

					reflection::description::Value GetCurrent()
					{
						return reflection::description::BoxValue<T>(current);
					}

					vint GetIndex()
					{
						return (vint)(current - begin);
					}

					bool Next()
					{
						if (current >= end) return false;
						current++;
						return true;
					}
				};
			public:
				WfRuntimeRange(T _begin, T _end)
					:begin(_begin), end(_end)
				{
				}

				Ptr<reflection::description::IValueEnumerator> CreateEnumerator()override
				{
					return Ptr(new Enumerator(begin, end));
				}
			};
			
/***********************************************************************
Lambda
***********************************************************************/

			class WfRuntimeLambda : public Object, public reflection::description::IValueFunctionProxy
			{
				typedef reflection::description::Value										Value;
			public:
				// use raw pointer because
				// if a lambda is stored in a global variable
				// it is stored in globalContext->globalVariables->variables[i]
				// so that globalContext has a cyclic reference to itself
				WfRuntimeGlobalContext*				globalContext = nullptr;
				Ptr<WfRuntimeVariableContext>		capturedVariables;
				vint								functionIndex;

				WfRuntimeLambda(Ptr<WfRuntimeGlobalContext> _globalContext, Ptr<WfRuntimeVariableContext> _capturedVariables, vint _functionIndex);

				Value								Invoke(Ptr<reflection::description::IValueReadonlyList> arguments)override;
				static Value						Invoke(Ptr<WfRuntimeGlobalContext> globalContext, Ptr<WfRuntimeVariableContext> capturedVariables, vint functionIndex, Ptr<reflection::description::IValueReadonlyList> arguments);
			};
			
/***********************************************************************
InterfaceInstance
***********************************************************************/

			class WfRuntimeInterfaceInstance : public Object, public reflection::description::IValueInterfaceProxy
			{
				typedef reflection::description::Value										Value;
				typedef reflection::description::IMethodInfo								IMethodInfo;
				typedef reflection::description::IValueFunctionProxy						IValueFunctionProxy;
				typedef reflection::description::IValueReadonlyList							IValueReadonlyList;
				typedef collections::Dictionary<IMethodInfo*, vint>							FunctionMap;
			public:
				// use raw pointer because
				// if a lambda is stored in a global variable
				// it is stored in globalContext->globalVariables->variables[i]
				// so that globalContext has a cyclic reference to itself
				WfRuntimeGlobalContext*				globalContext = nullptr;
				Ptr<WfRuntimeVariableContext>		capturedVariables;
				FunctionMap							functions;
				vint								destructorFunctionIndex = -1;

				~WfRuntimeInterfaceInstance();
				Value								Invoke(IMethodInfo* methodInfo, Ptr<IValueReadonlyList> arguments)override;
			};
		}
	}
}

#endif
#endif

/***********************************************************************
.\WFRUNTIMEDEBUGGER.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Workflow::Runtime

Interfaces:
**********************************************************************/

#ifndef VCZH_WORKFLOW_RUNTIME_WFRUNTIMEDEBUGGER
#define VCZH_WORKFLOW_RUNTIME_WFRUNTIMEDEBUGGER


#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA

namespace vl
{
	namespace workflow
	{
		namespace runtime
		{
			class WfRuntimeThreadContext;
			class WfRuntimeExceptionInfo;
			class IWfDebuggerCallback;
			class WfDebugger;

/***********************************************************************
Debugger
***********************************************************************/

			/// <summary>Break point action. It will </summary>
			class IWfBreakPointAction : public virtual Interface
			{
			public:
				/// <summary>Called a break point is about to activate.</summary>
				/// <returns>Returns false to skip this break point.</returns>
				/// <param name="debugger">The current attached debugger.</param>
				virtual bool					EvaluateCondition(WfDebugger* debugger) = 0;
				/// <summary>Called when a break point is about to activate, even <see cref="EvaluateCondition"/> returns false.</summary>
				/// <param name="debugger">The current attached debugger.</param>
				/// <param name="activated">The return value from <see cref="EvaluateCondition"/>.</param>
				virtual void					PostAction(WfDebugger* debugger, bool activated) = 0;
			};

			/// <summary>Break point.</summary>
			struct WfBreakPoint
			{
				enum Type
				{
					Instruction,	// assembly, instruction
					ReadGlobalVar,	// assembly, variable
					WriteGlobalVar,	// assembly, variable
					GetProperty,	// [thisObject], propertyInfo
					SetProperty,	// [thisObject], propertyInfo
					AttachEvent,	// [thisObject], eventInfo
					DetachEvent,	// [thisObject], eventInfo
					InvokeEvent,	// [thisObject], eventInfo
					InvokeMethod,	// [thisObject], methodInfo
					CreateObject,	// typeDescriptor
				};

				vint											id = -1;
				bool											available = false;
				bool											enabled = false;
				Ptr<IWfBreakPointAction>						action;

				Type											type;
				WfAssembly*										assembly = nullptr;
				union
				{
					vint										instruction = -1;
					vint										variable;
				};

				reflection::DescriptableObject*					thisObject = nullptr;
				union
				{
					reflection::description::IPropertyInfo*		propertyInfo = nullptr;
					reflection::description::IEventInfo*		eventInfo;
					reflection::description::IMethodInfo*		methodInfo;
					reflection::description::ITypeDescriptor*	typeDescriptor;
				};

				/// <summary>Create an instruction break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="assembly">The assembly that contains the instruction.</param>
				/// <param name="instruction">The index of the instruction.</param>
				static WfBreakPoint								Ins(WfAssembly* assembly, vint instruction);
				
				/// <summary>Create an global variable reading break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="assembly">The assembly that contains the instruction.</param>
				/// <param name="variable">The index of the global variable.</param>
				static WfBreakPoint								Read(WfAssembly* assembly, vint variable);
				
				/// <summary>Create an global variable writing break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="assembly">The assembly that contains the instruction.</param>
				/// <param name="variable">The index of the global variable.</param>
				static WfBreakPoint								Write(WfAssembly* assembly, vint variable);
				
				/// <summary>Create an property reading break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="thisObject">The target object. Set to null to apply to every object.</param>
				/// <param name="propertyInfo">The property.</param>
				static WfBreakPoint								Get(reflection::DescriptableObject* thisObject, reflection::description::IPropertyInfo* propertyInfo);
				
				/// <summary>Create an property writing break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="thisObject">The target object. Set to null to apply to every object.</param>
				/// <param name="propertyInfo">The property.</param>
				static WfBreakPoint								Set(reflection::DescriptableObject* thisObject, reflection::description::IPropertyInfo* propertyInfo);
				
				/// <summary>Create an event attaching break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="thisObject">The target object. Set to null to apply to every object.</param>
				/// <param name="eventInfo">The event.</param>
				static WfBreakPoint								Attach(reflection::DescriptableObject* thisObject, reflection::description::IEventInfo* eventInfo);
				
				/// <summary>Create an event detaching break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="thisObject">The target object. Set to null to apply to every object.</param>
				/// <param name="eventInfo">The event.</param>
				static WfBreakPoint								Detach(reflection::DescriptableObject* thisObject, reflection::description::IEventInfo* eventInfo);
				
				/// <summary>Create an event invoking break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="thisObject">The target object. Set to null to apply to every object.</param>
				/// <param name="eventInfo">The event.</param>
				static WfBreakPoint								Invoke(reflection::DescriptableObject* thisObject, reflection::description::IEventInfo* eventInfo);
				
				/// <summary>Create an function invoking break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="thisObject">The target object. Set to null to apply to every object.</param>
				/// <param name="methodInfo">The function.</param>
				static WfBreakPoint								Invoke(reflection::DescriptableObject* thisObject, reflection::description::IMethodInfo* methodInfo);
				
				/// <summary>Create an object creating break point.</summary>
				/// <returns>The created break point.</returns>
				/// <param name="typeDescriptor">The target object type.</param>
				static WfBreakPoint								Create(reflection::description::ITypeDescriptor* typeDescriptor);
			};

			class IWfDebuggerCallback : public virtual Interface
			{
			public:
				virtual void					EnterThreadContext(WfRuntimeThreadContext* context) = 0;
				virtual void					LeaveThreadContext(WfRuntimeThreadContext* context) = 0;
				virtual bool					BreakIns(WfAssembly* assembly, vint instruction) = 0;
				virtual bool					BreakRead(WfAssembly* assembly, vint variable) = 0;
				virtual bool					BreakWrite(WfAssembly* assembly, vint variable) = 0;
				virtual bool					BreakGet(reflection::DescriptableObject* thisObject, reflection::description::IPropertyInfo* propertyInfo) = 0;
				virtual bool					BreakSet(reflection::DescriptableObject* thisObject, reflection::description::IPropertyInfo* propertyInfo) = 0;
				virtual bool					BreakAttach(reflection::DescriptableObject* thisObject, reflection::description::IEventInfo* eventInfo) = 0;
				virtual bool					BreakDetach(reflection::DescriptableObject* thisObject, reflection::description::IEventInfo* eventInfo) = 0;
				virtual bool					BreakInvoke(reflection::DescriptableObject* thisObject, reflection::description::IEventInfo* eventInfo) = 0;
				virtual bool					BreakInvoke(reflection::DescriptableObject* thisObject, reflection::description::IMethodInfo* methodInfo) = 0;
				virtual bool					BreakCreate(reflection::description::ITypeDescriptor* typeDescriptor) = 0;
				virtual bool					BreakException(Ptr<WfRuntimeExceptionInfo> info) = 0;
				virtual bool					WaitForContinue() = 0;
			};

			/// <summary>Workflow debugger.</summary>
			/// <remarks>
			/// <p>
			/// <see cref="SetDebuggerForCurrentThread"/> needs to be called to make a debugger works for any Workflow script that is running in the current thread.
			/// </p>
			/// <p>
			/// <see cref="OnBlockExecution"/> needs to be overrided to make a debugger work properly.
			/// When the target Workflow script stops,
			/// this function will be called.
			/// In this function,
			/// one of <see cref="Run"/>, <see cref="Pause"/>, <see cref="Stop"/>, <see cref="StepOver"/> and <see cref="StepInto"/>
			/// must be called to make the target Workflow script continues.
			/// </p>
			/// <p>
			/// You are allowed to run the debugger logic in another thread,
			/// for example,
			/// an GUI application is debugging a Workflow script which is running in another thread.
			/// In this case, <see cref="OnBlockExecution"/> needs to be blocked until it is ready to continue.
			/// </p>
			/// <p>
			/// Locks are a good choice for this.
			/// </p>
			/// </remarks>
			class WfDebugger : public Object, protected virtual IWfDebuggerCallback
			{
				friend IWfDebuggerCallback* GetDebuggerCallback(WfDebugger* debugger);

				typedef collections::List<WfBreakPoint>					BreakPointList;
				typedef collections::List<WfRuntimeThreadContext*>		ThreadContextList;

				typedef Tuple<WfAssembly*, vint>														AssemblyKey;
				typedef Tuple<reflection::DescriptableObject*, reflection::description::IPropertyInfo*>	PropertyKey;
				typedef Tuple<reflection::DescriptableObject*, reflection::description::IEventInfo*>	EventKey;
				typedef Tuple<reflection::DescriptableObject*, reflection::description::IMethodInfo*>	MethodKey;
				typedef reflection::description::ITypeDescriptor*										TypeKey;

				typedef collections::Dictionary<AssemblyKey, vint>		AssemblyBreakPointMap;
				typedef collections::Dictionary<PropertyKey, vint>		PropertyBreakPointMap;
				typedef collections::Dictionary<EventKey, vint>			EventBreakPointMap;
				typedef collections::Dictionary<MethodKey, vint>		MethodBreakPointMap;
				typedef collections::Dictionary<TypeKey, vint>			TypeBreakPointMap;
			public:
				/// <summary>The state of the debugger.</summary>
				/// <remarks>
				/// <p>
				/// The state is affected by break points and the following operations:
				/// <ul>
				///   <li><b><see cref="Run"/></b>: If the Workflow script is paused, it continues the script.</li>
				///   <li><b><see cref="Pause"/></b>: If the Workflow script is running, it pauses the script, following by a call to <see cref="OnBlockExecution"/>.</li>
				///   <li><b><see cref="Stop"/></b>: If the Workflow script is not stopped, it stops the script by throwing in exception in the script.</li>
				///   <li><b><see cref="StepOver"/></b>: Stop over to the next code line and pause. It doesn't jump into the function to be called.</li>
				///   <li><b><see cref="StepInto"/></b>: Stop into the new code line and pause.</li>
				/// </ul>
				/// Operations are expected to be called in <see cref="OnBlockExecution"/>.
				/// </p>
				/// </remarks>
				enum State
				{						//		Run		Pause	Stop	StepOver	StepInto
					/// <summary>The associated thread is running Workflow script.</summary>
					Running,			// R			*RTP	*RTS
					/// <summary>The target Workflow script is paused by operations other than break points.</summary>
					PauseByOperation,	// PBO	*C				*RTS	*C			*C
					/// <summary>The target Workflow script is paused by break points.</summary>
					PauseByBreakPoint,	// PBB	*C				*RTS	*C			*C
					/// <summary>The associated thread has stopped running Workflow script.</summary>
					Stopped,			// S			*RTP			*			*
					/// <summary>The debugger allows the target Workflow script to continue.</summary>
					Continue,			// C	soon becomes Running
					/// <summary>The target Workflow script is required to pause. This value can be observed in <see cref="OnBlockExecution"/>. Operations to continue executing the Workflow script await to be called.</summary>
					RequiredToPause,	// RTP	soon becomes PauseByOperation (should be triggered in OnBlockExecution)
					/// <summary>The target Workflow script is required to stop. It caused to Workflow script to stop by throwing an exception saying this.</summary>
					RequiredToStop,		// RTS	soon becomes Stopped          (should be triggered in OnBlockExecution)
				};

				enum RunningType
				{
					RunUntilBreakPoint,
					RunStepOver,
					RunStepInto,
				};

				struct InstructionLocation
				{
					vint								contextIndex = -1;
					WfAssembly*							assembly = nullptr;
					vint								stackFrameIndex = -1;
					vint								instruction = -1;

					bool								BreakStepOver(const InstructionLocation& il, bool beforeCodegen);
					bool								BreakStepInto(const InstructionLocation& il, bool beforeCodegen);
				};

				static const vint						InvalidBreakPoint = -1;
				static const vint						PauseBreakPoint = -2;
			protected:
				BreakPointList							breakPoints;
				collections::List<vint>					freeBreakPointIndices;
				volatile bool							evaluatingBreakPoint = false;
				volatile bool							breakException = false;

				ThreadContextList						threadContexts;

				volatile State							state = Stopped;
				volatile RunningType					runningType = RunUntilBreakPoint;
				volatile vint							lastActivatedBreakPoint = InvalidBreakPoint;
				bool									stepBeforeCodegen = true;
				InstructionLocation						instructionLocation;

				AssemblyBreakPointMap					insBreakPoints;
				AssemblyBreakPointMap					getGlobalVarBreakPoints;
				AssemblyBreakPointMap					setGlobalVarBreakPoints;
				PropertyBreakPointMap					getPropertyBreakPoints;
				PropertyBreakPointMap					setPropertyBreakPoints;
				EventBreakPointMap						attachEventBreakPoints;
				EventBreakPointMap						detachEventBreakPoints;
				EventBreakPointMap						invokeEventBreakPoints;
				MethodBreakPointMap						invokeMethodBreakPoints;
				TypeBreakPointMap						createObjectBreakPoints;

				/// <summary>Called for doing something when a break point is activated. This function will be called multiple times before some one let the debugger to continue.</summary>
				/// <remarks>This function must be overrided, or the Workflow script will hang when it is paused by any reason.</remarks>
				virtual void							OnBlockExecution();
				/// <summary>Called when a new Workflow program is about to run.</summary>
				virtual void							OnStartExecution();
				/// <summary>Called when a Workflow program is stopped by any reason.</summary>
				virtual void							OnStopExecution();
				
				InstructionLocation						MakeCurrentInstructionLocation();
				template<typename TKey>
				bool									HandleBreakPoint(const TKey& key, collections::Dictionary<TKey, vint>& breakPointMap);
				bool									SetBreakPoint(const WfBreakPoint& breakPoint, bool available, vint index);
				
				void									EnterThreadContext(WfRuntimeThreadContext* context)override;
				void									LeaveThreadContext(WfRuntimeThreadContext* context)override;
				bool									BreakIns(WfAssembly* assembly, vint instruction)override;
				bool									BreakRead(WfAssembly* assembly, vint variable)override;
				bool									BreakWrite(WfAssembly* assembly, vint variable)override;
				bool									BreakGet(reflection::DescriptableObject* thisObject, reflection::description::IPropertyInfo* propertyInfo)override;
				bool									BreakSet(reflection::DescriptableObject* thisObject, reflection::description::IPropertyInfo* propertyInfo)override;
				bool									BreakAttach(reflection::DescriptableObject* thisObject, reflection::description::IEventInfo* eventInfo)override;
				bool									BreakDetach(reflection::DescriptableObject* thisObject, reflection::description::IEventInfo* eventInfo)override;
				bool									BreakInvoke(reflection::DescriptableObject* thisObject, reflection::description::IEventInfo* eventInfo)override;
				bool									BreakInvoke(reflection::DescriptableObject* thisObject, reflection::description::IMethodInfo* methodInfo)override;
				bool									BreakCreate(reflection::description::ITypeDescriptor* typeDescriptor)override;
				bool									BreakException(Ptr<WfRuntimeExceptionInfo> info)override;
				bool									WaitForContinue()override;
			public:
				/// <summary>Create a debugger.</summary>
				WfDebugger();
				~WfDebugger();

				/// <summary>Add a new break point.</summary>
				/// <returns>Returns the index of this break point. Returns -1 if failed.</returns>
				/// <param name="breakPoint">The break point.</param>
				vint									AddBreakPoint(const WfBreakPoint& breakPoint);
				/// <summary>Add a new source code break point.</summary>
				/// <returns>Returns the index of this break point. Returns -1 if failed.</returns>
				/// <param name="assembly">The assembly.</param>
				/// <param name="codeIndex">The code index of a module.</param>
				/// <param name="row">The row number, starts from 0.</param>
				/// <param name="beforeCodegen">Set to true to apply source code information to original source code.</param>
				vint									AddCodeLineBreakPoint(WfAssembly* assembly, vint codeIndex, vint row, bool beforeCodegen = true);
				/// <summary>Get the number of all break points.</summary>
				/// <returns>The number of all break points.</returns>
				vint									GetBreakPointCount();
				/// <summary>Test if an index is an available break point.</summary>
				/// <returns>Returns true if an index is an available break point. This function returns true for all disabled break points.</returns>
				/// <param name="index">The index of the break point.</param>
				bool									IsBreakPointAvailable(vint index);
				/// <summary>Get a specified break point. For unavailable break points, <see cref="WfBreakPoint::available"/> is false.</summary>
				/// <returns>The break point.</returns>
				/// <param name="index">The index of the break point.</param>
				const WfBreakPoint&						GetBreakPoint(vint index);
				/// <summary>Delete a specified break point.</summary>
				/// <returns>Returns true if this operation is succeeded.</returns>
				/// <param name="index">The index of the break point.</param>
				/// <remarks>After removing a break point, the break point becomes unavailable. The index will be reused later when a new break point is added to the debugger.</remarks>
				bool									RemoveBreakPoint(vint index);
				/// <summary>Enable or disable a specified break point.</summary>
				/// <returns>Returns true if this operation is succeeded.</returns>
				/// <param name="index">The index of the break point.</param>
				/// <param name="enabled">Set to true to enable a break point.</param>
				bool									EnableBreakPoint(vint index, bool enabled);
				/// <summary>Test if the exception break point is enabled or not.</summary>
				/// <returns>Returns true if the exception break point is enabled.</returns>
				bool									GetBreakException();
				/// <summary>Enable or disable the exception break point.</summary>
				/// <param name="value">Set to true to enable the exception break point.</param>
				void									SetBreakException(bool value);

				/// <summary>Continue to run the Workflow program.</summary>
				/// <returns>Returns true if this operation is succeeded.</returns>
				bool									Run();
				/// <summary>Pause the Workflow program.</summary>
				/// <returns>Returns true if this operation is succeeded.</returns>
				bool									Pause();
				/// <summary>Stop the Workflow program.</summary>
				/// <returns>Returns true if this operation is succeeded.</returns>
				bool									Stop();
				/// <summary>Run until reached the next row in the same function or outside of this function.</summary>
				/// <returns>Returns true if this operation is succeeded.</returns>
				/// <param name="beforeCodegen">Set to true to apply the source code information to original source code.</param>
				bool									StepOver(bool beforeCodegen = true);
				/// <summary>Run until reached the next row.</summary>
				/// <returns>Returns true if this operation is succeeded.</returns>
				/// <param name="beforeCodegen">Set to true to apply the source code information to original source code.</param>
				bool									StepInto(bool beforeCodegen = true);
				/// <summary>Get the current state of the debugger.</summary>
				/// <returns>The state of the debugger.</returns>
				State									GetState();
				/// <summary>Get the running type of the debugger.</summary>
				/// <returns>The running type of the debugger.</returns>
				RunningType								GetRunningType();
				/// <summary>Get the index of the last activated break point.</summary>
				/// <returns>The index of the last activated break point.</returns>
				vint									GetLastActivatedBreakPoint();

				const ThreadContextList&				GetThreadContexts();
				WfRuntimeThreadContext*					GetCurrentThreadContext();
				/// <summary>Get the current position of the executing instruction in the source code.</summary>
				/// <returns>The current position in the source code.</returns>
				/// <param name="beforeCodegen">Set to true to apply the source code information to original source code.</param>
				/// <param name="context">Specify a thread context. Set to null to use the top thread context.</param>
				/// <param name="callStackIndex">Specify a call stack index. Set to null to use the top call stack item of the specified thread context.</param>
				const glr::ParsingTextRange&			GetCurrentPosition(bool beforeCodegen = true, WfRuntimeThreadContext* context = nullptr, vint callStackIndex = -1);
				/// <summary>Get the variable value by name in the current scope.</summary>
				/// <returns>The value.</returns>
				/// <param name="name">The name.</param>
				/// <param name="context">Specify a thread context. Set to null to use the top thread context.</param>
				/// <param name="callStackIndex">Specify a call stack index. Set to null to use the top call stack item of the specified thread context.</param>
				reflection::description::Value			GetValueByName(const WString& name, WfRuntimeThreadContext* context = nullptr, vint callStackIndex = -1);
			};

			extern IWfDebuggerCallback*					GetDebuggerCallback();
			extern IWfDebuggerCallback*					GetDebuggerCallback(WfDebugger* debugger);
			
			/// <summary>Get the debugger for the current thread.</summary>
			/// <returns>The debugger.</returns>
			extern Ptr<WfDebugger>						GetDebuggerForCurrentThread();
			/// <summary>Set the debugger for the current thread.</summary>
			/// <param name="debugger">The debugger.</param>
			extern void									SetDebuggerForCurrentThread(Ptr<WfDebugger> debugger);
			/// <summary>Reset the debugger for the current thread.</summary>
			extern void									ResetDebuggerForCurrentThread();
		}
	}
}

#endif
#endif

/***********************************************************************
.\WFRUNTIME.H
***********************************************************************/
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Workflow::Runtime

Interfaces:
**********************************************************************/

#ifndef VCZH_WORKFLOW_RUNTIME_WFRUNTIME
#define VCZH_WORKFLOW_RUNTIME_WFRUNTIME


#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA

namespace vl
{
	namespace workflow
	{
		namespace runtime
		{

/***********************************************************************
RuntimeEnvironment
***********************************************************************/

			/// <summary>Variable storage.</summary>
			class WfRuntimeVariableContext : public Object, public reflection::Description<WfRuntimeVariableContext>
			{
				typedef collections::Array<reflection::description::Value>		VariableArray;

			public:
				/// <summary>Values of variables in runtime.</summary>
				VariableArray					variables;
			};

			/// <summary>Global context for executing a Workflow program. After the context is prepared, use [M:vl.workflow.runtime.LoadFunction`1] to call any functions inside the assembly. Function "<b>&lt;initialize&gt;</b>" should be the first to execute.</summary>
			class WfRuntimeGlobalContext : public Object, public reflection::Description<WfRuntimeGlobalContext>
			{
			public:
				/// <summary>The loaded assembly.</summary>
				Ptr<WfAssembly>					assembly;
				/// <summary>Global variable storages.</summary>
				Ptr<WfRuntimeVariableContext>	globalVariables;
				
				/// <summary>Create a global context for executing a Workflow program.</summary>
				/// <param name="_assembly">The assembly.</param>
				WfRuntimeGlobalContext(Ptr<WfAssembly> _assembly);
				~WfRuntimeGlobalContext();
			};

			struct WfRuntimeStackFrame
			{
				Ptr<WfRuntimeVariableContext>	capturedVariables;
				vint							functionIndex = -1;
				vint							nextInstructionIndex = -1;
				vint							stackBase = 0;
				vint							fixedVariableCount = 0;
				vint							freeStackBase = 0;
			};

			struct WfRuntimeTrapFrame
			{
				vint							stackFrameIndex = -1;
				vint							instructionIndex = -1;
				vint							stackPatternCount = -1;
			};

/***********************************************************************
RuntimeException
***********************************************************************/

			/// <summary>Representing a call stack item.</summary>
			class WfRuntimeCallStackInfo : public Object, public virtual reflection::description::IValueCallStack
			{
				using IValueReadonlyDictionary = reflection::description::IValueReadonlyDictionary;
			protected:
				Ptr<IValueReadonlyDictionary>	cachedLocalVariables;
				Ptr<IValueReadonlyDictionary>	cachedLocalArguments;
				Ptr<IValueReadonlyDictionary>	cachedCapturedVariables;
				Ptr<IValueReadonlyDictionary>	cachedGlobalVariables;

				Ptr<IValueReadonlyDictionary>	GetVariables(collections::List<WString>& names, Ptr<WfRuntimeVariableContext> context, Ptr<IValueReadonlyDictionary>& cache);
			public:
				WfRuntimeCallStackInfo();
				WfRuntimeCallStackInfo(WfRuntimeThreadContext* context, const WfRuntimeStackFrame& stackFrame);
				~WfRuntimeCallStackInfo();

				/// <summary>The executing assembly.</summary>
				Ptr<WfAssembly>					assembly;
				/// <summary>Global variable values.</summary>
				Ptr<WfRuntimeVariableContext>	global;
				/// <summary>Captured variable values.</summary>
				Ptr<WfRuntimeVariableContext>	captured;
				/// <summary>Argument values.</summary>
				Ptr<WfRuntimeVariableContext>	arguments;
				/// <summary>Local variable values.</summary>
				Ptr<WfRuntimeVariableContext>	localVariables;
				/// <summary>The executing function.</summary>
				vint							functionIndex = -1;
				/// <summary>The executing instruction.</summary>
				vint							instruction = -1;

				Ptr<IValueReadonlyDictionary>	GetLocalVariables()override;
				Ptr<IValueReadonlyDictionary>	GetLocalArguments()override;
				Ptr<IValueReadonlyDictionary>	GetCapturedVariables()override;
				Ptr<IValueReadonlyDictionary>	GetGlobalVariables()override;

				/// <summary>Get the name of the executing function.</summary>
				/// <returns>The name of the execution function.</returns>
				WString							GetFunctionName()override;
				/// <summary>Get the source code of the executing module.</summary>
				/// <returns>The source code.</returns>
				WString							GetSourceCodeBeforeCodegen()override;
				/// <summary>Get the source code of the executing module from generated syntax trees from the final compiling pass.</summary>
				/// <returns>The source code.</returns>
				WString							GetSourceCodeAfterCodegen()override;
				/// <summary>Get the row number (starts at 0) of the source code of the executing module.</summary>
				/// <returns>The row number.</returns>
				vint							GetRowBeforeCodegen()override;
				/// <summary>Get the row number (starts at 0) of the source code of the executing module from generated syntax trees from the final compiling pass.</summary>
				/// <returns>The row number.</returns>
				vint							GetRowAfterCodegen()override;
			};
			
			/// <summary>Representing an raised exception.</summary>
			class WfRuntimeExceptionInfo : public Object, public virtual reflection::description::IValueException
			{
				typedef collections::List<Ptr<WfRuntimeCallStackInfo>>		CallStackList;
				using IValueReadonlyList = reflection::description::IValueReadonlyList;
			protected:
				Ptr<IValueReadonlyList>			cachedCallStack;

			public:
				/// <summary>Exception message.</summary>
				WString							message;
				/// <summary>Fatal error flag.</summary>
				bool							fatal = false;
				/// <summary>All call stack items.</summary>
				CallStackList					callStack;

				WfRuntimeExceptionInfo(const WString& _message, bool _fatal);
				~WfRuntimeExceptionInfo();
				
#pragma push_macro("GetMessage")
#if defined GetMessage
#undef GetMessage
#endif
				WString							GetMessage()override;
#pragma pop_macro("GetMessage")
				bool							GetFatal()override;
				Ptr<IValueReadonlyList>			GetCallStack()override;
			};
			
			/// <summary>Representing an raised exception object for upper level C++ code.</summary>
			class WfRuntimeException : public reflection::description::TypeDescriptorException
			{
			protected:
				Ptr<WfRuntimeExceptionInfo>		info;
				bool							fatal = false;
			public:
				WfRuntimeException(Ptr<WfRuntimeExceptionInfo> _info)
					:reflection::description::TypeDescriptorException(_info->message)
					, info(_info)
					, fatal(_info->fatal)
				{
				}

				WfRuntimeException(const WString& _message, bool _fatal)
					:reflection::description::TypeDescriptorException(_message)
					, fatal(_fatal)
				{
				}

				/// <summary>Get the detailed information.</summary>
				/// <returns>The detailed information.</returns>
				Ptr<WfRuntimeExceptionInfo> GetInfo()const
				{
					return info;
				}

				/// <summary>Get the fatal error flag.</summary>
				/// <returns>Returns true if this exception is a fatal error, which normally means state corruption in a Workflow runtime.</returns>
				bool IsFatal()const
				{
					return fatal;
				}
			};

/***********************************************************************
RuntimeThreadContext
***********************************************************************/

			enum class WfRuntimeExecutionStatus
			{
				Ready,
				Executing,
				RaisedException,
				Finished,
				FatalError,
			};

			enum class WfRuntimeExecutionAction
			{
				ExecuteInstruction,
				UnwrapStack,
				EnterStackFrame,
				ExitStackFrame,
				Nop,
			};

			enum class WfRuntimeThreadContextError
			{
				Success,
				WrongStackItemIndex,
				WrongVariableIndex,
				WrongFunctionIndex,
				WrongArgumentCount,
				WrongCapturedVariableCount,
				EmptyStackFrame,
				EmptyTrapFrame,
				EmptyStack,
				TrapFrameCorrupted,
				StackCorrupted,
			};

			/// <summary>A Workflow script call stack.</summary>
			/// <remarks>
			/// <p>
			/// This object could be obtained by <see cref="WfDebugger::GetCurrentThreadContext"/>.
			/// A thread could have multiple thread contexts,
			/// a full list could be obtained by <see cref="WfDebugger::GetThreadContexts"/>.
			/// </p>
			/// <p>
			/// You are not recommended to update the call stack using this object.
			/// </p>
			/// <p>
			/// In the current version,
			/// the debug information doesn't contain enough data,
			/// so that it could be difficult to read local variables in high-level function constructions,
			/// like lambda expression or coroutines.
			/// </p>
			/// </remakrs>
			class WfRuntimeThreadContext
			{
				typedef collections::List<reflection::description::Value>		VariableList;
				typedef collections::List<WfRuntimeStackFrame>					StackFrameList;
				typedef collections::List<WfRuntimeTrapFrame>					TrapFrameList;
			public:

				Ptr<WfRuntimeGlobalContext>		globalContext;
				Ptr<WfRuntimeExceptionInfo>		exceptionInfo;
				VariableList					stack;
				StackFrameList					stackFrames;
				TrapFrameList					trapFrames;
				WfRuntimeExecutionStatus		status = WfRuntimeExecutionStatus::Finished;

				WfRuntimeThreadContext(Ptr<WfRuntimeGlobalContext> _context);
				WfRuntimeThreadContext(Ptr<WfAssembly> _assembly);

				WfRuntimeStackFrame&			GetCurrentStackFrame();
				WfRuntimeThreadContextError		PushStackFrame(vint functionIndex, vint argumentCount, Ptr<WfRuntimeVariableContext> capturedVariables = 0);
				WfRuntimeThreadContextError		PopStackFrame();
				WfRuntimeTrapFrame&				GetCurrentTrapFrame();
				WfRuntimeThreadContextError		PushTrapFrame(vint instructionIndex);
				WfRuntimeThreadContextError		PopTrapFrame(vint saveStackPatternCount);
				WfRuntimeThreadContextError		PushRuntimeValue(const WfRuntimeValue& value);
				WfRuntimeThreadContextError		PushValue(const reflection::description::Value& value);
				WfRuntimeThreadContextError		PopValue(reflection::description::Value& value);
				WfRuntimeThreadContextError		RaiseException(const WString& exception, bool fatalError, bool skipDebugger = false);
				WfRuntimeThreadContextError		RaiseException(Ptr<WfRuntimeExceptionInfo> info, bool skipDebugger = false);

				WfRuntimeThreadContextError		LoadStackValue(vint stackItemIndex, reflection::description::Value& value);
				WfRuntimeThreadContextError		LoadGlobalVariable(vint variableIndex, reflection::description::Value& value);
				WfRuntimeThreadContextError		StoreGlobalVariable(vint variableIndex, const reflection::description::Value& value);
				WfRuntimeThreadContextError		LoadCapturedVariable(vint variableIndex, reflection::description::Value& value);
				WfRuntimeThreadContextError		StoreCapturedVariable(vint variableIndex, const reflection::description::Value& value);
				WfRuntimeThreadContextError		LoadLocalVariable(vint variableIndex, reflection::description::Value& value);
				WfRuntimeThreadContextError		StoreLocalVariable(vint variableIndex, const reflection::description::Value& value);

				WfRuntimeExecutionAction		ExecuteInternal(WfInstruction& ins, WfRuntimeStackFrame& stackFrame, IWfDebuggerCallback* callback);
				WfRuntimeExecutionAction		Execute(IWfDebuggerCallback* callback);
				void							ExecuteToEnd();
			};

/***********************************************************************
Helper Functions
***********************************************************************/
			
			/// <summary>Load a function from a global context, raise an exception if multiple functions are found under the same name. Function "&lt;initialize&gt;" should be the first to execute.</summary>
			/// <returns>The loaded function.</returns>
			/// <param name="context">The context to the evaluation environment.</param>
			/// <param name="name">The function name.</param>
			/// <remarks>"<b>&lt;initialize&gt;</b>" must be the first function that is executed after an assembly is loaded. It has no argument or return value.</remarks>
			extern Ptr<reflection::description::IValueFunctionProxy>		LoadFunction(Ptr<WfRuntimeGlobalContext> context, const WString& name);
			
			/// <summary>Load a C++ friendly function from a global context, raise an exception if multiple functions are found under the same name. Function "&lt;initialize&gt;" should be the first to execute.</summary>
			/// <typeparam name="TFunction">Type of the function.</typeparam>
			/// <returns>The loaded C++ friendly function.</returns>
			/// <param name="context">The context to the evaluation environment.</param>
			/// <param name="name">The function name.</param>
			/// <remarks>"<b>&lt;initialize&gt;</b>" must be the first function that is executed after an assembly is loaded. Its type is <b>void()</b>.</remarks>
			template<typename TFunction>
			Func<TFunction> LoadFunction(Ptr<WfRuntimeGlobalContext> context, const WString& name)
			{
				auto proxy = LoadFunction(context, name);
				return reflection::description::UnboxParameter<Func<TFunction>>(reflection::description::Value::From(proxy)).Ref();
			}
		}
	}
}

#endif
#endif

