Exemplo n.º 1
0
void CHSSysEngines::CutPower(HS_INT32 level)
{
    if (level == 0)
    {
        if (GetOwnerObject() && GetOwnerObject()->GetType() == HST_SHIP)
        {
            CHSShip *cShip;

            cShip = (CHSShip *) GetOwnerObject();

            if (hsInterface.AtrGet(cShip->GetDbref(), "HSMSG_ENGINES_CUT"))
            {
                HS_DBREF idx = cShip->GetDbref();

                char *msg = hsInterface.EvalExpression(hsInterface.m_buffer,
                                                       idx, idx, idx);
                cShip->NotifySrooms(msg);
            }
            else
            {
                cShip->NotifySrooms(HSCONF.engines_cut);
            }
        }
    }
}
Exemplo n.º 2
0
void CHSDamCon::UnassignCrew(HS_DBREF player, int iCrew)
{
    // Be certain this is a valid crew ID.
    if ((iCrew < 1) || (iCrew > (int) GetNumCrews()))
    {
        return;
    }
    
    // Grab this crew's structure from the vector.
    THSDamageCrew & rtCrew = m_vecCrews[iCrew];
    // Only one crew can be assigned to a system at any one time.
    HS_INT32 iNumCrews = GetNumCrews();

    for (int idx = 0; idx < iNumCrews; idx++)
    {
        // If this crew is the one we're assigning, ignore it.
        if (idx == iCrew)
        {
            rtCrew.pAssignedTo = NULL;
            rtCrew.iSecondsLeft = 0;
            if (GetOwnerObject()->GetType() == HST_SHIP)
            {
                CHSShip *pOwnerShip = static_cast <CHSShip * >
                    (GetOwnerObject());

                pOwnerShip->NotifyConsoles(hsInterface.
                        HSPrintf(
                            "%s%s-%s Damage Control crew %i now available.",
                            ANSI_HILITE, ANSI_GREEN, ANSI_NORMAL, iCrew), 
                        MSG_ENGINEERING);
            }
        }
    }
}
Exemplo n.º 3
0
void CHSSysThrusters::PowerUp(int level)
{
    if (!GetOwnerObject())
    {
        return;
    }

    if (GetOwnerObject()->GetType() == HST_SHIP)
    {
        CHSShip *cShip;

        cShip = (CHSShip *) GetOwnerObject();

        if (hsInterface.
            AtrGet(cShip->GetDbref(), "HSMSG_THRUSTERS_ACTIVATING"))
        {
            char *msg = hsInterface.EvalExpression(hsInterface.m_buffer,
                                                   cShip->GetDbref(),
                                                   cShip->GetDbref(),
                                                   cShip->GetDbref());
            cShip->NotifySrooms(msg);
        }
        else
        {
            cShip->NotifySrooms(HSCONF.thrusters_activating);
        }
    }
}
Exemplo n.º 4
0
void CHSJumpDrive::DoCycle()
{
    float rate;

    // Do base stuff first
    CHSEngSystem::DoCycle();

    // Charge jumpers?
    if ((GetCurrentPower() > 0) && (m_fChargeLevel < 100))
    {
        rate = GetChargeRate(true);

        if (rate > 0)
        {
            m_fChargeLevel += rate;

            // Make sure we don't overcharge
            if (m_fChargeLevel > 100)
            {
                m_fChargeLevel = 100;
            }

            if (m_fChargeLevel == 100)
            {
                if (GetOwnerObject()
                    && GetOwnerObject()->GetType() == HST_SHIP)
                {
                    CHSShip *cShip;
                    cShip = (CHSShip *) GetOwnerObject();
                    if (cShip)
                    {
                        cShip->NotifyConsoles(hsInterface.
                                              HSPrintf
                                              ("%s%s-%s Jump Drive charged.",
                                               ANSI_HILITE, ANSI_GREEN,
                                               ANSI_NORMAL), MSG_ENGINEERING);
                    }
                }
            }

        }
    }

    // If engaged, consume fuel.
    if (m_bEngaged)
    {
        ConsumeFuelBySpeed(m_uiSublightSpeed * m_iJumpSpeedMultiplier);
    }
}
Exemplo n.º 5
0
// Gets the fuel system for the engines. Replaces the m_fuel_source variable.
CHSFuelSystem* CHSSysEngines::GetFuelSource(void)
{
      CHSShip *cShip = (CHSShip *) GetOwnerObject();
      if (!cShip)
              return NULL;
      return (CHSFuelSystem *)cShip->GetSystems().GetSystem(HSS_FUEL_SYSTEM);
}
Exemplo n.º 6
0
// Gets the fuel system for the engines. Replaces the m_fuel_source variable.
CHSFuelSystem* CHSJumpDrive::GetFuelSource(void)
{
	CHSShip *cShip = (CHSShip *) GetOwnerObject();
	if (!cShip)
    {
		return NULL;
    }
	return (CHSFuelSystem *)cShip->GetSystems().GetSystem(HSS_FUEL_SYSTEM);
}
Exemplo n.º 7
0
void CHSJumpDrive::CutPower(HS_INT32 level)
{
    if (level == 0)
    {
        if (GetOwnerObject() && (GetOwnerObject()->GetType() == HST_SHIP))
        {
            CHSShip *cShip;

            cShip = (CHSShip *) GetOwnerObject();

            if (hsInterface.AtrGet(cShip->GetDbref(), "HSMSG_JUMPERS_CUT"))
            {
                char *msg = hsInterface.EvalExpression(hsInterface.m_buffer,
                                                       cShip->GetDbref(),
                                                       cShip->GetDbref(),
                                                       cShip->GetDbref());
                cShip->NotifySrooms(msg);
            }
            else
            {
                cShip->NotifySrooms(HSCONF.jumpers_cut);
            }
        }

        // Set charge level to 0.
        m_fChargeLevel = 0;

        // If jumpers are engaged and power is set to 0, then
        // disengage.
        if (GetEngaged())
        {
            HS_INT8 tbuf[128];

            m_bEngaged = false;
            sprintf(tbuf, "%s%s-%s Jump drive disengaged.",
                    ANSI_HILITE, ANSI_GREEN, ANSI_NORMAL);
            if (GetOwnerObject())
            {
                GetOwnerObject()->HandleMessage(tbuf, MSG_ENGINEERING);
            }
        }

    }
}
Exemplo n.º 8
0
// Tells the engines that they need to gobble up some fuel
// from the fuel source.  The engines know their efficiency
// and such, so they just drain the fuel from the fuel system.
// Speed here should be given in units per hour.
void CHSSysEngines::ConsumeFuelBySpeed(HS_INT32 speed)
{
    float fConsume;
    float fRealized;

    // Do we have a fuel system?
    if (!GetFuelSource() ||
        (GetFuelSource()->GetFuelRemaining() <= 0))
    {
        return;
    }

    // If efficiency is 0, do not consume fuel
    if (0 == GetEfficiency())
    {
        return;
    }

    // Calculate per second travel rate
    fConsume = (float) (speed * .0002778);

    // Divide by efficiency
    fConsume = (float) (fConsume / (1000.0 * GetEfficiency()));

    // Engines consume burnable fuel
    fRealized = GetFuelSource()->ExtractFuelUnit(fConsume);

    // check system consumed the ammount we asked for
    if (fRealized < fConsume)
    {
        // Out of gas.  Set desired speed to 0.
        m_desired_speed = 0;
        HS_INT8 tbuf[128];
        sprintf_s(tbuf,
                "%s%s-%s A warning light flashing, indicating engines have run \
			out of fuel.",
                ANSI_HILITE, ANSI_YELLOW, ANSI_NORMAL);
        if (GetOwnerObject())
        {
            GetOwnerObject()->HandleMessage(tbuf, MSG_ENGINEERING, NULL);
        }
    }
}
Exemplo n.º 9
0
// Tells the engines that they need to gobble up some fuel
// from the fuel source.  The engines know their efficiency
// and such, so they just drain the fuel from the fuel system.
// Speed here should be given in units per hour.
void CHSJumpDrive::ConsumeFuelBySpeed(HS_INT32 speed)
{
    float fConsume;
    float fRealized;

    // Do we have a fuel system?
    if (!GetFuelSource() || (GetFuelSource()->GetFuelRemaining() <= 0))
    {
        return;
    }

    // Do not consume fuel if efficiency is 0
    if (0 == GetEfficiency())
    {
        return;
    }

    // Calculate per second travel rate
    fConsume = (float) (speed * .0002778);

    // Divide by efficiency
    fConsume = (float) (fConsume / (1000.0 * GetEfficiency()));

    fRealized = GetFuelSource()->ExtractFuelUnit(fConsume);
    if (fRealized < fConsume)
    {
        // Out of gas.  Disengage.
        m_bEngaged = false;
        HS_INT8 tbuf[128];
        sprintf(tbuf,
                "%s%s-%s A warning light flashing, indicating jump drives have \
			run out of fuel.",
                ANSI_HILITE, ANSI_YELLOW, ANSI_NORMAL);

        if (GetOwnerObject())
        {
            GetOwnerObject()->HandleMessage(tbuf, MSG_ENGINEERING, NULL);
        }
    }
}
Exemplo n.º 10
0
void CHSDamCon::AssignCrew(HS_DBREF player, int iCrew, CHSEngSystem * pSystem)
{
    // Be certain this is a valid crew ID.
    if ((iCrew < 1) || (iCrew > (int) GetNumCrews()))
    {
        return;
    }

    // Grab this crew's structure from the vector.
    THSDamageCrew & rtCrew = m_vecCrews[iCrew];

    // If we're assigning to a valid system, try that.  
    // Otherwise, unassign this crew.
    if (pSystem)
    {
        // Only one crew can be assigned to a system at any one time.
        HS_INT32 iNumCrews = GetNumCrews();

        for (int idx = 0; idx < iNumCrews; idx++)
        {
            // If this crew is the one we're assigning, ignore it.
            if (idx == iCrew)
            {
                continue;
            }

            THSDamageCrew & rtAssignedCrew = m_vecCrews[idx];

            // Is this crew assigned to the system we want?
            if (rtAssignedCrew.pAssignedTo == pSystem)
            {
                hsStdError(player,
                           "A repair crew is already working on that system.");
                return;
            }
        }

        // This crew is now assigned.
        rtCrew.pAssignedTo = pSystem;
        rtCrew.iSecondsLeft = HSCONF.damage_repair_time;

        if (0 == rtCrew.iSecondsLeft)
        {
            rtCrew.iSecondsLeft = 1;
        }

        if (GetOwnerObject()->GetType() == HST_SHIP)
        {
            CHSShip *pOwnerShip = static_cast < CHSShip * >(GetOwnerObject());

            pOwnerShip->NotifyConsoles(hsInterface.
                                       HSPrintf
                                       ("%s%s-%s Damage Control crew %i assigned to %s.",
                                        ANSI_HILITE, ANSI_GREEN, ANSI_NORMAL,
                                        iCrew, pSystem->GetName()),
                                       MSG_ENGINEERING);
        }
    }
    else
    {
        // This crew is unassigned.
        rtCrew.pAssignedTo = NULL;
        rtCrew.iSecondsLeft = 0;

        if (GetOwnerObject()->GetType() == HST_SHIP)
        {
            CHSShip *pOwnerShip = static_cast < CHSShip * >(GetOwnerObject());

            pOwnerShip->NotifyConsoles(hsInterface.
                                       HSPrintf
                                       ("%s%s-%s Damage Control crew %i now idle.",
                                        ANSI_HILITE, ANSI_GREEN, ANSI_NORMAL,
                                        iCrew), MSG_ENGINEERING);
        }
    }
}
Exemplo n.º 11
0
void CHSDamCon::DoCycle()
{
    // First we do the basic cycle, stress and such.
    CHSEngSystem::DoCycle();

    // Now we'll just go through our damage crews.
    HS_INT32 iEfficiency;
    HS_INT32 iRandNum;

    // Calculate percentage of power allocated to damage control.
    if (GetCurrentPower() != 0 && GetOptimalPower(false) != 0)
    {
        iEfficiency = (int) (100 * ((GetCurrentPower() * 1.00) /
                                    (GetOptimalPower(false) * 1.00)));
    }
    else
    {
        iEfficiency = 0;
    }

    iRandNum = hsInterface.GetRandom(99) + 1;

    // If we roll a random number greater than the power allocated to damage
    // control, then this round of damage control goes into the toilet.
    if (iRandNum > iEfficiency)
    {
        return;
    }

    // Insure that our number of crews matches the vector size.
    m_vecCrews.resize(GetNumCrews() + 1);

    // Run through all of our damage crews.
    // Those that are assigned get their time remaining reduced.
    unsigned int idx;
    for (idx = 1; idx <= GetNumCrews(); idx++)
    {
        THSDamageCrew & rtCrew = m_vecCrews[idx];

        // Is this crew working on anything?
        if (!rtCrew.pAssignedTo)
        {
            continue;
        }

        // This crew's time decreases.
        if (rtCrew.iSecondsLeft > 0)
        {
            rtCrew.iSecondsLeft--;
        }

        // If the crew is done working, reduce the damage on the system.
        if (rtCrew.iSecondsLeft <= 0)
        {
            rtCrew.pAssignedTo->ReduceDamage();

            // If this system is fully repaired, notify everyone, and pull this
            // crew off duty.
            if (rtCrew.pAssignedTo->GetDamageLevel() == DMG_NONE)
            {
                // If this system is part of a ship,
                // notify all consoles that repairs are complete.
                if (GetOwnerObject()->GetType() == HST_SHIP)
                {
                    CHSShip *pOwnerShip =
                        static_cast < CHSShip * >(GetOwnerObject());

                    pOwnerShip->NotifyConsoles(hsInterface.
                                               HSPrintf
                                               ("%s%s-%s %s repairs complete.",
                                                ANSI_HILITE, ANSI_GREEN,
                                                ANSI_NORMAL,
                                                rtCrew.pAssignedTo->
                                                GetName()), MSG_ENGINEERING);
                }

                // This crew is no longer assigned.
                rtCrew.pAssignedTo = NULL;
            }
            else
            {
                // This system is not repaired.  Reassign the crew to another
                // round of repairs.
                rtCrew.iSecondsLeft = HSCONF.damage_repair_time;

                if (0 == rtCrew.iSecondsLeft)
                {
                    rtCrew.iSecondsLeft = 1;
                }

                if (GetOwnerObject()->GetType() == HST_SHIP)
                {
                    CHSShip *pOwnerShip =
                        static_cast < CHSShip * >(GetOwnerObject());

                    pOwnerShip->NotifyConsoles(hsInterface.
                                               HSPrintf
                                               ("%s%s-%s %s repairs incomplete, continuing repairs.",
                                                ANSI_HILITE, ANSI_GREEN,
                                                ANSI_NORMAL,
                                                rtCrew.pAssignedTo->
                                                GetName()), MSG_ENGINEERING);
                }
            }
        }
    }
}
Exemplo n.º 12
0
			WfRuntimeExecutionAction WfRuntimeThreadContext::ExecuteInternal(WfInstruction& ins, WfRuntimeStackFrame& stackFrame, IWfDebuggerCallback* callback)
			{
				switch (ins.code)
				{
				case WfInsCode::LoadValue:
					PushValue(ins.valueParameter);
					return WfRuntimeExecutionAction::ExecuteInstruction;
				case WfInsCode::LoadClosure:
					{
						Ptr<WfRuntimeVariableContext> capturedVariables;
						if (ins.countParameter > 0)
						{
							capturedVariables = new WfRuntimeVariableContext;
							capturedVariables->variables.Resize(ins.countParameter);
							Value operand;
							for (vint i = 0; i < ins.countParameter; i++)
							{
								CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
								capturedVariables->variables[ins.countParameter - 1 - i] = operand;
							}
						}

						auto lambda = MakePtr<WfRuntimeLambda>(globalContext, capturedVariables, ins.indexParameter);
						PushValue(Value::From(lambda));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::LoadException:
					{
						PushValue(BoxValue(exceptionInfo));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::LoadLocalVar:
					{
						Value operand;
						CONTEXT_ACTION(LoadLocalVariable(ins.indexParameter, operand), L"illegal local variable index.");
						PushValue(operand);
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::LoadCapturedVar:
					{
						Value operand;
						CONTEXT_ACTION(LoadCapturedVariable(ins.indexParameter, operand), L"illegal captured variable index.");
						PushValue(operand);
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::LoadGlobalVar:
					{
						CALL_DEBUGGER(callback->BreakRead(globalContext->assembly.Obj(), ins.indexParameter));
						Value operand;
						CONTEXT_ACTION(LoadGlobalVariable(ins.indexParameter, operand), L"illegal global variable index.");
						PushValue(operand);
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::StoreLocalVar:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						CONTEXT_ACTION(StoreLocalVariable(ins.indexParameter, operand), L"illegal local variable index.");
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::StoreGlobalVar:
					{
						CALL_DEBUGGER(callback->BreakWrite(globalContext->assembly.Obj(), ins.indexParameter));
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						CONTEXT_ACTION(StoreGlobalVariable(ins.indexParameter, operand), L"illegal global variable index.");
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::Duplicate:
					{
						vint index = stack.Count() - 1 - ins.countParameter;
						Value operand;
						CONTEXT_ACTION(LoadStackValue(index, operand), L"failed to duplicate a value from the stack.");
						PushValue(operand);
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::Pop:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::Return:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop the function result.");
						CONTEXT_ACTION(PopStackFrame(), L"failed to pop the stack frame.");
						PushValue(operand);
						if (stackFrames.Count() == 0)
						{
							status = WfRuntimeExecutionStatus::Finished;
						}
						return WfRuntimeExecutionAction::ExitStackFrame;
					}
				case WfInsCode::CreateArray:
					{
						auto list = IValueList::Create();
						Value operand;
						for (vint i = 0; i < ins.countParameter; i++)
						{
							CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
							list->Add(operand);
						}
						PushValue(Value::From(list));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::CreateMap:
					{
						auto map = IValueDictionary::Create();
						Value key, value;
						for (vint i = 0; i < ins.countParameter; i+=2)
						{
							CONTEXT_ACTION(PopValue(value), L"failed to pop a value from the stack.");
							CONTEXT_ACTION(PopValue(key), L"failed to pop a value from the stack.");
							map->Set(key, value);
						}
						PushValue(Value::From(map));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::CreateInterface:
					{
						auto proxy = MakePtr<WfRuntimeInterfaceInstance>();
						Value key, value;
						for (vint i = 0; i < ins.countParameter; i+=2)
						{
							CONTEXT_ACTION(PopValue(value), L"failed to pop a value from the stack.");
							CONTEXT_ACTION(PopValue(key), L"failed to pop a value from the stack.");
							auto name = UnboxValue<WString>(key);
							auto func = UnboxValue<Ptr<IValueFunctionProxy>>(value);
							proxy->functions.Add(name, func);
						}
						PushValue(Value::From(proxy));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::CreateRange:
					BEGIN_TYPE
						EXECUTE(OpCreateRange, I1)
						EXECUTE(OpCreateRange, I2)
						EXECUTE(OpCreateRange, I4)
						EXECUTE(OpCreateRange, I8)
						EXECUTE(OpCreateRange, U1)
						EXECUTE(OpCreateRange, U2)
						EXECUTE(OpCreateRange, U4)
						EXECUTE(OpCreateRange, U8)
					END_TYPE
				case WfInsCode::ReverseEnumerable:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						Value reversedEnumerable = OPERATOR_OpReverseEnumerable(operand);
						PushValue(reversedEnumerable);
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::DeleteRawPtr:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						operand.DeleteRawPtr();
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::ConvertToType:
					{
						Value result, converted;
						CONTEXT_ACTION(PopValue(result), L"failed to pop a value from the stack.");
						if (OPERATOR_OpConvertToType(result, converted, ins))
						{
							PushValue(converted);
							return WfRuntimeExecutionAction::ExecuteInstruction;
						}
						else
						{
							WString from = result.IsNull() ? L"<null>" : L"<" + result.GetText() + L"> of " + result.GetTypeDescriptor()->GetTypeName();
							WString to = ins.typeDescriptorParameter->GetTypeName();
							RaiseException(L"Failed to convert from \"" + from + L"\" to \"" + to + L"\".", false);
							return WfRuntimeExecutionAction::Nop;
						}
					}
				case WfInsCode::TryConvertToType:
					{
						Value result, converted;
						CONTEXT_ACTION(PopValue(result), L"failed to pop a value from the stack.");
						if (OPERATOR_OpConvertToType(result, converted, ins))
						{
							PushValue(converted);
						}
						else
						{
							PushValue(Value());
						}
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::TestType:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						if (operand.GetTypeDescriptor() && operand.GetValueType() == ins.flagParameter && operand.GetTypeDescriptor()->CanConvertTo(ins.typeDescriptorParameter))
						{
							PushValue(BoxValue(true));
						}
						else
						{
							PushValue(BoxValue(false));
						}
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::GetType:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						PushValue(Value::From(operand.GetTypeDescriptor()));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::Jump:
					{
						stackFrame.nextInstructionIndex = ins.indexParameter;
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::JumpIf:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						if (UnboxValue<bool>(operand))
						{
							stackFrame.nextInstructionIndex = ins.indexParameter;
						}
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::Invoke:
					{
						CONTEXT_ACTION(PushStackFrame(ins.indexParameter, ins.countParameter), L"failed to invoke a function.");
						return WfRuntimeExecutionAction::EnterStackFrame;
					}
				case WfInsCode::GetProperty:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						CALL_DEBUGGER(callback->BreakGet(operand.GetRawPtr(), ins.propertyParameter));
						Value result = ins.propertyParameter->GetValue(operand);
						PushValue(result);
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::SetProperty:
					{
						Value operand, value;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						CONTEXT_ACTION(PopValue(value), L"failed to pop a value from the stack.");
						CALL_DEBUGGER(callback->BreakSet(operand.GetRawPtr(), ins.propertyParameter));
						ins.propertyParameter->SetValue(operand, value);
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::InvokeProxy:
					{
						Value thisValue;
						CONTEXT_ACTION(PopValue(thisValue), L"failed to pop a value from the stack.");
						auto proxy = UnboxValue<Ptr<IValueFunctionProxy>>(thisValue);
						if (!proxy)
						{
							INTERNAL_ERROR(L"failed to invoke a null function proxy.");
							return WfRuntimeExecutionAction::Nop;
						}

						if (auto lambda = proxy.Cast<WfRuntimeLambda>())
						{
							if (lambda->globalContext == globalContext)
							{
								CONTEXT_ACTION(PushStackFrame(lambda->functionIndex, ins.countParameter, lambda->capturedVariables), L"failed to invoke a function.");
								return WfRuntimeExecutionAction::EnterStackFrame;
							}
						}

						List<Value> arguments;
						for (vint i = 0; i < ins.countParameter; i++)
						{
							Value argument;
							CONTEXT_ACTION(PopValue(argument), L"failed to pop a value from the stack.");
							arguments.Insert(0, argument);
						}

						Ptr<IValueList> list = new ValueListWrapper<List<Value>*>(&arguments);
						Value result = proxy->Invoke(list);
						PushValue(result);
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::InvokeMethod:
					{
						Value thisValue;
						CONTEXT_ACTION(PopValue(thisValue), L"failed to pop a value from the stack.");
						CALL_DEBUGGER(callback->BreakInvoke(thisValue.GetRawPtr(), ins.methodParameter));

						if (auto staticMethod = dynamic_cast<WfStaticMethod*>(ins.methodParameter))
						{
							if (staticMethod->GetGlobalContext() == globalContext.Obj())
							{
								CONTEXT_ACTION(PushStackFrame(staticMethod->functionIndex, ins.countParameter, nullptr), L"failed to invoke a function.");
								return WfRuntimeExecutionAction::EnterStackFrame;
							}
						}

						Array<Value> arguments(ins.countParameter);
						for (vint i = 0; i < ins.countParameter; i++)
						{
							Value argument;
							CONTEXT_ACTION(PopValue(argument), L"failed to pop a value from the stack.");
							arguments[ins.countParameter - i - 1] = argument;
						}

						Value result = ins.methodParameter->Invoke(thisValue, arguments);
						PushValue(result);
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::AttachEvent:
					{
						Value thisValue, function;
						CONTEXT_ACTION(PopValue(function), L"failed to pop a value from the stack.");
						CONTEXT_ACTION(PopValue(thisValue), L"failed to pop a value from the stack.");
						CALL_DEBUGGER(callback->BreakAttach(thisValue.GetRawPtr(), ins.eventParameter));
						auto proxy = UnboxValue<Ptr<IValueFunctionProxy>>(function);
						auto handler = ins.eventParameter->Attach(thisValue, proxy);
						PushValue(Value::From(handler));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::DetachEvent:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						auto handler = UnboxValue<Ptr<IEventHandler>>(operand);
						CALL_DEBUGGER(callback->BreakDetach(handler->GetOwnerObject().GetRawPtr(), handler->GetOwnerEvent()));
						auto result = handler->Detach();
						PushValue(BoxValue(result));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::InstallTry:
					CONTEXT_ACTION(PushTrapFrame(ins.indexParameter), L"failed to push a trap frame");
					return WfRuntimeExecutionAction::ExecuteInstruction;
				case WfInsCode::UninstallTry:
					{
						if (trapFrames.Count() == 0)
						{
							INTERNAL_ERROR(L"failed to pop the trap frame.");
						}
						auto frame = GetCurrentTrapFrame();
						CONTEXT_ACTION(PopTrapFrame(ins.countParameter), L"failed to pop the trap frame.");
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::RaiseException:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						if (operand.GetValueType() == Value::Text)
						{
							RaiseException(operand.GetText(), false);
						}
						else if (auto info = operand.GetSharedPtr().Cast<WfRuntimeExceptionInfo>())
						{
							RaiseException(info);
						}
						else
						{
							INTERNAL_ERROR(L"failed to raise an exception which is neither a string nor a WfRuntimeExceptionInfo.");
						}
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::TestElementInSet:
					{
						Value element, set;
						CONTEXT_ACTION(PopValue(set), L"failed to pop a value from the stack.");
						CONTEXT_ACTION(PopValue(element), L"failed to pop a value from the stack.");

						auto enumerable = UnboxValue<Ptr<IValueEnumerable>>(set);
						auto enumerator = enumerable->CreateEnumerator();
						while (enumerator->Next())
						{
							if (enumerator->GetCurrent() == element)
							{
								PushValue(BoxValue(true));
								return WfRuntimeExecutionAction::ExecuteInstruction;
							}
						}
						PushValue(BoxValue(false));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::CompareLiteral:
					BEGIN_TYPE
						EXECUTE(OpCompare, Bool)
						EXECUTE(OpCompare, I1)
						EXECUTE(OpCompare, I2)
						EXECUTE(OpCompare, I4)
						EXECUTE(OpCompare, I8)
						EXECUTE(OpCompare, U1)
						EXECUTE(OpCompare, U2)
						EXECUTE(OpCompare, U4)
						EXECUTE(OpCompare, U8)
						EXECUTE(OpCompare, F4)
						EXECUTE(OpCompare, F8)
						EXECUTE(OpCompare, String)
					END_TYPE
				case WfInsCode::CompareStruct:
					{
						Value first, second;
						CONTEXT_ACTION(PopValue(second), L"failed to pop a value from the stack.");
						CONTEXT_ACTION(PopValue(first), L"failed to pop a value from the stack.");
						if (!first.IsNull() && !first.GetTypeDescriptor()->GetValueSerializer())
						{
							INTERNAL_ERROR(L"type" + first.GetTypeDescriptor()->GetTypeName() + L" is not a struct.");
						}
						if (!second.IsNull() && !second.GetTypeDescriptor()->GetValueSerializer())
						{
							INTERNAL_ERROR(L"type" + second.GetTypeDescriptor()->GetTypeName() + L" is not a struct.");
						}

						if (first.GetValueType() != second.GetValueType())
						{
							PushValue(BoxValue(false));
						}
						else if (first.IsNull())
						{
							PushValue(BoxValue(true));
						}
						else
						{
							PushValue(BoxValue(first.GetText() == second.GetText()));
						}
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::CompareReference:
					{
						Value first, second;
						CONTEXT_ACTION(PopValue(second), L"failed to pop a value from the stack.");
						CONTEXT_ACTION(PopValue(first), L"failed to pop a value from the stack.");
						bool result = first.GetValueType() != Value::Text && second.GetValueType() != Value::Text && first.GetRawPtr() == second.GetRawPtr();
						PushValue(BoxValue(result));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::CompareValue:
					{
						Value first, second;
						CONTEXT_ACTION(PopValue(second), L"failed to pop a value from the stack.");
						CONTEXT_ACTION(PopValue(first), L"failed to pop a value from the stack.");
						switch (first.GetValueType())
						{
						case Value::RawPtr:
						case Value::SharedPtr:
							switch (first.GetValueType())
							{
							case Value::RawPtr:
							case Value::SharedPtr:
								PushValue(BoxValue(first.GetRawPtr() == second.GetRawPtr()));
								break;
							default:
								PushValue(BoxValue(false));
							}
							break;
						case Value::Text:
							switch (first.GetValueType())
							{
							case Value::Text:
								PushValue(BoxValue(first.GetText() == second.GetText()));
							default:
								PushValue(BoxValue(false));
							}
							break;
						default:
							PushValue(BoxValue(second.IsNull()));
						}
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::OpNot:
					BEGIN_TYPE
						EXECUTE(OpNot_Bool, Bool)
						EXECUTE(OpNot, I1)
						EXECUTE(OpNot, I2)
						EXECUTE(OpNot, I4)
						EXECUTE(OpNot, I8)
						EXECUTE(OpNot, U1)
						EXECUTE(OpNot, U2)
						EXECUTE(OpNot, U4)
						EXECUTE(OpNot, U8)
					END_TYPE
				case WfInsCode::OpPositive:
					BEGIN_TYPE
						EXECUTE(OpPositive, I1)
						EXECUTE(OpPositive, I2)
						EXECUTE(OpPositive, I4)
						EXECUTE(OpPositive, I8)
						EXECUTE(OpPositive, U1)
						EXECUTE(OpPositive, U2)
						EXECUTE(OpPositive, U4)
						EXECUTE(OpPositive, U8)
						EXECUTE(OpPositive, F4)
						EXECUTE(OpPositive, F8)
					END_TYPE
				case WfInsCode::OpNegative:
					BEGIN_TYPE
						EXECUTE(OpNegative, I1)
						EXECUTE(OpNegative, I2)
						EXECUTE(OpNegative, I4)
						EXECUTE(OpNegative, I8)
						EXECUTE(OpNegative, F4)
						EXECUTE(OpNegative, F8)
					END_TYPE
				case WfInsCode::OpConcat:
					{
						Value first, second;
						CONTEXT_ACTION(PopValue(second), L"failed to pop a value from the stack.");
						CONTEXT_ACTION(PopValue(first), L"failed to pop a value from the stack.");
						PushValue(BoxValue(first.GetText() + second.GetText()));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
				case WfInsCode::OpExp:
					BEGIN_TYPE
						EXECUTE(OpExp, F4)
						EXECUTE(OpExp, F8)
					END_TYPE
				case WfInsCode::OpAdd:
					BEGIN_TYPE
						EXECUTE(OpAdd, I1)
						EXECUTE(OpAdd, I2)
						EXECUTE(OpAdd, I4)
						EXECUTE(OpAdd, I8)
						EXECUTE(OpAdd, U1)
						EXECUTE(OpAdd, U2)
						EXECUTE(OpAdd, U4)
						EXECUTE(OpAdd, U8)
						EXECUTE(OpAdd, F4)
						EXECUTE(OpAdd, F8)
					END_TYPE
				case WfInsCode::OpSub:
					BEGIN_TYPE
						EXECUTE(OpSub, I1)
						EXECUTE(OpSub, I2)
						EXECUTE(OpSub, I4)
						EXECUTE(OpSub, I8)
						EXECUTE(OpSub, U1)
						EXECUTE(OpSub, U2)
						EXECUTE(OpSub, U4)
						EXECUTE(OpSub, U8)
						EXECUTE(OpSub, F4)
						EXECUTE(OpSub, F8)
					END_TYPE
				case WfInsCode::OpMul:
					BEGIN_TYPE
						EXECUTE(OpMul, I1)
						EXECUTE(OpMul, I2)
						EXECUTE(OpMul, I4)
						EXECUTE(OpMul, I8)
						EXECUTE(OpMul, U1)
						EXECUTE(OpMul, U2)
						EXECUTE(OpMul, U4)
						EXECUTE(OpMul, U8)
						EXECUTE(OpMul, F4)
						EXECUTE(OpMul, F8)
					END_TYPE
				case WfInsCode::OpDiv:
					BEGIN_TYPE
						EXECUTE(OpDiv, I1)
						EXECUTE(OpDiv, I2)
						EXECUTE(OpDiv, I4)
						EXECUTE(OpDiv, I8)
						EXECUTE(OpDiv, U1)
						EXECUTE(OpDiv, U2)
						EXECUTE(OpDiv, U4)
						EXECUTE(OpDiv, U8)
						EXECUTE(OpDiv, F4)
						EXECUTE(OpDiv, F8)
					END_TYPE
				case WfInsCode::OpMod:
					BEGIN_TYPE
						EXECUTE(OpMod, I1)
						EXECUTE(OpMod, I2)
						EXECUTE(OpMod, I4)
						EXECUTE(OpMod, I8)
						EXECUTE(OpMod, U1)
						EXECUTE(OpMod, U2)
						EXECUTE(OpMod, U4)
						EXECUTE(OpMod, U8)
					END_TYPE
				case WfInsCode::OpShl:
					BEGIN_TYPE
						EXECUTE(OpShl, I1)
						EXECUTE(OpShl, I2)
						EXECUTE(OpShl, I4)
						EXECUTE(OpShl, I8)
						EXECUTE(OpShl, U1)
						EXECUTE(OpShl, U2)
						EXECUTE(OpShl, U4)
						EXECUTE(OpShl, U8)
					END_TYPE
				case WfInsCode::OpShr:
					BEGIN_TYPE
						EXECUTE(OpShr, I1)
						EXECUTE(OpShr, I2)
						EXECUTE(OpShr, I4)
						EXECUTE(OpShr, I8)
						EXECUTE(OpShr, U1)
						EXECUTE(OpShr, U2)
						EXECUTE(OpShr, U4)
						EXECUTE(OpShr, U8)
					END_TYPE
				case WfInsCode::OpXor:
					BEGIN_TYPE
						EXECUTE(OpXor, Bool)
						EXECUTE(OpXor, I1)
						EXECUTE(OpXor, I2)
						EXECUTE(OpXor, I4)
						EXECUTE(OpXor, I8)
						EXECUTE(OpXor, U1)
						EXECUTE(OpXor, U2)
						EXECUTE(OpXor, U4)
						EXECUTE(OpXor, U8)
					END_TYPE
				case WfInsCode::OpAnd:
					BEGIN_TYPE
						EXECUTE(OpAnd_Bool, Bool)
						EXECUTE(OpAnd, I1)
						EXECUTE(OpAnd, I2)
						EXECUTE(OpAnd, I4)
						EXECUTE(OpAnd, I8)
						EXECUTE(OpAnd, U1)
						EXECUTE(OpAnd, U2)
						EXECUTE(OpAnd, U4)
						EXECUTE(OpAnd, U8)
					END_TYPE
				case WfInsCode::OpOr:
					BEGIN_TYPE
						EXECUTE(OpOr_Bool, Bool)
						EXECUTE(OpOr, I1)
						EXECUTE(OpOr, I2)
						EXECUTE(OpOr, I4)
						EXECUTE(OpOr, I8)
						EXECUTE(OpOr, U1)
						EXECUTE(OpOr, U2)
						EXECUTE(OpOr, U4)
						EXECUTE(OpOr, U8)
					END_TYPE
				case WfInsCode::OpLT:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						vint value = UnboxValue<vint>(operand);
						PushValue(BoxValue(value < 0));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
					break;
				case WfInsCode::OpGT:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						vint value = UnboxValue<vint>(operand);
						PushValue(BoxValue(value > 0));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
					break;
				case WfInsCode::OpLE:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						vint value = UnboxValue<vint>(operand);
						PushValue(BoxValue(value <= 0));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
					break;
				case WfInsCode::OpGE:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						vint value = UnboxValue<vint>(operand);
						PushValue(BoxValue(value >= 0));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
					break;
				case WfInsCode::OpEQ:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						vint value = UnboxValue<vint>(operand);
						PushValue(BoxValue(value == 0));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
					break;
				case WfInsCode::OpNE:
					{
						Value operand;
						CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");
						vint value = UnboxValue<vint>(operand);
						PushValue(BoxValue(value != 0));
						return WfRuntimeExecutionAction::ExecuteInstruction;
					}
					break;
				default:
					return WfRuntimeExecutionAction::Nop;
				}
			}