File Index Symbol Index

#include "WfRuntime.h" #include <math.h>
#ifdef VCZH_DESCRIPTABLEOBJECT_WITH_METADATA
namespace
vl
{
namespace
workflow
{
namespace
runtime
{
using
namespace
collections
;
using
namespace
reflection
;
using
namespace
reflection
::
description
;
using
namespace
typeimpl
;
/*********************************************************************** WfRuntimeThreadContext (Operators) ***********************************************************************/
#define INTERNAL_ERROR(MESSAGE)\
do{\
context.RaiseException(WString(L"Internal error: " MESSAGE), true);\
return WfRuntimeExecutionAction::Nop; \
} while (0)\
#define CONTEXT_ACTION(ACTION, MESSAGE)\
do{\
if ((context.ACTION) != WfRuntimeThreadContextError::Success)\
{\
INTERNAL_ERROR(MESSAGE);\
}\
} while (0)\
//-------------------------------------------------------------------------------
#define UNARY_OPERATOR(NAME, OPERATOR)\
template<typename T>\
WfRuntimeExecutionAction OPERATOR_##NAME(WfRuntimeThreadContext& context)\
{\
Value operand;\
CONTEXT_ACTION(PopValue(operand), L"failed to pop a value from the stack.");\
T value = OPERATOR UnboxValue<T>(operand);\
CONTEXT_ACTION(PushValue(BoxValue(value)), L"failed to push a value to the stack.");\
return WfRuntimeExecutionAction::ExecuteInstruction;\
}\
#define BINARY_OPERATOR(NAME, OPERATOR)\
template<typename T>\
WfRuntimeExecutionAction OPERATOR_##NAME(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 value = UnboxValue<T>(first) OPERATOR UnboxValue<T>(second);\
CONTEXT_ACTION(PushValue(BoxValue(value)), L"failed to push a value to the stack.");\
return WfRuntimeExecutionAction::ExecuteInstruction;\
}\
//-------------------------------------------------------------------------------
template
<
typename
T
>
WfRuntimeExecutionAction
OPERATOR_OpExp
(
WfRuntimeThreadContext
&
context
) {
Value
first
,
second
;
T
firstValue
=
UnboxValue
<
T
>(
first
);
T
secondValue
=
UnboxValue
<
T
>(
second
);
T
value
= (
T
)
exp
(
secondValue
*
log
(
firstValue
));
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
template
<
typename
T
>
WfRuntimeExecutionAction
OPERATOR_OpCompare
(
WfRuntimeThreadContext
&
context
) {
Value
first
,
second
;
bool
firstNull
=
first
.
GetValueType
() ==
Value
::
Null
;
bool
secondNull
=
second
.
GetValueType
() ==
Value
::
Null
;
if
(
firstNull
) {
if
(
secondNull
) { }
else
{ } }
else
{
if
(
secondNull
) { }
else
{
T
firstValue
=
UnboxValue
<
T
>(
first
);
T
secondValue
=
UnboxValue
<
T
>(
second
);
if
(
firstValue
<
secondValue
) { }
else
if
(
firstValue
>
secondValue
) { }
else
{ } } }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
/*********************************************************************** WfRuntimeThreadContext (TypeConversion) ***********************************************************************/
bool
OPERATOR_OpConvertToType
(
const
Value
&
result
,
Value
&
converted
,
const
WfInstruction
&
ins
) {
switch
(
ins
.
flagParameter
) {
case
Value
::
Null
:
return
false
;
case
Value
::
RawPtr
:
if
(
result
.
GetValueType
() ==
Value
::
BoxedValue
) {
return
false
; }
else
if
(
result
.
GetRawPtr
()) {
if
(
result
.
GetTypeDescriptor
()->
CanConvertTo
(
ins
.
typeDescriptorParameter
)) {
converted
=
Value
::
From
(
result
.
GetRawPtr
()); }
else
{
return
false
; } }
break
;
case
Value
::
SharedPtr
:
if
(
result
.
GetValueType
() ==
Value
::
BoxedValue
) {
return
false
; }
else
if
(
result
.
GetRawPtr
()) {
if
(
result
.
GetTypeDescriptor
()->
CanConvertTo
(
ins
.
typeDescriptorParameter
)) {
converted
=
Value
::
From
(
Ptr
<
DescriptableObject
>(
result
.
GetRawPtr
())); }
else
{
return
false
; } }
break
;
case
Value
::
BoxedValue
:
if
(
result
.
GetValueType
() !=
Value
::
BoxedValue
) {
return
false
; }
if
(
result
.
GetTypeDescriptor
() ==
ins
.
typeDescriptorParameter
) {
converted
=
result
;
return
true
; }
if
(
auto
stFrom
=
result
.
GetTypeDescriptor
()->
GetSerializableType
()) {
if
(
auto
stTo
=
ins
.
typeDescriptorParameter
->
GetSerializableType
()) {
WString
text
;
return
stFrom
->
Serialize
(
result
,
text
) &&
stTo
->
Deserialize
(
text
,
converted
); }
else
{
switch
(
ins
.
typeDescriptorParameter
->
GetTypeDescriptorFlags
()) {
case
TypeDescriptorFlags
::
FlagEnum
:
case
TypeDescriptorFlags
::
NormalEnum
:
if
(
result
.
GetTypeDescriptor
() !=
GetTypeDescriptor
<
vuint64_t
>()) {
return
false
; }
else
{
auto
intValue
=
result
.
GetBoxedValue
().
Cast
<
IValueType
::
TypedBox
<
vuint64_t
>>()
-
>
value
;
converted
=
ins
.
typeDescriptorParameter
->
GetEnumType
()->
ToEnum
(
intValue
); }
break
;
default
:
return
false
; } } }
else
{
switch
(
result
.
GetTypeDescriptor
()->
GetTypeDescriptorFlags
()) {
case
TypeDescriptorFlags
::
FlagEnum
:
case
TypeDescriptorFlags
::
NormalEnum
:
if
(
ins
.
typeDescriptorParameter
!=
GetTypeDescriptor
<
vuint64_t
>()) {
return
false
; }
else
{
auto
intValue
=
result
.
GetTypeDescriptor
()->
GetEnumType
()->
FromEnum
(
result
);
converted
=
BoxValue
<
vuint64_t
>(
intValue
); }
break
;
default
:
return
false
; } } }
return
true
; }
/*********************************************************************** WfRuntimeThreadContext (Range) ***********************************************************************/
template
<
typename
T
>
WfRuntimeExecutionAction
OPERATOR_OpCreateRange
(
WfRuntimeThreadContext
&
context
) {
Value
first
,
second
;
T
firstValue
=
UnboxValue
<
T
>(
first
);
T
secondValue
=
UnboxValue
<
T
>(
second
);
auto
enumerable
=
MakePtr
<
WfRuntimeRange
<
T
>>(
firstValue
,
secondValue
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
#undef INTERNAL_ERROR
#undef CONTEXT_ACTION
#undef UNARY_OPERATOR
#undef BINARY_OPERATOR
/*********************************************************************** Helper Functions ***********************************************************************/
Ptr
<
reflection
::
description
::
IValueFunctionProxy
>
LoadFunction
(
Ptr
<
WfRuntimeGlobalContext
>
context
,
const
WString
&
name
) {
const
auto
&
names
=
context
-
>
assembly
-
>
functionByName
[
name
];
vint
functionIndex
=
names
[
0
];
auto
lambda
=
MakePtr
<
WfRuntimeLambda
>(
context
,
nullptr
,
functionIndex
);
return
lambda
; }
/*********************************************************************** WfRuntimeThreadContext ***********************************************************************/
#define INTERNAL_ERROR(MESSAGE)\
do{\
RaiseException(WString(L"Internal error: " MESSAGE), true);\
return WfRuntimeExecutionAction::Nop; \
} while (0)\
#define CONTEXT_ACTION(ACTION, MESSAGE)\
do{\
if ((ACTION) != WfRuntimeThreadContextError::Success)\
{\
INTERNAL_ERROR(MESSAGE);\
}\
} while (0)\
#define CALL_DEBUGGER(ACTION)\
do {\
if (callback)\
{\
if (ACTION)\
{\
if (!callback->WaitForContinue())\
{\
INTERNAL_ERROR(L"Debugger stopped the program.");\
}\
}\
}\
} while (0)\
#define TYPE_OF_Bool bool
#define TYPE_OF_I1 vint8_t
#define TYPE_OF_I2 vint16_t
#define TYPE_OF_I4 vint32_t
#define TYPE_OF_I8 vint64_t
#define TYPE_OF_U1 vuint8_t
#define TYPE_OF_U2 vuint16_t
#define TYPE_OF_U4 vuint32_t
#define TYPE_OF_U8 vuint64_t
#define TYPE_OF_F4 float
#define TYPE_OF_F8 double
#define TYPE_OF_String WString
#define EXECUTE(OPERATION, TYPE) case WfInsType::TYPE: return OPERATOR_##OPERATION<TYPE_OF_##TYPE>(*this);
#define BEGIN_TYPE switch(ins.typeParameter) {
#define END_TYPE default: INTERNAL_ERROR(L"unexpected type argument."); }
WfRuntimeExecutionAction
WfRuntimeThreadContext
::
ExecuteInternal
(
WfInstruction
&
ins
,
WfRuntimeStackFrame
&
stackFrame
,
IWfDebuggerCallback
*
callback
) {
switch
(
ins
.
code
) {
case
WfInsCode
::
LoadValue
:
return
WfRuntimeExecutionAction
::
ExecuteInstruction
;
case
WfInsCode
::
LoadFunction
: {
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
LoadException
: {
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
LoadLocalVar
: {
Value
operand
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
LoadCapturedVar
: {
Value
operand
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
LoadGlobalVar
: {
Value
operand
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
LoadMethodInfo
: {
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
LoadMethodClosure
: {
Value
operand
;
auto
closure
=
ins
.
methodParameter
->
CreateFunctionProxy
(
operand
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
LoadClosureContext
: {
auto
capturedVariables
=
GetCurrentStackFrame
().
capturedVariables
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
StoreLocalVar
: {
Value
operand
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
StoreCapturedVar
: {
Value
operand
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
StoreGlobalVar
: {
Value
operand
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
Duplicate
: {
vint
index
=
stack
.
Count
() -
1
-
ins
.
countParameter
;
Value
operand
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
Pop
: {
Value
operand
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
Return
: {
Value
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
++) {
list
-
>
Add
(
operand
); }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
CreateObservableList
: {
auto
list
=
IValueObservableList
::
Create
();
Value
operand
;
for
(
vint
i
=
0
;
i
<
ins
.
countParameter
;
i
++) {
list
-
>
Add
(
operand
); }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
CreateMap
: {
auto
map
=
IValueDictionary
::
Create
();
Value
key
,
value
;
for
(
vint
i
=
0
;
i
<
ins
.
countParameter
;
i
+=
2
) {
map
-
>
Set
(
key
,
value
); }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
CreateClosureContext
: {
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
++) {
capturedVariables
-
>
variables
[
ins
.
countParameter
-
1
-
i
]
=
operand
; } }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
CreateClosure
: {
Value
context
,
function
;
auto
capturedVariables
=
context
.
GetSharedPtr
().
Cast
<
WfRuntimeVariableContext
>();
auto
functionIndex
=
UnboxValue
<
vint
>(
function
);
auto
lambda
=
MakePtr
<
WfRuntimeLambda
>(
globalContext
,
capturedVariables
,
functionIndex
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
CreateInterface
: {
auto
proxy
=
MakePtr
<
WfRuntimeInterfaceInstance
>();
Value
key
,
value
,
operand
;
for
(
vint
i
=
0
;
i
<
ins
.
countParameter
;
i
+=
2
) {
auto
name
=
UnboxValue
<
IMethodInfo
*>(
key
);
auto
func
=
UnboxValue
<
vint
>(
value
);
proxy
-
>
functions
.
Add
(
name
,
func
); }
auto
capturedVariables
=
operand
.
GetSharedPtr
().
Cast
<
WfRuntimeVariableContext
>();
proxy
-
>
capturedVariables
=
capturedVariables
;
proxy
-
>
globalContext
=
globalContext
;
Array
<
Value
>
arguments
(
1
);
arguments
[
0
]
=
Value
::
From
(
proxy
);
auto
obj
=
ins
.
methodParameter
->
Invoke
(
Value
(),
arguments
);
capturedVariables
-
>
variables
[
capturedVariables
-
>
variables
.
Count
() -
1
]
=
Value
::
From
(
obj
.
GetRawPtr
());
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
CreateRange
:
case
WfInsCode
::
CreateStruct
: {
if
(
ins
.
typeDescriptorParameter
->
GetTypeDescriptorFlags
() !=
TypeDescriptorFlags
::
Struct
) { }
Value
result
=
ins
.
typeDescriptorParameter
->
GetValueType
()->
CreateDefault
();
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
DeleteRawPtr
: {
Value
operand
;
operand
.
DeleteRawPtr
();
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
ConvertToType
: {
Value
result
,
converted
;
if
(
OPERATOR_OpConvertToType
(
result
,
converted
,
ins
)) { }
else
{
WString
from
;
if
(
result
.
IsNull
()) {
from
=
L"<null>"
; }
else
{
if
(
auto
st
=
result
.
GetTypeDescriptor
()->
GetSerializableType
()) {
WString
text
;
st
->
Serialize
(
result
,
text
);
from
=
L"<"
+
text
+
L"> of "
+
result
.
GetTypeDescriptor
()->
GetTypeName
(); }
else
{
from
=
result
.
GetTypeDescriptor
()->
GetTypeName
(); } }
WString
to
=
ins
.
typeDescriptorParameter
->
GetTypeName
();
RaiseException
(
L"Failed to convert from \""
+
from
+
L"\" to \""
+
to
+
L"\"."
,
false
); }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
TryConvertToType
: {
Value
result
,
converted
;
if
(
OPERATOR_OpConvertToType
(
result
,
converted
,
ins
)) { }
else
{ }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
TestType
: {
Value
operand
;
if
(
operand
.
GetTypeDescriptor
() &&
operand
.
GetValueType
() ==
ins
.
flagParameter
&&
operand
.
GetTypeDescriptor
()->
CanConvertTo
(
ins
.
typeDescriptorParameter
)) { }
else
{ }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
GetType
: {
Value
operand
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
Jump
: {
stackFrame
.
nextInstructionIndex
=
ins
.
indexParameter
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
JumpIf
: {
Value
operand
;
if
(
UnboxValue
<
bool
>(
operand
)) {
stackFrame
.
nextInstructionIndex
=
ins
.
indexParameter
; }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
Invoke
: {
return
WfRuntimeExecutionAction
::
EnterStackFrame
; }
case
WfInsCode
::
InvokeWithContext
: {
return
WfRuntimeExecutionAction
::
EnterStackFrame
; }
case
WfInsCode
::
GetProperty
: {
Value
operand
;
Value
result
=
ins
.
propertyParameter
->
GetValue
(
operand
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
SetProperty
: {
Value
operand
,
value
;
ins
.
propertyParameter
->
SetValue
(
operand
,
value
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
UpdateProperty
: {
Value
operand
,
value
;
ins
.
propertyParameter
->
SetValue
(
operand
,
value
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
InvokeProxy
: {
Value
thisValue
;
auto
proxy
=
UnboxValue
<
Ptr
<
IValueFunctionProxy
>>(
thisValue
);
if
(!
proxy
) {
return
WfRuntimeExecutionAction
::
Nop
; }
if
(
auto
lambda
=
proxy
.
Cast
<
WfRuntimeLambda
>()) {
if
(
lambda
-
>
globalContext
=
=
globalContext
) {
return
WfRuntimeExecutionAction
::
EnterStackFrame
; } }
List
<
Value
>
arguments
;
for
(
vint
i
=
0
;
i
<
ins
.
countParameter
;
i
++) {
Value
argument
;
arguments
.
Insert
(
0
,
argument
); }
Ptr
<
IValueList
>
list
=
new
ValueListWrapper
<
List
<
Value
>*>(&
arguments
);
Value
result
=
proxy
-
>
Invoke
(
list
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
InvokeMethod
: {
Value
thisValue
;
if
(
auto
staticMethod
=
dynamic_cast
<
WfStaticMethod
*>(
ins
.
methodParameter
)) {
if
(
staticMethod
->
GetGlobalContext
() ==
globalContext
.
Obj
()) {
return
WfRuntimeExecutionAction
::
EnterStackFrame
; } }
if
(
auto
classMethod
=
dynamic_cast
<
WfClassMethod
*>(
ins
.
methodParameter
)) {
if
(
classMethod
->
GetGlobalContext
() ==
globalContext
.
Obj
()) {
auto
capturedVariable
=
MakePtr
<
WfRuntimeVariableContext
>();
capturedVariable
-
>
variables
.
Resize
(
1
);
capturedVariable
-
>
variables
[
0
]
=
Value
::
From
(
thisValue
.
GetRawPtr
());
return
WfRuntimeExecutionAction
::
EnterStackFrame
; } }
Array
<
Value
>
arguments
(
ins
.
countParameter
);
for
(
vint
i
=
0
;
i
<
ins
.
countParameter
;
i
++) {
Value
argument
;
arguments
[
ins
.
countParameter
-
i
-
1
]
=
argument
; }
Value
result
=
ins
.
methodParameter
->
Invoke
(
thisValue
,
arguments
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
InvokeEvent
: {
Value
thisValue
;
auto
arguments
=
IValueList
::
Create
();
for
(
vint
i
=
0
;
i
<
ins
.
countParameter
;
i
++) {
Value
argument
;
arguments
-
>
Insert
(
0
,
argument
); }
ins
.
eventParameter
->
Invoke
(
thisValue
,
arguments
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
InvokeBaseCtor
: {
Value
thisValue
;
if
(
auto
ctor
=
dynamic_cast
<
WfClassConstructor
*>(
ins
.
methodParameter
)) {
if
(
ctor
->
GetGlobalContext
() ==
globalContext
.
Obj
()) {
auto
capturedVariable
=
MakePtr
<
WfRuntimeVariableContext
>();
capturedVariable
-
>
variables
.
Resize
(
1
);
capturedVariable
-
>
variables
[
0
]
=
Value
::
From
(
thisValue
.
GetRawPtr
());
return
WfRuntimeExecutionAction
::
EnterStackFrame
; } }
Array
<
Value
>
arguments
(
ins
.
countParameter
);
for
(
vint
i
=
0
;
i
<
ins
.
countParameter
;
i
++) {
Value
argument
;
arguments
[
ins
.
countParameter
-
i
-
1
]
=
argument
; }
if
(
auto
ctor
=
dynamic_cast
<
WfClassConstructor
*>(
ins
.
methodParameter
)) {
ctor
->
InvokeBaseCtor
(
thisValue
,
arguments
); }
else
{
auto
instance
=
dynamic_cast
<
WfClassInstance
*>(
thisValue
.
GetRawPtr
());
if
(!
instance
) { }
Value
baseValue
=
ins
.
methodParameter
->
Invoke
(
Value
(),
arguments
);
instance
->
InstallBaseObject
(
ins
.
methodParameter
->
GetOwnerTypeDescriptor
(),
baseValue
); }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
AttachEvent
: {
Value
thisValue
,
function
;
auto
proxy
=
UnboxValue
<
Ptr
<
IValueFunctionProxy
>>(
function
);
auto
handler
=
ins
.
eventParameter
->
Attach
(
thisValue
,
proxy
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
DetachEvent
: {
Value
thisValue
,
operand
;
auto
handler
=
UnboxValue
<
Ptr
<
IEventHandler
>>(
operand
);
auto
result
=
ins
.
eventParameter
->
Detach
(
thisValue
,
handler
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
InstallTry
:
return
WfRuntimeExecutionAction
::
ExecuteInstruction
;
case
WfInsCode
::
UninstallTry
: {
if
(
trapFrames
.
Count
() ==
0
) { }
auto
frame
=
GetCurrentTrapFrame
();
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
RaiseException
: {
Value
operand
;
if
(
operand
.
GetValueType
() ==
Value
::
BoxedValue
) {
WString
text
;
operand
.
GetTypeDescriptor
()->
GetSerializableType
()->
Serialize
(
operand
,
text
);
RaiseException
(
text
,
false
); }
else
if
(
auto
info
=
operand
.
GetSharedPtr
().
Cast
<
WfRuntimeExceptionInfo
>()) {
RaiseException
(
info
); }
else
if
(
auto
ex
=
operand
.
GetSharedPtr
().
Cast
<
IValueException
>()) { }
else
{ }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
TestElementInSet
: {
Value
element
,
set
;
auto
enumerable
=
UnboxValue
<
Ptr
<
IValueEnumerable
>>(
set
);
auto
enumerator
=
enumerable
-
>
CreateEnumerator
();
while
(
enumerator
-
>
Next
()) {
if
(
enumerator
-
>
GetCurrent
()
=
=
element
) {
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; } }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
CompareLiteral
:
case
WfInsCode
::
CompareReference
: {
Value
first
,
second
;
bool
result
=
first
.
GetValueType
() !=
Value
::
BoxedValue
&&
second
.
GetValueType
() !=
Value
::
BoxedValue
&&
first
.
GetRawPtr
() ==
second
.
GetRawPtr
();
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
CompareValue
: {
Value
first
,
second
;
bool
result
=
first
=
=
second
;
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
OpNot
:
case
WfInsCode
::
OpPositive
:
case
WfInsCode
::
OpNegative
:
case
WfInsCode
::
OpConcat
: {
Value
first
,
second
;
WString
firstText
,
secondText
;
first
.
GetTypeDescriptor
()->
GetSerializableType
()->
Serialize
(
first
,
firstText
);
first
.
GetTypeDescriptor
()->
GetSerializableType
()->
Serialize
(
second
,
secondText
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
case
WfInsCode
::
OpExp
:
case
WfInsCode
::
OpAdd
:
case
WfInsCode
::
OpSub
:
case
WfInsCode
::
OpMul
:
case
WfInsCode
::
OpDiv
:
case
WfInsCode
::
OpMod
:
case
WfInsCode
::
OpShl
:
case
WfInsCode
::
OpShr
:
case
WfInsCode
::
OpXor
:
case
WfInsCode
::
OpAnd
:
case
WfInsCode
::
OpOr
:
case
WfInsCode
::
OpLT
: {
Value
operand
;
vint
value
=
UnboxValue
<
vint
>(
operand
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
break
;
case
WfInsCode
::
OpGT
: {
Value
operand
;
vint
value
=
UnboxValue
<
vint
>(
operand
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
break
;
case
WfInsCode
::
OpLE
: {
Value
operand
;
vint
value
=
UnboxValue
<
vint
>(
operand
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
break
;
case
WfInsCode
::
OpGE
: {
Value
operand
;
vint
value
=
UnboxValue
<
vint
>(
operand
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
break
;
case
WfInsCode
::
OpEQ
: {
Value
operand
;
vint
value
=
UnboxValue
<
vint
>(
operand
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
break
;
case
WfInsCode
::
OpNE
: {
Value
operand
;
vint
value
=
UnboxValue
<
vint
>(
operand
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
break
;
default
:
return
WfRuntimeExecutionAction
::
Nop
; } }
WfRuntimeExecutionAction
WfRuntimeThreadContext
::
Execute
(
IWfDebuggerCallback
*
callback
) {
try
{
switch
(
status
) {
case
WfRuntimeExecutionStatus
::
Ready
:
case
WfRuntimeExecutionStatus
::
Executing
: {
if
(
stackFrames
.
Count
() ==
0
) { }
auto
&
stackFrame
=
GetCurrentStackFrame
();
if
(
stackFrame
.
nextInstructionIndex
<
0
||
stackFrame
.
nextInstructionIndex
>=
globalContext
-
>
assembly
-
>
instructions
.
Count
()) { }
auto
insIndex
=
stackFrame
.
nextInstructionIndex
;
stackFrame
.
nextInstructionIndex
++;
auto
&
ins
=
globalContext
-
>
assembly
-
>
instructions
[
insIndex
];
return
ExecuteInternal
(
ins
,
stackFrame
,
callback
); }
break
;
case
WfRuntimeExecutionStatus
::
RaisedException
:
if
(
trapFrames
.
Count
() >
0
) {
auto
trapFrame
=
GetCurrentTrapFrame
();
if
(
trapFrame
.
stackFrameIndex
==
stackFrames
.
Count
() -
1
) {
GetCurrentStackFrame
().
nextInstructionIndex
=
trapFrame
.
instructionIndex
;
status
=
WfRuntimeExecutionStatus
::
Executing
;
return
WfRuntimeExecutionAction
::
UnwrapStack
; }
else
if
(
stackFrames
.
Count
() >
0
) {
return
WfRuntimeExecutionAction
::
UnwrapStack
; } }
break
;
default
:; }
return
WfRuntimeExecutionAction
::
Nop
; }
catch
(
const
WfRuntimeException
&
ex
) {
if
(
ex
.
GetInfo
()) {
RaiseException
(
ex
.
GetInfo
()); }
else
{
RaiseException
(
ex
.
Message
(),
ex
.
IsFatal
()); }
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; }
catch
(
const
Exception
&
ex
) {
RaiseException
(
ex
.
Message
(),
false
);
return
WfRuntimeExecutionAction
::
ExecuteInstruction
; } }
#undef INTERNAL_ERROR
#undef CONTEXT_ACTION
#undef CALL_DEBUGGER
#undef TYPE_OF_Bool
#undef TYPE_OF_I1
#undef TYPE_OF_I2
#undef TYPE_OF_I4
#undef TYPE_OF_I8
#undef TYPE_OF_U1
#undef TYPE_OF_U2
#undef TYPE_OF_U4
#undef TYPE_OF_U8
#undef TYPE_OF_F4
#undef TYPE_OF_F8
#undef TYPE_OF_String
#undef EXECUTE
#undef BEGIN_TYPE
#undef END_TYPE
} } }
#endif