2022-03-03 08:14:05 -06:00
using System ;
using System.Collections ;
2022-06-24 20:41:00 -05:00
using System.Collections.Generic ;
2022-03-03 08:14:05 -06:00
using System.Linq ;
using System.Xml ;
using Microsoft.Iris.Debug ;
using Microsoft.Iris.Library ;
using Microsoft.Iris.Markup.UIX ;
using Microsoft.Iris.Session ;
namespace Microsoft.Iris.Markup
{
// Token: 0x0200018B RID: 395
internal class Interpreter
{
// Token: 0x06000F21 RID: 3873 RVA: 0x00029E78 File Offset: 0x00028E78
public static object Run ( InterpreterContext context )
{
object result = null ;
ByteCodeReader byteCodeReader = null ;
long num = - 1L ;
2023-05-22 18:04:22 -05:00
bool isErrored = true ;
2022-03-03 08:14:05 -06:00
ErrorManager . EnterContext ( context );
try
{
byteCodeReader = context . LoadResult . ObjectSection ;
2023-05-22 18:04:22 -05:00
num = ( long )( ulong ) byteCodeReader . CurrentOffset ;
2022-03-03 08:14:05 -06:00
byteCodeReader . CurrentOffset = context . InitialBytecodeOffset ;
2023-05-23 20:28:19 -05:00
if ( Application . DebugSettings . UseDecompiler )
2022-03-03 08:14:05 -06:00
result = RunDecompile ( context , byteCodeReader );
else
result = Run ( context , byteCodeReader );
2023-05-22 18:04:22 -05:00
isErrored = false ;
2022-03-03 08:14:05 -06:00
}
finally
{
2023-05-22 18:04:22 -05:00
if ( isErrored )
2022-03-03 08:14:05 -06:00
ExceptionContext = context . ToString ();
ErrorManager . ExitContext ();
2023-05-22 18:04:22 -05:00
2022-03-03 08:14:05 -06:00
if ( byteCodeReader != null && num != - 1L )
byteCodeReader . CurrentOffset = ( uint ) num ;
}
return result ;
}
// Token: 0x06000F22 RID: 3874 RVA: 0x00029EF8 File Offset: 0x00028EF8
private static object Run ( InterpreterContext context , ByteCodeReader reader )
{
MarkupLoadResult loadResult = context . LoadResult ;
IMarkupTypeBase instance = context . Instance ;
MarkupImportTables importTables = loadResult . ImportTables ;
MarkupConstantsTable constantsTable = loadResult . ConstantsTable ;
SymbolReference [] symbolReferenceTable = context . MarkupType . SymbolReferenceTable ;
2023-05-22 18:04:22 -05:00
ErrorWatermark watermark = ErrorManager . Watermark ;
2022-03-03 08:14:05 -06:00
Trace . IsCategoryEnabled ( TraceCategory . Markup );
2023-05-22 18:04:22 -05:00
2022-03-03 08:14:05 -06:00
Stack stack = _stack ;
int count = stack . Count ;
if ( instance != null )
{
stack . Push ( instance );
}
2023-05-22 18:04:22 -05:00
bool errorsDetected = false ;
2022-03-03 08:14:05 -06:00
object result = null ;
bool wasInDebugState = false ;
2023-05-22 21:44:05 -05:00
bool debugging = Application . Debugger != null ;
2023-05-22 18:04:22 -05:00
while (! errorsDetected )
2022-03-03 08:14:05 -06:00
{
OpCode opCode = ( OpCode ) reader . ReadByte ();
2023-05-22 18:04:22 -05:00
Debug . Data . InterpreterEntry entry = new ( opCode );
2023-05-23 21:35:58 -05:00
// Fetch line and column numbers from the table
if ( debugging && context . LoadResult . LineNumberTable . TryLookup ( reader . CurrentOffset , out int line , out int column ))
{
// Check if a breakpoint has been set at this location
bool shouldBreak = Application . DebugSettings . Breakpoints
. Any ( b => b . Line == line && b . Column == column && b . Uri . Equals ( loadResult . Uri , StringComparison . OrdinalIgnoreCase ));
if ( shouldBreak )
System . Diagnostics . Debugger . Break ();
}
2022-03-03 08:14:05 -06:00
switch ( opCode )
{
case OpCode . ConstructObject :
{
int num = reader . ReadUInt16 ();
TypeSchema typeSchema = importTables . TypeImports [ num ];
object obj = typeSchema . ConstructDefault ();
ReportErrorOnNull ( obj , "Construction" , typeSchema . Name );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
RegisterDisposable ( obj , typeSchema , instance );
stack . Push ( obj );
}
break ;
}
case OpCode . ConstructObjectIndirect :
{
int num2 = reader . ReadUInt16 ();
TypeSchema typeSchema2 = importTables . TypeImports [ num2 ];
TypeSchema typeSchema3 = ( TypeSchema ) stack . Pop ();
if (! typeSchema2 . IsAssignableFrom ( typeSchema3 ))
{
ErrorManager . ReportError ( "Script runtime failure: Dynamic construction type override failed. Attempting to construct '{0}' in place of '{1}'" , ( typeSchema3 != null ) ? typeSchema3 . Name : "null" , typeSchema2 . Name );
2023-05-22 18:04:22 -05:00
if ( ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
break ;
}
}
IDynamicConstructionSchema dynamicConstructionSchema = typeSchema3 as IDynamicConstructionSchema ;
object obj2 ;
if ( dynamicConstructionSchema != null )
{
obj2 = dynamicConstructionSchema . ConstructDefault ( typeSchema2 );
}
else
{
obj2 = typeSchema3 . ConstructDefault ();
}
ReportErrorOnNull ( obj2 , "Construction" , typeSchema3 . Name );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
RegisterDisposable ( obj2 , typeSchema3 , instance );
stack . Push ( obj2 );
}
break ;
}
case OpCode . ConstructObjectParam :
{
int num3 = reader . ReadUInt16 ();
TypeSchema typeSchema4 = importTables . TypeImports [ num3 ];
int num4 = reader . ReadUInt16 ();
ConstructorSchema constructorSchema = importTables . ConstructorImports [ num4 ];
int i = constructorSchema . ParameterTypes . Length ;
object [] array = ParameterListAllocator . Alloc ( i );
for ( i --; i >= 0 ; i --)
{
array [ i ] = stack . Pop ();
}
object obj3 = constructorSchema . Construct ( array );
ReportErrorOnNull ( obj3 , "Construction" , typeSchema4 . Name );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
RegisterDisposable ( obj3 , typeSchema4 , instance );
stack . Push ( obj3 );
ParameterListAllocator . Free ( array );
}
break ;
}
case OpCode . ConstructFromString :
{
int num5 = reader . ReadUInt16 ();
TypeSchema typeSchema5 = importTables . TypeImports [ num5 ];
int index = reader . ReadUInt16 ();
string from = ( string ) constantsTable . Get ( index );
object obj4 ;
typeSchema5 . TypeConverter ( from , StringSchema . Type , out obj4 );
ReportErrorOnNull ( obj4 , "Construction" , typeSchema5 . Name );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
RegisterDisposable ( obj4 , typeSchema5 , instance );
stack . Push ( obj4 );
}
break ;
}
case OpCode . ConstructFromBinary :
{
int num6 = reader . ReadUInt16 ();
TypeSchema typeSchema6 = importTables . TypeImports [ num6 ];
object obj5 = typeSchema6 . DecodeBinary ( reader );
ReportErrorOnNull ( obj5 , "Construction" , typeSchema6 . Name );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
RegisterDisposable ( obj5 , typeSchema6 , instance );
stack . Push ( obj5 );
}
break ;
}
case OpCode . InitializeInstance :
{
int num7 = reader . ReadUInt16 ();
TypeSchema typeSchema7 = importTables . TypeImports [ num7 ];
object obj6 = stack . Pop ();
typeSchema7 . InitializeInstance ( ref obj6 );
ReportErrorOnNull ( obj6 , "Initialize" , typeSchema7 . Name );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
stack . Push ( obj6 );
}
break ;
}
case OpCode . InitializeInstanceIndirect :
{
TypeSchema typeSchema8 = ( TypeSchema ) stack . Pop ();
object obj7 = stack . Pop ();
typeSchema8 . InitializeInstance ( ref obj7 );
ReportErrorOnNull ( obj7 , "Initialize" , typeSchema8 . Name );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
stack . Push ( obj7 );
}
break ;
}
case OpCode . LookupSymbol :
{
int num8 = reader . ReadUInt16 ();
SymbolReference symbolRef = symbolReferenceTable [ num8 ];
object obj8 = context . ReadSymbol ( symbolRef );
stack . Push ( obj8 );
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . WriteSymbol :
case OpCode . WriteSymbolPeek :
{
object value = ( opCode == OpCode . WriteSymbolPeek ) ? stack . Peek () : stack . Pop ();
int num9 = reader . ReadUInt16 ();
SymbolReference symbolRef2 = symbolReferenceTable [ num9 ];
context . WriteSymbol ( symbolRef2 , value );
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . ClearSymbol :
{
int num10 = reader . ReadUInt16 ();
SymbolReference symbolRef3 = symbolReferenceTable [ num10 ];
context . ClearSymbol ( symbolRef3 );
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . PropertyInitialize :
case OpCode . PropertyInitializeIndirect :
{
bool flag2 = opCode == OpCode . PropertyInitializeIndirect ;
TypeSchema typeSchema9 = null ;
if ( flag2 )
{
typeSchema9 = ( TypeSchema ) stack . Pop ();
}
int num11 = reader . ReadUInt16 ();
PropertySchema propertySchema = importTables . PropertyImports [ num11 ];
object obj9 = stack . Pop ();
object obj10 = stack . Pop ();
ReportErrorOnNull ( obj10 , "Property Set" , propertySchema . Name );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
if ( flag2 )
{
PropertySchema propertySchema2 = typeSchema9 . FindPropertyDeep ( propertySchema . Name );
if ( propertySchema2 != propertySchema )
{
TypeSchema propertyType = propertySchema2 . PropertyType ;
if (! propertyType . IsAssignableFrom ( obj9 ))
{
string param = TypeSchema . NameFromInstance ( obj9 );
ErrorManager . ReportError ( "Script runtime failure: Incompatible value for property '{0}' supplied (expecting values of type '{1}' but got '{2}') while constructing runtime replacement type '{3}' (original type '{4}')" , propertySchema . Name , propertyType . Name , param , typeSchema9 . Name , propertySchema . Owner . Name );
result = ScriptError ;
}
2023-05-22 18:04:22 -05:00
if ( ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
break ;
}
}
}
propertySchema . SetValue ( ref obj10 , obj9 );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
stack . Push ( obj10 );
}
}
break ;
}
case OpCode . PropertyListAdd :
{
int propertyIndex = reader . ReadUInt16 ();
object value2 = stack . Pop ();
object collection = GetCollection ( stack . Peek (), importTables , propertyIndex );
ReportErrorOnNull ( collection , "List Add" );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
(( IList ) collection ). Add ( value2 );
2023-05-22 18:04:22 -05:00
if ( ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
}
}
break ;
}
case OpCode . PropertyDictionaryAdd :
{
int propertyIndex2 = reader . ReadUInt16 ();
int index2 = reader . ReadUInt16 ();
string key = ( string ) constantsTable . Get ( index2 );
object value3 = stack . Pop ();
object collection2 = GetCollection ( stack . Peek (), importTables , propertyIndex2 );
ReportErrorOnNull ( collection2 , "Dictionary Add" );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
(( IDictionary ) collection2 )[ key ] = value3 ;
2023-05-22 18:04:22 -05:00
if ( ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
}
}
break ;
}
case OpCode . PropertyAssign :
case OpCode . PropertyAssignStatic :
{
int num12 = reader . ReadUInt16 ();
PropertySchema propertySchema3 = importTables . PropertyImports [ num12 ];
object instance2 = null ;
if ( opCode == OpCode . PropertyAssign )
{
instance2 = stack . Pop ();
ReportErrorOnNullOrDisposed ( instance2 , "Property Set" , propertySchema3 . Name , propertySchema3 . Owner );
2023-05-22 18:04:22 -05:00
if ( ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
break ;
}
}
object value4 = stack . Peek ();
propertySchema3 . SetValue ( ref instance2 , value4 );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ) && Trace . IsCategoryEnabled ( TraceCategory . Markup ))
2022-03-03 08:14:05 -06:00
{
}
break ;
}
case OpCode . PropertyGet :
case OpCode . PropertyGetPeek :
case OpCode . PropertyGetStatic :
{
int num13 = reader . ReadUInt16 ();
PropertySchema propertySchema4 = importTables . PropertyImports [ num13 ];
object instance3 = null ;
if ( opCode != OpCode . PropertyGetStatic )
{
instance3 = (( opCode == OpCode . PropertyGet ) ? stack . Pop () : stack . Peek ());
ReportErrorOnNullOrDisposed ( instance3 , "Property Get" , propertySchema4 . Name , propertySchema4 . Owner );
2023-05-22 18:04:22 -05:00
if ( ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
break ;
}
}
object value5 = propertySchema4 . GetValue ( instance3 );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
stack . Push ( value5 );
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
break ;
}
case OpCode . MethodInvoke :
case OpCode . MethodInvokePeek :
case OpCode . MethodInvokeStatic :
case OpCode . MethodInvokePushLastParam :
case OpCode . MethodInvokeStaticPushLastParam :
{
int num14 = reader . ReadUInt16 ();
MethodSchema methodSchema = importTables . MethodImports [ num14 ];
int j = methodSchema . ParameterTypes . Length ;
object [] array2 = ParameterListAllocator . Alloc ( j );
for ( j --; j >= 0 ; j --)
{
array2 [ j ] = stack . Pop ();
}
object instance4 = null ;
bool flag3 = opCode != OpCode . MethodInvokeStatic && opCode != OpCode . MethodInvokeStaticPushLastParam ;
bool flag4 = opCode == OpCode . MethodInvokePeek ;
bool flag5 = opCode == OpCode . MethodInvokePushLastParam || opCode == OpCode . MethodInvokeStaticPushLastParam ;
if ( flag3 )
{
if (! flag4 )
{
instance4 = stack . Pop ();
}
else
{
instance4 = stack . Peek ();
}
ReportErrorOnNullOrDisposed ( instance4 , "Method Invoke" , methodSchema . Name , methodSchema . Owner );
2023-05-22 18:04:22 -05:00
if ( ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
break ;
}
}
2023-04-28 18:46:37 -05:00
2022-03-03 08:14:05 -06:00
object obj11 = methodSchema . Invoke ( instance4 , array2 );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
if (! flag5 )
{
if ( methodSchema . ReturnType != VoidSchema . Type )
{
stack . Push ( obj11 );
}
}
else
{
stack . Push ( array2 [ array2 . Length - 1 ]);
}
ParameterListAllocator . Free ( array2 );
}
break ;
}
case OpCode . VerifyTypeCast :
{
int num15 = reader . ReadUInt16 ();
TypeSchema typeSchema10 = importTables . TypeImports [ num15 ];
object obj12 = stack . Peek ();
if ( obj12 != null )
{
if (! typeSchema10 . IsAssignableFrom ( obj12 ))
{
string param2 = TypeSchema . NameFromInstance ( obj12 );
string name = typeSchema10 . Name ;
ErrorManager . ReportError ( "Script runtime failure: Invalid type cast while attempting to cast an instance with a runtime type of '{0}' to '{1}'" , param2 , name );
result = ScriptError ;
}
2023-05-22 18:04:22 -05:00
if ( ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
}
}
else if (! typeSchema10 . IsNullAssignable )
{
ReportErrorOnNull ( obj12 , "Verify Type Cast" , typeSchema10 . Name );
2023-05-22 18:04:22 -05:00
if ( ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
}
}
break ;
}
case OpCode . ConvertType :
{
int num16 = reader . ReadUInt16 ();
TypeSchema typeSchema11 = importTables . TypeImports [ num16 ];
int num17 = reader . ReadUInt16 ();
TypeSchema fromType = importTables . TypeImports [ num17 ];
object obj13 = stack . Pop ();
ReportErrorOnNull ( obj13 , "Type Conversion" , typeSchema11 . Name );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
object obj14 ;
Result result2 = typeSchema11 . TypeConverter ( obj13 , fromType , out obj14 );
if ( result2 . Failed )
{
ErrorManager . ReportError ( "Script runtime failure: Type conversion failed while attempting to convert to '{0}' ({1})" , typeSchema11 . Name , result2 . Error );
}
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
stack . Push ( obj14 );
}
}
break ;
}
case OpCode . Operation :
{
int num18 = reader . ReadUInt16 ();
TypeSchema typeSchema12 = importTables . TypeImports [ num18 ];
OperationType op = ( OperationType ) reader . ReadByte ();
object right = null ;
if (! TypeSchema . IsUnaryOperation ( op ))
{
right = stack . Pop ();
}
object left = stack . Pop ();
object obj15 = typeSchema12 . PerformOperationDeep ( left , right , op );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
stack . Push ( obj15 );
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
break ;
}
case OpCode . IsCheck :
{
int num19 = reader . ReadUInt16 ();
TypeSchema typeSchema13 = importTables . TypeImports [ num19 ];
object obj16 = stack . Pop ();
bool value6 = false ;
if ( obj16 != null )
{
value6 = typeSchema13 . IsAssignableFrom ( obj16 );
}
stack . Push ( BooleanBoxes . Box ( value6 ));
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . As :
{
int num20 = reader . ReadUInt16 ();
TypeSchema typeSchema14 = importTables . TypeImports [ num20 ];
object obj17 = stack . Peek ();
if ( obj17 != null && ! typeSchema14 . IsAssignableFrom ( obj17 ))
{
stack . Pop ();
stack . Push ( null );
}
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . TypeOf :
{
int num21 = reader . ReadUInt16 ();
TypeSchema obj18 = importTables . TypeImports [ num21 ];
stack . Push ( obj18 );
break ;
}
case OpCode . PushNull :
stack . Push ( null );
break ;
case OpCode . PushConstant :
{
int index3 = reader . ReadUInt16 ();
object obj19 = constantsTable . Get ( index3 );
stack . Push ( obj19 );
break ;
}
case OpCode . PushThis :
stack . Push ( instance );
break ;
case OpCode . DiscardValue :
stack . Pop ();
break ;
case OpCode . ReturnValue :
{
object obj20 = stack . Pop ();
result = obj20 ;
2023-05-22 18:04:22 -05:00
errorsDetected = true ;
2022-03-03 08:14:05 -06:00
break ;
}
case OpCode . ReturnVoid :
result = VoidReturnValue ;
2023-05-22 18:04:22 -05:00
errorsDetected = true ;
2022-03-03 08:14:05 -06:00
break ;
case OpCode . JumpIfFalse :
case OpCode . JumpIfFalsePeek :
case OpCode . JumpIfTruePeek :
{
uint currentOffset = reader . ReadUInt32 ();
object obj21 = ( opCode == OpCode . JumpIfFalse ) ? stack . Pop () : stack . Peek ();
bool flag6 = ( bool ) obj21 ;
bool flag7 = opCode == OpCode . JumpIfTruePeek ;
Trace . IsCategoryEnabled ( TraceCategory . Markup );
if ( flag7 == flag6 )
{
reader . CurrentOffset = currentOffset ;
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
break ;
}
case OpCode . JumpIfDictionaryContains :
{
ushort propertyIndex3 = reader . ReadUInt16 ();
ushort index4 = reader . ReadUInt16 ();
uint currentOffset2 = reader . ReadUInt32 ();
string key2 = ( string ) constantsTable . Get ( index4 );
object collection3 = GetCollection ( stack . Peek (), importTables , propertyIndex3 );
ReportErrorOnNull ( collection3 , "Dictionary Contains" );
2023-05-22 18:04:22 -05:00
if (! ErrorsDetected ( watermark , ref result , ref errorsDetected ))
2022-03-03 08:14:05 -06:00
{
bool flag8 = (( IDictionary ) collection3 ). Contains ( key2 );
Trace . IsCategoryEnabled ( TraceCategory . Markup );
if ( flag8 )
{
reader . CurrentOffset = currentOffset2 ;
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
}
break ;
}
case OpCode . JumpIfNullPeek :
{
uint currentOffset3 = reader . ReadUInt32 ();
object obj22 = stack . Peek ();
Trace . IsCategoryEnabled ( TraceCategory . Markup );
if ( obj22 == null )
{
reader . CurrentOffset = currentOffset3 ;
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
break ;
}
case OpCode . Jump :
{
uint currentOffset4 = reader . ReadUInt32 ();
reader . CurrentOffset = currentOffset4 ;
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . ConstructListenerStorage :
{
int listenerCount = reader . ReadUInt16 ();
if ( instance . Listeners == null )
{
MarkupListeners markupListeners = new MarkupListeners ( listenerCount );
markupListeners . DeclareOwner ( instance );
instance . Listeners = markupListeners ;
}
else
{
instance . Listeners . AddEntries ( listenerCount );
}
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . Listen :
case OpCode . DestructiveListen :
{
int index5 = reader . ReadUInt16 ();
ListenerType listenerType = ( ListenerType ) reader . ReadByte ();
int num22 = reader . ReadUInt16 ();
uint scriptOffset = reader . ReadUInt32 ();
uint refreshOffset = uint . MaxValue ;
if ( opCode == OpCode . DestructiveListen )
{
refreshOffset = reader . ReadUInt32 ();
}
string watch = null ;
switch ( listenerType )
{
case ListenerType . Property :
watch = importTables . PropertyImports [ num22 ]. Name ;
break ;
case ListenerType . Event :
watch = importTables . EventImports [ num22 ]. Name ;
break ;
case ListenerType . Symbol :
watch = symbolReferenceTable [ num22 ]. Symbol ;
break ;
}
object obj23 = stack . Peek ();
if ( obj23 != null )
{
INotifyObject notifier = ( INotifyObject ) obj23 ;
Trace . IsCategoryEnabled ( TraceCategory . Markup );
MarkupListeners listeners = instance . Listeners ;
listeners . RefreshListener ( index5 , notifier , watch , instance , scriptOffset , refreshOffset );
}
else
{
Trace . IsCategoryEnabled ( TraceCategory . Markup );
}
break ;
}
case OpCode . EnterDebugState :
{
int breakpointIndex = reader . ReadInt32 ();
if ( MarkupSystem . IsDebuggingEnabled ( 2 ))
{
wasInDebugState = MarkupDebugHelper . EnterDebugState ( wasInDebugState , loadResult , breakpointIndex , instance . Storage );
}
break ;
}
}
2023-05-22 18:04:22 -05:00
2023-05-22 21:44:05 -05:00
Application . Debugger ?. LogInterpreterOpCode ( opCode , entry );
2022-03-03 08:14:05 -06:00
}
while ( stack . Count > count )
{
stack . Pop ();
}
return result ;
}
// Token: 0x06000F23 RID: 3875 RVA: 0x0002ADA7 File Offset: 0x00029DA7
private static bool ErrorsDetected ( ErrorWatermark watermark , ref object result , ref bool done )
{
if ( watermark . ErrorsDetected )
{
result = ScriptError ;
done = true ;
return true ;
}
return false ;
}
// Token: 0x06000F24 RID: 3876 RVA: 0x0002ADC0 File Offset: 0x00029DC0
private static void RegisterDisposable ( object instance , TypeSchema type , IMarkupTypeBase root )
{
if ( type . Disposable && root != null )
{
IDisposableObject disposableObject = ( IDisposableObject ) instance ;
root . RegisterDisposable ( disposableObject );
disposableObject . DeclareOwner ( root );
}
}
// Token: 0x06000F25 RID: 3877 RVA: 0x0002ADF0 File Offset: 0x00029DF0
private static object GetCollection ( object stackInstance , MarkupImportTables importTables , int propertyIndex )
{
object result = null ;
if ( propertyIndex == 65535 )
{
result = stackInstance ;
}
else
{
PropertySchema propertySchema = importTables . PropertyImports [ propertyIndex ];
ReportErrorOnNull ( stackInstance , "Property Get" , propertySchema . Name );
if ( stackInstance != null )
{
result = propertySchema . GetValue ( stackInstance );
}
}
return result ;
}
// Token: 0x06000F26 RID: 3878 RVA: 0x0002AE31 File Offset: 0x00029E31
private static void ReportErrorOnNull ( object instance , string operation , string member )
{
if ( instance == null )
{
ErrorManager . ReportError ( "Script runtime failure: Null-reference while attempting a '{0}' of '{1}' on a null instance" , operation , member );
}
}
// Token: 0x06000F27 RID: 3879 RVA: 0x0002AE42 File Offset: 0x00029E42
private static void ReportErrorOnNull ( object instance , string operation )
{
if ( instance == null )
{
ErrorManager . ReportError ( "Script runtime failure: Null-reference while attempting a '{0}'" , operation );
}
}
// Token: 0x06000F28 RID: 3880 RVA: 0x0002AE54 File Offset: 0x00029E54
private static void ReportErrorOnNullOrDisposed ( object instance , string operation , string member , TypeSchema typeSchema )
{
if ( instance == null )
{
ErrorManager . ReportError ( "Script runtime failure: Null-reference while attempting a '{0}' of '{1}' on a null instance" , operation , member );
return ;
}
if ( typeSchema . Disposable )
{
IDisposableObject disposableObject = ( IDisposableObject ) instance ;
if ( disposableObject . IsDisposed )
{
ErrorManager . ReportError ( "Script runtime failure: Attempting a '{0}' of '{1}' on an object '{2}' that has already been disposed" , operation , member , TypeSchema . NameFromInstance ( instance ));
}
}
}
// Token: 0x04000947 RID: 2375
public const uint InvalidOffset = 4294967295 U ;
// Token: 0x04000948 RID: 2376
private static object VoidReturnValue = new object ();
// Token: 0x04000949 RID: 2377
private static Stack _stack = new Stack ();
2022-06-24 20:41:00 -05:00
private static Stack < XmlNode > _xmlStack = new Stack < XmlNode >();
2022-03-03 08:14:05 -06:00
// Token: 0x0400094A RID: 2378
public static object ScriptError = new Interpreter . ScriptErrorObject ();
// Token: 0x0400094B RID: 2379
public static string ExceptionContext ;
// Token: 0x0200018C RID: 396
private class ScriptErrorObject
{
}
// Token: 0x0200018D RID: 397
private struct ParameterListAllocator
{
// Token: 0x06000F2C RID: 3884 RVA: 0x0002AECC File Offset: 0x00029ECC
public static object [] Alloc ( int count )
{
object [] array ;
if ( count == 0 )
{
array = s_params0 ;
}
2023-05-22 18:04:22 -05:00
else if ( count < MAX_CACHED_LIST_SIZE )
2022-03-03 08:14:05 -06:00
{
array = s_cachedLists [ count ];
if ( array != null )
{
s_cachedLists [ count ] = null ;
}
else
{
array = new object [ count ];
}
}
else
{
array = new object [ count ];
}
return array ;
}
// Token: 0x06000F2D RID: 3885 RVA: 0x0002AF10 File Offset: 0x00029F10
public static void Free ( object [] paramList )
{
int num = paramList . Length ;
2023-05-22 18:04:22 -05:00
if ( num != 0 && num < MAX_CACHED_LIST_SIZE && s_cachedLists [ num ] == null )
2022-03-03 08:14:05 -06:00
{
Array . Clear ( paramList , 0 , paramList . Length );
s_cachedLists [ num ] = paramList ;
}
}
// Token: 0x0400094C RID: 2380
private const int MAX_CACHED_LIST_SIZE = 20 ;
// Token: 0x0400094D RID: 2381
private static object [] s_params0 = new object [ 0 ];
// Token: 0x0400094E RID: 2382
2023-05-22 18:04:22 -05:00
private static object [][] s_cachedLists = new object [ MAX_CACHED_LIST_SIZE ][];
2022-03-03 08:14:05 -06:00
}
private static XmlElement UIXElem ;
private static XmlDocument _xmlDoc ;
public static XmlDocument XmlDoc
{
get
{
if ( _xmlDoc == null )
{
_xmlDoc = new XmlDocument ();
UIXElem = _xmlDoc . CreateElement ( "UIX" );
UIXElem . SetAttribute ( "xmlns" , "http://schemas.microsoft.com/2007/uix" );
_xmlDoc . AppendChild ( UIXElem );
}
return _xmlDoc ;
}
}
/// <summary>
/// Attempts to generate source UIX from a compiled result
/// </summary>
private static object RunDecompile ( InterpreterContext context , ByteCodeReader reader )
{
MarkupLoadResult loadResult = context . LoadResult ;
IMarkupTypeBase instance = context . Instance ;
MarkupImportTables importTables = loadResult . ImportTables ;
MarkupConstantsTable constantsTable = loadResult . ConstantsTable ;
SymbolReference [] symbolReferenceTable = context . MarkupType . SymbolReferenceTable ;
2023-05-22 18:04:22 -05:00
2022-03-03 08:14:05 -06:00
Trace . IsCategoryEnabled ( TraceCategory . Markup );
2023-05-22 18:04:22 -05:00
bool decompile = Application . DebugSettings . UseDecompiler ;
2022-03-03 08:14:05 -06:00
Stack stack = _stack ;
2022-06-24 20:41:00 -05:00
Stack < XmlNode > xmlStack = _xmlStack ;
2022-03-03 08:14:05 -06:00
int count = stack . Count ;
2023-05-22 18:04:22 -05:00
2022-03-03 08:14:05 -06:00
if ( instance != null )
{
stack . Push ( instance );
// Make sure XmlDoc has been initialized
_ = XmlDoc ;
// Add UI container to root
string key = instance . TypeSchema . Name ;
XmlElement instanceXml = UIXElem . ChildNodes . OfType < XmlElement >()
. FirstOrDefault ( elem => elem ?. GetAttribute ( "Name" ) == key );
if ( instanceXml == null )
{
instanceXml = XmlDoc . CreateElement ( "UI" );
instanceXml . SetAttribute ( "Name" , key );
UIXElem . AppendChild ( instanceXml );
}
xmlStack . Push ( instanceXml );
}
ErrorWatermark watermark = ErrorManager . Watermark ;
bool flag = false ;
object result = null ;
bool wasInDebugState = false ;
while (! flag )
{
OpCode opCode = ( OpCode ) reader . ReadByte ();
2022-06-07 14:30:29 -05:00
var entry = new Debug . Data . InterpreterEntry ( opCode );
2022-03-03 08:14:05 -06:00
switch ( opCode )
{
case OpCode . ConstructObject :
{
int num = reader . ReadUInt16 ();
TypeSchema typeSchema = importTables . TypeImports [ num ];
object obj = typeSchema . ConstructDefault ();
string typeName = obj . GetType (). Name ;
int idxTilde = typeName . IndexOf ( '`' );
if ( idxTilde >= 0 )
typeName = typeName . Substring ( 0 , idxTilde );
var objXml = XmlDoc . CreateElement ( typeName );
2022-06-07 14:30:29 -05:00
entry . Arguments . Add ( new Debug . Data . OpCodeArgument (
"type" , typeof ( TypeSchema ), typeSchema ));
2022-03-03 08:14:05 -06:00
ReportErrorOnNull ( obj , "Construction" , typeSchema . Name );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
RegisterDisposable ( obj , typeSchema , instance );
stack . Push ( obj );
xmlStack . Push ( objXml );
}
break ;
}
case OpCode . ConstructObjectIndirect :
{
int num2 = reader . ReadUInt16 ();
TypeSchema typeSchema2 = importTables . TypeImports [ num2 ];
TypeSchema typeSchema3 = ( TypeSchema ) stack . Pop ();
2022-06-24 20:41:00 -05:00
xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
if (! typeSchema2 . IsAssignableFrom ( typeSchema3 ))
{
ErrorManager . ReportError ( "Script runtime failure: Dynamic construction type override failed. Attempting to construct '{0}' in place of '{1}'" , ( typeSchema3 != null ) ? typeSchema3 . Name : "null" , typeSchema2 . Name );
if ( ErrorsDetected ( watermark , ref result , ref flag ))
{
break ;
}
}
IDynamicConstructionSchema dynamicConstructionSchema = typeSchema3 as IDynamicConstructionSchema ;
object obj2 ;
if ( dynamicConstructionSchema != null )
{
obj2 = dynamicConstructionSchema . ConstructDefault ( typeSchema2 );
}
else
{
obj2 = typeSchema3 . ConstructDefault ();
}
var objXml2 = XmlDoc . CreateElement ( obj2 . GetType (). Name );
ReportErrorOnNull ( obj2 , "Construction" , typeSchema3 . Name );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
RegisterDisposable ( obj2 , typeSchema3 , instance );
stack . Push ( obj2 );
xmlStack . Push ( objXml2 );
}
break ;
}
case OpCode . ConstructObjectParam :
{
int num3 = reader . ReadUInt16 ();
TypeSchema typeSchema4 = importTables . TypeImports [ num3 ];
int num4 = reader . ReadUInt16 ();
ConstructorSchema constructorSchema = importTables . ConstructorImports [ num4 ];
int i = constructorSchema . ParameterTypes . Length ;
object [] array = ParameterListAllocator . Alloc ( i );
for ( i --; i >= 0 ; i --)
{
array [ i ] = stack . Pop ();
xmlStack . Pop (); // TODO
}
object obj3 = constructorSchema . Construct ( array );
var objXml3 = XmlDoc . CreateElement ( obj3 . GetType (). Name );
ReportErrorOnNull ( obj3 , "Construction" , typeSchema4 . Name );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
RegisterDisposable ( obj3 , typeSchema4 , instance );
stack . Push ( obj3 );
xmlStack . Push ( objXml3 );
ParameterListAllocator . Free ( array );
}
break ;
}
case OpCode . ConstructFromString :
{
int num5 = reader . ReadUInt16 ();
TypeSchema typeSchema5 = importTables . TypeImports [ num5 ];
int index = reader . ReadUInt16 ();
string from = ( string ) constantsTable . Get ( index );
object obj4 ;
typeSchema5 . TypeConverter ( from , StringSchema . Type , out obj4 );
var objXml4 = XmlDoc . CreateElement ( obj4 . GetType (). Name );
ReportErrorOnNull ( obj4 , "Construction" , typeSchema5 . Name );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
RegisterDisposable ( obj4 , typeSchema5 , instance );
stack . Push ( obj4 );
xmlStack . Push ( objXml4 );
}
break ;
}
case OpCode . ConstructFromBinary :
{
int num6 = reader . ReadUInt16 ();
TypeSchema typeSchema6 = importTables . TypeImports [ num6 ];
object obj5 = typeSchema6 . DecodeBinary ( reader );
var objXml5 = XmlDoc . CreateElement ( obj5 . GetType (). Name );
ReportErrorOnNull ( obj5 , "Construction" , typeSchema6 . Name );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
RegisterDisposable ( obj5 , typeSchema6 , instance );
stack . Push ( obj5 );
xmlStack . Push ( objXml5 );
}
break ;
}
case OpCode . InitializeInstance :
{
int num7 = reader . ReadUInt16 ();
TypeSchema typeSchema7 = importTables . TypeImports [ num7 ];
object obj6 = stack . Pop ();
var objXml6 = ( XmlElement ) xmlStack . Pop ();
typeSchema7 . InitializeInstance ( ref obj6 );
objXml6 . SetAttribute ( "Name" , typeSchema7 . Name );
ReportErrorOnNull ( obj6 , "Initialize" , typeSchema7 . Name );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
stack . Push ( obj6 );
xmlStack . Push ( objXml6 );
}
break ;
}
case OpCode . InitializeInstanceIndirect :
{
TypeSchema typeSchema8 = ( TypeSchema ) stack . Pop ();
object obj7 = stack . Pop ();
typeSchema8 . InitializeInstance ( ref obj7 );
2022-07-05 12:00:18 -05:00
xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
var objXml7 = ( XmlElement ) xmlStack . Pop ();
objXml7 . SetAttribute ( "Name" , typeSchema8 . Name );
ReportErrorOnNull ( obj7 , "Initialize" , typeSchema8 . Name );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
stack . Push ( obj7 );
xmlStack . Push ( objXml7 );
}
break ;
}
case OpCode . LookupSymbol :
{
int num8 = reader . ReadUInt16 ();
SymbolReference symbolRef = symbolReferenceTable [ num8 ];
2022-06-07 14:30:29 -05:00
entry . Arguments . Add ( new Debug . Data . OpCodeArgument (
"symbolRef" , typeof ( SymbolReference ), symbolRef ));
2022-03-03 08:14:05 -06:00
object obj8 = context . ReadSymbol ( symbolRef );
2022-06-24 20:41:00 -05:00
var objXml8 = GenerateXmlRepresentation ( obj8 );
2022-06-07 14:30:29 -05:00
2022-03-03 08:14:05 -06:00
stack . Push ( obj8 );
xmlStack . Push ( objXml8 );
2022-06-07 14:30:29 -05:00
entry . ReturnValues . Add ( obj8 );
2022-03-03 08:14:05 -06:00
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . WriteSymbol :
case OpCode . WriteSymbolPeek :
{
object value = ( opCode == OpCode . WriteSymbolPeek ) ? stack . Peek () : stack . Pop ();
2022-07-05 12:00:18 -05:00
if ( opCode == OpCode . WriteSymbol ) xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
int num9 = reader . ReadUInt16 ();
SymbolReference symbolRef2 = symbolReferenceTable [ num9 ];
2022-06-07 14:30:29 -05:00
entry . Arguments . Add ( new Debug . Data . OpCodeArgument (
"symbolRef" , typeof ( SymbolReference ), symbolRef2 ));
entry . Arguments . Add ( new Debug . Data . OpCodeArgument (
"value" , typeof ( object ), value ));
2022-03-03 08:14:05 -06:00
context . WriteSymbol ( symbolRef2 , value );
2022-06-07 14:30:29 -05:00
2022-03-03 08:14:05 -06:00
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . ClearSymbol :
{
int num10 = reader . ReadUInt16 ();
SymbolReference symbolRef3 = symbolReferenceTable [ num10 ];
context . ClearSymbol ( symbolRef3 );
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . PropertyInitialize :
case OpCode . PropertyInitializeIndirect :
{
bool isPropInitIndirect = opCode == OpCode . PropertyInitializeIndirect ;
TypeSchema typeSchema9 = null ;
if ( isPropInitIndirect )
{
typeSchema9 = ( TypeSchema ) stack . Pop ();
2022-07-05 12:00:18 -05:00
xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
}
int num11 = reader . ReadUInt16 ();
PropertySchema propertySchema = importTables . PropertyImports [ num11 ];
object propValue = stack . Pop ();
object destObj = stack . Pop ();
2022-06-24 20:41:00 -05:00
XmlNode propValueXml = xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
var destObjXml = ( XmlElement ) xmlStack . Pop ();
ReportErrorOnNull ( destObj , "Property Set" , propertySchema . Name );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
if ( isPropInitIndirect )
{
PropertySchema propertySchema2 = typeSchema9 . FindPropertyDeep ( propertySchema . Name );
if ( propertySchema2 != propertySchema )
{
TypeSchema propertyType = propertySchema2 . PropertyType ;
if (! propertyType . IsAssignableFrom ( propValue ))
{
string param = TypeSchema . NameFromInstance ( propValue );
ErrorManager . ReportError ( "Script runtime failure: Incompatible value for property '{0}' supplied (expecting values of type '{1}' but got '{2}') while constructing runtime replacement type '{3}' (original type '{4}')" , propertySchema . Name , propertyType . Name , param , typeSchema9 . Name , propertySchema . Owner . Name );
result = ScriptError ;
}
if ( ErrorsDetected ( watermark , ref result , ref flag ))
{
break ;
}
}
}
2022-06-24 20:41:00 -05:00
2022-03-03 08:14:05 -06:00
propertySchema . SetValue ( ref destObj , propValue );
2022-06-24 20:41:00 -05:00
if (! IsDefaultValue ( propValue ))
SetXmlPropValue ( destObjXml , propertySchema . Name , propValueXml );
2022-03-03 08:14:05 -06:00
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
stack . Push ( destObj );
xmlStack . Push ( destObjXml );
}
}
break ;
}
case OpCode . PropertyListAdd :
{
int propertyIndex = reader . ReadUInt16 ();
object value2 = stack . Pop ();
2022-06-24 20:41:00 -05:00
XmlNode valueXml2 = xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
object collection = GetCollectionDecompile ( stack . Peek (), importTables , propertyIndex , out var propertySchema );
ReportErrorOnNull ( collection , "List Add" );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
(( IList ) collection ). Add ( value2 );
if ( ErrorsDetected ( watermark , ref result , ref flag ))
{
}
// Add value to list
2022-06-24 20:41:00 -05:00
var destObjXml = xmlStack . Peek ();
if (! IsDefaultValue ( value2 ) && valueXml2 != null )
2022-03-03 08:14:05 -06:00
{
2022-07-05 12:00:18 -05:00
if ( propertySchema != null )
2022-06-24 20:41:00 -05:00
{
2022-07-05 12:00:18 -05:00
// Create element if needed
if ( destObjXml . SelectSingleNode ( propertySchema . Name ) is not XmlElement propXmlElem2 )
{
propXmlElem2 = XmlDoc . CreateElement ( propertySchema . Name );
destObjXml . AppendChild ( propXmlElem2 );
}
propXmlElem2 . AppendChild ( valueXml2 );
}
else
{
// Add straight to parent element
var valueXmlElem2 = XmlDoc . CreateElement ( "String" );
valueXmlElem2 . AppendChild ( valueXml2 );
destObjXml . AppendChild ( valueXmlElem2 );
2022-06-24 20:41:00 -05:00
}
2022-03-03 08:14:05 -06:00
}
}
break ;
}
case OpCode . PropertyDictionaryAdd :
{
int propertyIndex2 = reader . ReadUInt16 ();
int index2 = reader . ReadUInt16 ();
string key = ( string ) constantsTable . Get ( index2 );
object value3 = stack . Pop ();
2022-06-24 20:41:00 -05:00
XmlNode valueXml3 = xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
object collection2 = GetCollectionDecompile ( stack . Peek (), importTables , propertyIndex2 , out var propertySchema2 );
ReportErrorOnNull ( collection2 , "Dictionary Add" );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
(( IDictionary ) collection2 )[ key ] = value3 ;
if ( ErrorsDetected ( watermark , ref result , ref flag ))
{
}
2022-06-24 20:41:00 -05:00
if (! IsDefaultValue ( value3 ) && valueXml3 != null )
2022-03-03 08:14:05 -06:00
{
2022-06-24 20:41:00 -05:00
// Prepare value XML element
if ( valueXml3 is not XmlElement valueXmlElem3 )
2022-03-03 08:14:05 -06:00
{
2022-06-24 20:41:00 -05:00
// Need to create an XML element from the node
valueXmlElem3 = XmlDoc . CreateElement ( value3 . GetType (). Name );
valueXmlElem3 . AppendChild ( valueXml3 );
2022-03-03 08:14:05 -06:00
}
2022-06-24 20:41:00 -05:00
// Add value to dictionary
var destObjXml2 = xmlStack . Peek ();
// Create element if needed
if ( propertySchema2 != null )
{
if ( destObjXml2 . SelectSingleNode ( propertySchema2 . Name ) is not XmlElement propXmlElem2 )
{
propXmlElem2 = XmlDoc . CreateElement ( propertySchema2 . Name );
destObjXml2 . AppendChild ( propXmlElem2 );
}
propXmlElem2 . AppendChild ( valueXmlElem3 );
}
valueXmlElem3 . SetAttribute ( "Name" , key );
2022-03-03 08:14:05 -06:00
}
}
break ;
}
case OpCode . PropertyAssign :
case OpCode . PropertyAssignStatic :
{
int num12 = reader . ReadUInt16 ();
PropertySchema propertySchema3 = importTables . PropertyImports [ num12 ];
object instance2 = null ;
if ( opCode == OpCode . PropertyAssign )
{
instance2 = stack . Pop ();
ReportErrorOnNullOrDisposed ( instance2 , "Property Set" , propertySchema3 . Name , propertySchema3 . Owner );
if ( ErrorsDetected ( watermark , ref result , ref flag ))
{
break ;
}
}
object value4 = stack . Peek ();
propertySchema3 . SetValue ( ref instance2 , value4 );
2022-06-24 20:41:00 -05:00
if ( opCode == OpCode . PropertyAssign )
{
var xmlInstance2 = ( XmlElement ) xmlStack . Pop ();
SetXmlPropValue ( xmlInstance2 , propertySchema3 . Name , value4 );
}
2022-03-03 08:14:05 -06:00
if (! ErrorsDetected ( watermark , ref result , ref flag ) && Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . PropertyGet :
case OpCode . PropertyGetPeek :
case OpCode . PropertyGetStatic :
{
int num13 = reader . ReadUInt16 ();
PropertySchema propertySchema4 = importTables . PropertyImports [ num13 ];
2022-06-24 20:41:00 -05:00
2022-03-03 08:14:05 -06:00
object instance3 = null ;
2022-06-24 20:41:00 -05:00
2022-03-03 08:14:05 -06:00
if ( opCode != OpCode . PropertyGetStatic )
{
2022-06-24 20:41:00 -05:00
bool pop = opCode == OpCode . PropertyGet ;
instance3 = pop ? stack . Pop () : stack . Peek ();
2022-07-05 12:00:18 -05:00
if ( pop ) xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
ReportErrorOnNullOrDisposed ( instance3 , "Property Get" , propertySchema4 . Name , propertySchema4 . Owner );
if ( ErrorsDetected ( watermark , ref result , ref flag ))
{
break ;
}
}
object value5 = propertySchema4 . GetValue ( instance3 );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
stack . Push ( value5 );
xmlStack . Push ( GenerateXmlRepresentation ( value5 ));
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
break ;
}
case OpCode . MethodInvoke :
case OpCode . MethodInvokePeek :
case OpCode . MethodInvokeStatic :
case OpCode . MethodInvokePushLastParam :
case OpCode . MethodInvokeStaticPushLastParam :
{
int num14 = reader . ReadUInt16 ();
MethodSchema methodSchema = importTables . MethodImports [ num14 ];
int j = methodSchema . ParameterTypes . Length ;
object [] array2 = ParameterListAllocator . Alloc ( j );
for ( j --; j >= 0 ; j --)
{
array2 [ j ] = stack . Pop ();
2022-06-24 20:41:00 -05:00
xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
}
object instance4 = null ;
bool flag3 = opCode != OpCode . MethodInvokeStatic && opCode != OpCode . MethodInvokeStaticPushLastParam ;
bool flag4 = opCode == OpCode . MethodInvokePeek ;
bool flag5 = opCode == OpCode . MethodInvokePushLastParam || opCode == OpCode . MethodInvokeStaticPushLastParam ;
if ( flag3 )
{
if (! flag4 )
{
instance4 = stack . Pop ();
2022-06-24 20:41:00 -05:00
xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
}
else
{
instance4 = stack . Peek ();
}
ReportErrorOnNullOrDisposed ( instance4 , "Method Invoke" , methodSchema . Name , methodSchema . Owner );
if ( ErrorsDetected ( watermark , ref result , ref flag ))
{
break ;
}
}
2023-04-28 18:46:37 -05:00
if ( methodSchema . Name == "PlayOrPreview" )
System . Diagnostics . Debugger . Break ();
2022-03-03 08:14:05 -06:00
object obj11 = methodSchema . Invoke ( instance4 , array2 );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
if (! flag5 )
{
if ( methodSchema . ReturnType != VoidSchema . Type )
{
stack . Push ( obj11 );
2022-06-24 20:41:00 -05:00
xmlStack . Push ( GenerateXmlRepresentation ( obj11 ));
2022-03-03 08:14:05 -06:00
}
}
else
{
2022-06-24 20:41:00 -05:00
var lastParam = array2 [ array2 . Length - 1 ];
stack . Push ( lastParam );
xmlStack . Push ( GenerateXmlRepresentation ( lastParam ));
2022-03-03 08:14:05 -06:00
}
ParameterListAllocator . Free ( array2 );
}
break ;
}
case OpCode . VerifyTypeCast :
{
int num15 = reader . ReadUInt16 ();
TypeSchema typeSchema10 = importTables . TypeImports [ num15 ];
object obj12 = stack . Peek ();
if ( obj12 != null )
{
if (! typeSchema10 . IsAssignableFrom ( obj12 ))
{
string param2 = TypeSchema . NameFromInstance ( obj12 );
string name = typeSchema10 . Name ;
ErrorManager . ReportError ( "Script runtime failure: Invalid type cast while attempting to cast an instance with a runtime type of '{0}' to '{1}'" , param2 , name );
result = ScriptError ;
}
if ( ErrorsDetected ( watermark , ref result , ref flag ))
{
}
}
else if (! typeSchema10 . IsNullAssignable )
{
ReportErrorOnNull ( obj12 , "Verify Type Cast" , typeSchema10 . Name );
if ( ErrorsDetected ( watermark , ref result , ref flag ))
{
}
}
break ;
}
case OpCode . ConvertType :
{
int num16 = reader . ReadUInt16 ();
TypeSchema typeSchema11 = importTables . TypeImports [ num16 ];
int num17 = reader . ReadUInt16 ();
TypeSchema fromType = importTables . TypeImports [ num17 ];
object obj13 = stack . Pop ();
2022-06-24 20:41:00 -05:00
var xmlObj13 = xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
ReportErrorOnNull ( obj13 , "Type Conversion" , typeSchema11 . Name );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
object obj14 ;
Result result2 = typeSchema11 . TypeConverter ( obj13 , fromType , out obj14 );
if ( result2 . Failed )
{
ErrorManager . ReportError ( "Script runtime failure: Type conversion failed while attempting to convert to '{0}' ({1})" , typeSchema11 . Name , result2 . Error );
}
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
stack . Push ( obj14 );
2022-06-24 20:41:00 -05:00
xmlStack . Push ( GenerateXmlRepresentation ( obj14 ));
2022-03-03 08:14:05 -06:00
}
}
break ;
}
case OpCode . Operation :
{
int num18 = reader . ReadUInt16 ();
TypeSchema typeSchema12 = importTables . TypeImports [ num18 ];
OperationType op = ( OperationType ) reader . ReadByte ();
object right = null ;
if (! TypeSchema . IsUnaryOperation ( op ))
{
right = stack . Pop ();
2022-06-24 20:41:00 -05:00
xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
}
object left = stack . Pop ();
2022-06-24 20:41:00 -05:00
xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
object obj15 = typeSchema12 . PerformOperationDeep ( left , right , op );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
stack . Push ( obj15 );
2022-06-24 20:41:00 -05:00
xmlStack . Push ( GenerateXmlRepresentation ( obj15 ));
2022-03-03 08:14:05 -06:00
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
break ;
}
case OpCode . IsCheck :
{
int num19 = reader . ReadUInt16 ();
TypeSchema typeSchema13 = importTables . TypeImports [ num19 ];
object obj16 = stack . Pop ();
2022-06-24 20:41:00 -05:00
var xmlObj16 = xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
bool value6 = false ;
if ( obj16 != null )
{
value6 = typeSchema13 . IsAssignableFrom ( obj16 );
}
stack . Push ( BooleanBoxes . Box ( value6 ));
2022-06-24 20:41:00 -05:00
xmlStack . Push ( GenerateXmlRepresentation ( value6 ));
2022-03-03 08:14:05 -06:00
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . As :
{
int num20 = reader . ReadUInt16 ();
TypeSchema typeSchema14 = importTables . TypeImports [ num20 ];
object obj17 = stack . Peek ();
if ( obj17 != null && ! typeSchema14 . IsAssignableFrom ( obj17 ))
{
stack . Pop ();
stack . Push ( null );
2022-06-24 20:41:00 -05:00
xmlStack . Pop ();
xmlStack . Push ( GenerateXmlRepresentation ( null ));
2022-03-03 08:14:05 -06:00
}
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . TypeOf :
{
int num21 = reader . ReadUInt16 ();
TypeSchema obj18 = importTables . TypeImports [ num21 ];
stack . Push ( obj18 );
2022-06-24 20:41:00 -05:00
xmlStack . Push ( GenerateXmlRepresentation ( obj18 ));
2022-03-03 08:14:05 -06:00
break ;
}
case OpCode . PushNull :
stack . Push ( null );
2022-06-24 20:41:00 -05:00
xmlStack . Push ( GenerateXmlRepresentation ( null ));
2022-03-03 08:14:05 -06:00
break ;
case OpCode . PushConstant :
{
int index3 = reader . ReadUInt16 ();
object obj19 = constantsTable . Get ( index3 );
stack . Push ( obj19 );
xmlStack . Push ( GenerateXmlRepresentation ( obj19 ));
break ;
}
case OpCode . PushThis :
stack . Push ( instance );
xmlStack . Push ( GenerateXmlRepresentation ( instance ));
break ;
case OpCode . DiscardValue :
stack . Pop ();
2022-06-24 20:41:00 -05:00
xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
break ;
case OpCode . ReturnValue :
{
object obj20 = stack . Pop ();
2022-06-24 20:41:00 -05:00
xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
result = obj20 ;
flag = true ;
break ;
}
case OpCode . ReturnVoid :
result = VoidReturnValue ;
flag = true ;
break ;
case OpCode . JumpIfFalse :
case OpCode . JumpIfFalsePeek :
case OpCode . JumpIfTruePeek :
{
uint currentOffset = reader . ReadUInt32 ();
object obj21 = ( opCode == OpCode . JumpIfFalse ) ? stack . Pop () : stack . Peek ();
2022-06-24 20:41:00 -05:00
if ( opCode == OpCode . JumpIfFalse ) xmlStack . Pop ();
2022-03-03 08:14:05 -06:00
bool flag6 = ( bool ) obj21 ;
bool flag7 = opCode == OpCode . JumpIfTruePeek ;
Trace . IsCategoryEnabled ( TraceCategory . Markup );
if ( flag7 == flag6 )
{
reader . CurrentOffset = currentOffset ;
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
break ;
}
case OpCode . JumpIfDictionaryContains :
{
ushort propertyIndex3 = reader . ReadUInt16 ();
ushort index4 = reader . ReadUInt16 ();
uint currentOffset2 = reader . ReadUInt32 ();
string key2 = ( string ) constantsTable . Get ( index4 );
object collection3 = GetCollection ( stack . Peek (), importTables , propertyIndex3 );
ReportErrorOnNull ( collection3 , "Dictionary Contains" );
if (! ErrorsDetected ( watermark , ref result , ref flag ))
{
bool flag8 = (( IDictionary ) collection3 ). Contains ( key2 );
Trace . IsCategoryEnabled ( TraceCategory . Markup );
if ( flag8 )
{
reader . CurrentOffset = currentOffset2 ;
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
}
break ;
}
case OpCode . JumpIfNullPeek :
{
uint currentOffset3 = reader . ReadUInt32 ();
object obj22 = stack . Peek ();
Trace . IsCategoryEnabled ( TraceCategory . Markup );
if ( obj22 == null )
{
reader . CurrentOffset = currentOffset3 ;
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
}
break ;
}
case OpCode . Jump :
{
uint currentOffset4 = reader . ReadUInt32 ();
reader . CurrentOffset = currentOffset4 ;
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . ConstructListenerStorage :
{
int listenerCount = reader . ReadUInt16 ();
if ( instance . Listeners == null )
{
MarkupListeners markupListeners = new MarkupListeners ( listenerCount );
markupListeners . DeclareOwner ( instance );
instance . Listeners = markupListeners ;
}
else
{
instance . Listeners . AddEntries ( listenerCount );
}
if ( Trace . IsCategoryEnabled ( TraceCategory . Markup ))
{
}
break ;
}
case OpCode . Listen :
case OpCode . DestructiveListen :
{
int index5 = reader . ReadUInt16 ();
ListenerType listenerType = ( ListenerType ) reader . ReadByte ();
int num22 = reader . ReadUInt16 ();
uint scriptOffset = reader . ReadUInt32 ();
uint refreshOffset = uint . MaxValue ;
if ( opCode == OpCode . DestructiveListen )
{
refreshOffset = reader . ReadUInt32 ();
}
string watch = null ;
switch ( listenerType )
{
case ListenerType . Property :
watch = importTables . PropertyImports [ num22 ]. Name ;
break ;
case ListenerType . Event :
watch = importTables . EventImports [ num22 ]. Name ;
break ;
case ListenerType . Symbol :
watch = symbolReferenceTable [ num22 ]. Symbol ;
break ;
}
object obj23 = stack . Peek ();
if ( obj23 != null )
{
INotifyObject notifier = ( INotifyObject ) obj23 ;
Trace . IsCategoryEnabled ( TraceCategory . Markup );
MarkupListeners listeners = instance . Listeners ;
listeners . RefreshListener ( index5 , notifier , watch , instance , scriptOffset , refreshOffset );
}
else
{
Trace . IsCategoryEnabled ( TraceCategory . Markup );
}
break ;
}
case OpCode . EnterDebugState :
{
int breakpointIndex = reader . ReadInt32 ();
if ( MarkupSystem . IsDebuggingEnabled ( 2 ))
{
wasInDebugState = MarkupDebugHelper . EnterDebugState ( wasInDebugState , loadResult , breakpointIndex , instance . Storage );
}
break ;
}
}
2023-05-22 21:44:05 -05:00
Application . Debugger ?. LogInterpreterOpCode ( opCode , entry );
2022-06-07 14:30:29 -05:00
2022-03-03 08:14:05 -06:00
if ( stack . Count != xmlStack . Count )
throw new InvalidOperationException (
$"Invalid stacks, stack:{stack.Count} != xmlStack{xmlStack.Count}! " +
2022-06-07 14:30:29 -05:00
$"Check implementations for {opCode}" );
2022-03-03 08:14:05 -06:00
}
while ( stack . Count > count )
{
stack . Pop ();
xmlStack . Pop ();
}
CleanUpXmlDoc ();
2022-06-24 20:41:00 -05:00
Application . DebugSettings . DecompileResults . Add ( new ( loadResult . Uri , XmlDoc ));
2022-03-03 08:14:05 -06:00
return result ;
}
// Token: 0x06000F25 RID: 3877 RVA: 0x0002ADF0 File Offset: 0x00029DF0
private static object GetCollectionDecompile ( object stackInstance , MarkupImportTables importTables , int propertyIndex , out PropertySchema prop )
{
object result = null ;
prop = null ;
if ( propertyIndex == 65535 )
{
result = stackInstance ;
}
else
{
PropertySchema propertySchema = importTables . PropertyImports [ propertyIndex ];
ReportErrorOnNull ( stackInstance , "Property Get" , propertySchema . Name );
if ( stackInstance != null )
{
result = propertySchema . GetValue ( stackInstance );
prop = propertySchema ;
}
}
return result ;
}
2022-06-24 20:41:00 -05:00
private static XmlNode GenerateXmlRepresentation ( object obj , int recursionLevel = 5 )
2022-03-03 08:14:05 -06:00
{
2022-06-24 20:41:00 -05:00
if ( obj == null || recursionLevel < 0 )
2022-03-03 08:14:05 -06:00
{
2022-06-24 20:41:00 -05:00
return null ;
}
var objType = obj . GetType ();
if ( objType . IsPrimitive || objType . IsEnum || objType == typeof ( string ))
{
return XmlDoc . CreateTextNode ( obj . ToString ());
}
else if ( obj is AssemblyObjectProxyHelper . IAssemblyProxyObject objProxy
&& obj != objProxy . AssemblyObject )
{
// This is a proxy object, meaning it doesn't actually hold any values itself.
return GenerateXmlRepresentation ( objProxy . AssemblyObject , recursionLevel );
}
else if ( typeof ( IEnumerable ). IsAssignableFrom ( objType ))
{
// This is a list or array
var objXml = XmlDoc . CreateElement ( "List" );
foreach ( object item in obj as IEnumerable )
2022-03-03 08:14:05 -06:00
{
2022-06-24 20:41:00 -05:00
var itemXml = GenerateXmlRepresentation ( item , recursionLevel );
if ( itemXml != null )
objXml . AppendChild ( itemXml );
2022-03-03 08:14:05 -06:00
}
return objXml ;
}
2022-06-24 20:41:00 -05:00
else
{
var objXml = XmlDoc . CreateElement ( objType . Name );
// Use reflection to recursively generate XML representations for each property
foreach ( System . Reflection . PropertyInfo prop in objType . GetProperties ())
{
if (! prop . CanWrite || ! prop . CanRead )
continue ;
2022-07-05 12:00:18 -05:00
try
{
object value = prop . GetValue ( obj , null );
if ( IsDefaultValue ( value ))
continue ;
2022-06-24 20:41:00 -05:00
2022-07-05 12:00:18 -05:00
SetXmlPropValue ( objXml , prop . Name , value , recursionLevel - 1 );
}
catch
{
// Ignore errors, sometimes things aren't initialized yet
continue ;
}
2022-06-24 20:41:00 -05:00
}
return objXml ;
}
}
private static void SetXmlPropValue ( XmlElement objXml , string propName , object value , int recursionLevel = 10 )
{
var valueXml = GenerateXmlRepresentation ( value , recursionLevel );
SetXmlPropValue ( objXml , propName , valueXml );
}
private static void SetXmlPropValue ( XmlElement objXml , string propName , XmlNode valueXml )
{
if ( valueXml is XmlElement propValueXml )
{
var propXml = XmlDoc . CreateElement ( propName );
propXml . AppendChild ( propValueXml );
objXml . AppendChild ( propXml );
}
else if ( valueXml != null )
{
// Primitive type, set as attribute
objXml . SetAttribute ( propName , valueXml . InnerText );
}
}
private static bool IsDefaultValue ( object value )
{
if ( value == null )
return true ;
var type = value . GetType ();
object defaultValue = type . IsValueType ? Activator . CreateInstance ( type ) : null ;
return value ?. Equals ( defaultValue ) ?? true ;
2022-03-03 08:14:05 -06:00
}
private static void CleanUpXmlDoc ()
{
XmlNamespaceManager nsManager = new XmlNamespaceManager ( XmlDoc . NameTable );
2022-06-24 20:41:00 -05:00
var hosts = XmlDoc . DocumentElement . SelectNodes ( "*//Host" , nsManager );
2022-03-03 08:14:05 -06:00
foreach ( XmlNode node in hosts )
{
if (!( node is XmlElement host ))
continue ;
if ( host . Attributes . Count == 1 && host . HasAttribute ( "Name" ))
{
string uiElemName = host . GetAttribute ( "Name" );
nsManager . AddNamespace ( "me" , "Me" );
XmlDoc . DocumentElement . SetAttribute ( "xmlns:me" , "Me" );
XmlElement uiElem = XmlDoc . CreateElement ( "me" , uiElemName , "Me" );
host . ParentNode . ReplaceChild ( uiElem , host );
}
}
}
}
}