Exemplo n.º 1
0
			WfRuntimeExecutionAction OPERATOR_OpCreateRange(WfRuntimeThreadContext& context)
			{
				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.");
				T firstValue = UnboxValue<T>(first);
				T secondValue = UnboxValue<T>(second);
				auto enumerable = MakePtr<WfRuntimeRange<T>>(firstValue, secondValue);
				context.PushValue(Value::From(enumerable));
				return WfRuntimeExecutionAction::ExecuteInstruction;
			}
Exemplo n.º 2
0
 //------------------------------------------------------------------------------
 void Evaluator::ApplyBinOp(Token::BinOp op)
 {
   float b = PopValue();
   float a = PopValue();
   switch (op)
   {
   case Token::BinOpAdd: PushValue(a + b); break;
   case Token::BinOpSub: PushValue(a - b); break;
   case Token::BinOpMul: PushValue(a * b); break;
   case Token::BinOpDiv: PushValue(a / b); break;
   default: LOG_WARN("Unknown bin-op!");
   }
 }
Exemplo n.º 3
0
int PT_Set (lua_State *L) {
    ParamTable *pt = check_PT (L, 1);
    const char *key = luaL_checkstring (L, 2);
    luaL_argcheck (L, key, 2, "a valid string expected");
    const Value &val = PopValue (L, 3);
    DEBUG ("PT_Set: %s\n", key);
    pt->Set (key, val);
    return 0;
}
Exemplo n.º 4
0
			WfRuntimeExecutionAction OPERATOR_OpCompare(WfRuntimeThreadContext& context)
			{
				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 firstNull = first.GetValueType() == Value::Null;
				bool secondNull = second.GetValueType() == Value::Null;
				if (firstNull)
				{
					if (secondNull)
					{
						context.PushValue(BoxValue((vint)0));
					}
					else
					{
						context.PushValue(BoxValue((vint)-1));
					}
				}
				else
				{
					if (secondNull)
					{context.PushValue(BoxValue((vint)1));
					}
					else
					{
						T firstValue = UnboxValue<T>(first);
						T secondValue = UnboxValue<T>(second);
						if (firstValue < secondValue)
						{
							context.PushValue(BoxValue((vint)-1));
						}
						else if (firstValue > secondValue)
						{
							context.PushValue(BoxValue((vint)1));
						}
						else
						{
							context.PushValue(BoxValue((vint)0));
						}
					}
				}
				return WfRuntimeExecutionAction::ExecuteInstruction;
			}
Exemplo n.º 5
0
  //------------------------------------------------------------------------------
  float Evaluator::Evaluate(const vector<Token>& expression, const Environment* env)
  {

    // Now perform the actual shunting :)
    for (size_t i = 0; i < expression.size(); ++i)
    {
      const Token& t = expression[i];

      if (t.type == Token::Type::Constant)
      {
        operandStack.push_back(t);
      }
      else if (t.type == Token::Type::BinOp)
      {
        // Apply any higher priority operators
        int prio = BINOP_PRIO[t.binOp];
        while (!operatorStack.empty())
        {
          const Token& op = operatorStack.back();
          if (op.type == Token::Type::BinOp && BINOP_PRIO[op.binOp] >= prio)
          {
            ApplyBinOp(op.binOp);
            operatorStack.pop_back();
          }
          else
            break;
        }

        operatorStack.push_back(t);
      }
      else if (t.type == Token::Type::FuncCall)
      {
        operatorStack.push_back(t);
      }
      else if (t.type == Token::Type::LeftParen)
      {
        operatorStack.push_back(t);
      }
      else if (t.type == Token::Type::Comma)
      {
        // apply all the operators until the left paren
        ApplyUntilLeftParen(false);
      }
      else if (t.type == Token::Type::RightParen)
      {
        ApplyUntilLeftParen(true);
        if (!operatorStack.empty())
        {
          // if the token at the top of the operator stack is a function call,
          // then invoke it
          Token t = operatorStack.back();
          if (t.type == Token::Type::FuncCall)
          {
            InvokeFunction(t, env);
            operatorStack.pop_back();
          }
        }
      }
      else if (t.type == Token::Type::Var)
      {
        LookupVar(t, env);
      }
    }

    // apply all the remaining operators
    while (!operatorStack.empty())
    {
      ApplyBinOp(PopOperator().binOp);
    }

    return PopValue();
  }
Exemplo n.º 6
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;
				}
			}