public static bool IsCallMethodInsideNamespace(Instruction instruction, string targetNamespace, out MethodReference methodRef) { methodRef = null; if (InstructionHelper.IsCallMethod(instruction.OpCode.Code)) { var method = instruction.Operand as MethodReference; if (method != null && method.FullName.Contains(targetNamespace)) { methodRef = method; return(true); } } return(false); }
/// <summary> /// Parses the instruction. /// </summary> /// <param name="mainProcessor">The processor.</param> /// <param name="asmCollection">The papyrus assembly collection.</param> /// <param name="instruction">The instruction.</param> /// <param name="targetMethod">The target method.</param> /// <param name="type">The type.</param> /// <returns></returns> /// <exception cref="System.NotImplementedException"></exception> /// <exception cref="MissingVariableException"></exception> public IEnumerable <PapyrusInstruction> Process( IClrInstructionProcessor mainProcessor, IReadOnlyCollection <PapyrusAssemblyDefinition> asmCollection, Instruction instruction, MethodDefinition targetMethod, TypeDefinition type) { bool isStructAccess; var outputInstructions = new List <PapyrusInstruction>(); if (InstructionHelper.NextInstructionIs(instruction, Code.Ldnull) && InstructionHelper.NextInstructionIs(instruction.Next, Code.Cgt_Un)) { var stack = mainProcessor.EvaluationStack; //var itemToCheck = stack.Pop().Value; var itemToCheck = instruction.Operand as FieldReference; if (itemToCheck != null) { mainProcessor.EvaluationStack.Push( new EvaluationStackItem { Value = itemToCheck, TypeName = "" } ); mainProcessor.EvaluationStack.Push( new EvaluationStackItem { Value = null, TypeName = "none" } ); mainProcessor.SkipToOffset = InstructionHelper.NextInstructionIsOffset(instruction.Next, Code.Cgt_Un) - 1; //bool structAccess; //var targetVar = mainInstructionProcessor.GetTargetVariable(tarInstruction, null, out structAccess, "Bool"); //if (mainInstructionProcessor.SkipNextInstruction) //{ // mainInstructionProcessor.SkipToOffset += 2; // mainInstructionProcessor.SkipNextInstruction = false; //} //outputInstructions.Add(mainInstructionProcessor.CreatePapyrusInstruction(PapyrusOpCodes.Is, // mainInstructionProcessor.CreateVariableReferenceFromName(targetVar), fieldDef, // mainInstructionProcessor.CreateVariableReferenceFromName(typeToCheckAgainst.Name))); return(outputInstructions); } } if (InstructionHelper.IsLoadMethodRef(instruction.OpCode.Code)) { // Often used for delegates or Action/func parameters, when loading a reference pointer to a method and pushing it to the stack. // To maintain the evaluation stack, this could add a dummy item, but for now im not going to do so. } if (InstructionHelper.IsLoadLength(instruction.OpCode.Code)) { var popCount = Utility.GetStackPopCount(instruction.OpCode.StackBehaviourPop); if (mainProcessor.EvaluationStack.Count >= popCount) { var val = mainProcessor.EvaluationStack.Pop(); if (val.TypeName.EndsWith("[]")) { if (val.Value is PapyrusPropertyDefinition) { // for now, so if this exception is thrown, i will have to remember I have to fix it. throw new NotImplementedException(); } if (val.Value is PapyrusVariableReference || val.Value is PapyrusFieldDefinition || val.Value is PapyrusParameterDefinition) { int variableIndex; var storeInstruction = mainProcessor.GetNextStoreLocalVariableInstruction(instruction, out variableIndex); if (storeInstruction != null || InstructionHelper.IsConverToNumber(instruction.Next.OpCode.Code)) { if (InstructionHelper.IsConverToNumber(instruction.Next.OpCode.Code)) { mainProcessor.SkipNextInstruction = false; mainProcessor.SkipToOffset = 0; var targetVariableName = mainProcessor.GetTargetVariable(instruction, null, out isStructAccess, "Int", true); var allVars = mainProcessor.PapyrusMethod.GetVariables(); var targetVariable = allVars.FirstOrDefault(v => v.Name.Value == targetVariableName); if (targetVariable == null && mainProcessor.PapyrusCompilerOptions == PapyrusCompilerOptions.Strict) { throw new MissingVariableException(targetVariableName); } if (targetVariable != null) { mainProcessor.EvaluationStack.Push(new EvaluationStackItem { TypeName = targetVariable.TypeName.Value, Value = targetVariable }); outputInstructions.Add( mainProcessor.CreatePapyrusInstruction( PapyrusOpCodes.ArrayLength, mainProcessor.CreateVariableReference( PapyrusPrimitiveType.Reference, targetVariableName), val.Value)); } } else { var allVars = mainProcessor.PapyrusMethod.GetVariables(); mainProcessor.EvaluationStack.Push(new EvaluationStackItem { TypeName = allVars[variableIndex].TypeName.Value, Value = allVars[variableIndex] }); outputInstructions.Add( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.ArrayLength, allVars[variableIndex], val.Value)); //return "ArrayLength " + allVars[variableIndex].Name + " " + // (val.Value as VariableReference).Name; } } } } } // ArrayLength <outputVariableName> <arrayName> } if (InstructionHelper.IsLoadArgs(instruction.OpCode.Code)) { var index = (int)mainProcessor.GetNumericValue(instruction); if (targetMethod.IsStatic && index == 0 && targetMethod.Parameters.Count == 0) { mainProcessor.EvaluationStack.Push(new EvaluationStackItem { IsThis = true, Value = type, TypeName = type.FullName }); } else { if (targetMethod.HasThis && index == 0) { return(outputInstructions); } if (!targetMethod.IsStatic && index > 0) { index--; } if (index < mainProcessor.PapyrusMethod.Parameters.Count) { mainProcessor.EvaluationStack.Push(new EvaluationStackItem { Value = mainProcessor.PapyrusMethod.Parameters[index], TypeName = mainProcessor.PapyrusMethod.Parameters[index].TypeName.Value }); } } } if (InstructionHelper.IsLoadInteger(instruction.OpCode.Code)) { var index = mainProcessor.GetNumericValue(instruction); mainProcessor.EvaluationStack.Push(new EvaluationStackItem { Value = index, TypeName = "Int" }); } if (InstructionHelper.IsLoadNull(instruction.OpCode.Code)) { mainProcessor.EvaluationStack.Push(new EvaluationStackItem { Value = "None", TypeName = "None" }); } if (InstructionHelper.IsLoadLocalVariable(instruction.OpCode.Code)) { var index = (int)mainProcessor.GetNumericValue(instruction); var allVariables = mainProcessor.PapyrusMethod.GetVariables(); if (index < allVariables.Count) { mainProcessor.EvaluationStack.Push(new EvaluationStackItem { Value = allVariables[index], TypeName = allVariables[index].TypeName.Value }); } } if (InstructionHelper.IsLoadString(instruction.OpCode.Code)) { var value = StringUtility.AsString(instruction.Operand); mainProcessor.EvaluationStack.Push(new EvaluationStackItem { Value = value, TypeName = "String" }); } if (InstructionHelper.IsLoadFieldObject(instruction.OpCode.Code)) { if (instruction.Operand is FieldReference) { var fieldRef = instruction.Operand as FieldReference; PapyrusFieldDefinition targetField = null; targetField = mainProcessor.PapyrusType.Fields.FirstOrDefault( f => f.Name.Value == "::" + fieldRef.Name.Replace('<', '_').Replace('>', '_')); if (targetField == null) { targetField = mainProcessor.GetDelegateField(fieldRef); } if (targetField != null) { mainProcessor.EvaluationStack.Push(new EvaluationStackItem { Value = targetField, TypeName = targetField.TypeName }); } if (InstructionHelper.PreviousInstructionWas(instruction, Code.Ldflda) && fieldRef.FullName.Contains("/")) { var targetStructVariable = mainProcessor.EvaluationStack.Pop().Value; var structRef = new PapyrusStructFieldReference(mainProcessor.PapyrusAssembly, null) { StructSource = targetStructVariable, StructVariable = mainProcessor.CreateVariableReferenceFromName(fieldRef.Name) }; mainProcessor.EvaluationStack.Push(new EvaluationStackItem { Value = structRef, TypeName = "$StructAccess$" }); return(outputInstructions); // // The target field is not inside the declared type. // // Most likely, this is a get field from struct. // if (fieldRef.FieldType.FullName.Contains("/")) // { // var location = fieldRef.FieldType.FullName.Split("/").LastOrDefault(); // var targetStruct = mainInstructionProcessor.PapyrusType.NestedTypes.FirstOrDefault(n => n.Name.Value == location); // if (targetStruct != null) // { // targetField = mainInstructionProcessor.PapyrusType.Fields.FirstOrDefault( // f => f.Name.Value == "::" + fieldRef.Name); // // var stack = mainInstructionProcessor.EvaluationStack; // // TODO: Add support for getting values from Structs // // // // CreatePapyrusInstruction(PapyrusOpCode.StructGet, ...) // } // } } //else //{ // targetField = mainInstructionProcessor.PapyrusType.Fields.FirstOrDefault( // f => f.Name.Value == "::" + fieldRef.Name.Replace('<', '_').Replace('>', '_')); //} } } if (InstructionHelper.IsLoadElement(instruction.OpCode.Code)) { // TODO: Load Element (Arrays, and what not) var popCount = Utility.GetStackPopCount(instruction.OpCode.StackBehaviourPop); if (mainProcessor.EvaluationStack.Count >= popCount) { var itemIndex = mainProcessor.EvaluationStack.Pop(); var itemArray = mainProcessor.EvaluationStack.Pop(); object targetItemIndex = null; var targetItemArray = itemArray.Value; if (itemIndex.Value != null) { targetItemIndex = itemIndex.Value; } // 128 is the array size limit for Skyrim if (mainProcessor.PapyrusAssembly.VersionTarget == PapyrusVersionTargets.Skyrim) { if ((targetItemIndex as int?) > 128) { targetItemIndex = 128; } } // We want to use the Array Element together with a Method Call? var isBoxing = InstructionHelper.IsBoxing(instruction.Next.OpCode.Code); if (isBoxing || InstructionHelper.IsCallMethod(instruction.Next.OpCode.Code)) { if (isBoxing) { var sourceArray = targetItemArray as PapyrusVariableReference; if (sourceArray != null) { // Since we apply our logic necessary for this "boxing" right here // we can skip the next instruction to avoid unexpected behaviour. mainProcessor.SkipNextInstruction = true; // Create a new Temp Variable // Assign our value to this temp variable and push it to the stack // so that the next instruction can take care of it. var tempVariableType = sourceArray.TypeName.Value.Replace("[]", ""); var destinationTempVar = mainProcessor.GetTargetVariable(instruction, null, out isStructAccess, tempVariableType, true); var varRef = mainProcessor.PapyrusMethod.GetVariables() .FirstOrDefault(n => n.Name.Value == destinationTempVar); mainProcessor.EvaluationStack.Push(new EvaluationStackItem { Value = varRef ?? (object)destinationTempVar, // Should be the actual variable reference TypeName = tempVariableType }); outputInstructions.Add( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.ArrayGetElement, mainProcessor.CreateVariableReference( PapyrusPrimitiveType.Reference, destinationTempVar), targetItemArray, targetItemIndex)); } } else { // Get the method reference and then create a temp variable that // we can use for assigning the value to. var methodRef = instruction.Next.Operand as MethodReference; if (methodRef != null && methodRef.HasParameters) { var sourceArray = targetItemArray as PapyrusVariableReference; if (sourceArray != null) { var tempVariableType = sourceArray.TypeName.Value.Replace("[]", ""); var destinationTempVar = mainProcessor.GetTargetVariable(instruction, methodRef, out isStructAccess, tempVariableType); // "ArrayGetElement " + destinationTempVar + " " + targetItemArray + " " + targetItemIndex; outputInstructions.Add( mainProcessor.CreatePapyrusInstruction( PapyrusOpCodes.ArrayGetElement, mainProcessor.CreateVariableReference( PapyrusPrimitiveType.Reference, destinationTempVar), targetItemArray, targetItemIndex)); } } } } else { // Otherwise we just want to store it somewhere. int destinationVariableIndex; // Get the target variable by finding the next store instruction and returning the variable index. mainProcessor.GetNextStoreLocalVariableInstruction(instruction, out destinationVariableIndex); var destinationVar = mainProcessor.PapyrusMethod.GetVariables()[destinationVariableIndex]; // ArrayGetElement targetVariable targetItemArray targetItemIndex outputInstructions.Add( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.ArrayGetElement, destinationVar, targetItemArray, targetItemIndex) ); } } } return(outputInstructions); }
/// <summary> /// Parses the instruction. /// </summary> /// <param name="mainProcessor">The main processor.</param> /// <param name="asmCollection">The papyrus assembly collection.</param> /// <param name="instruction">The instruction.</param> /// <param name="targetMethod">The target method.</param> /// <param name="type">The type.</param> /// <returns></returns> public IEnumerable <PapyrusInstruction> Process( IClrInstructionProcessor mainProcessor, IReadOnlyCollection <PapyrusAssemblyDefinition> asmCollection, Instruction instruction, MethodDefinition targetMethod, TypeDefinition type) { var allVariables = mainProcessor.PapyrusMethod.GetVariables(); if (InstructionHelper.IsStoreElement(instruction.OpCode.Code)) { var popCount = Utility.GetStackPopCount(instruction.OpCode.StackBehaviourPop); if (mainProcessor.EvaluationStack.Count >= popCount) { var newValue = mainProcessor.EvaluationStack.Pop(); var itemIndex = mainProcessor.EvaluationStack.Pop(); var itemArray = mainProcessor.EvaluationStack.Pop(); object targetItemIndex = null; object targetItemArray = null; object targetItemValue = null; if (itemIndex.Value is PapyrusVariableReference) { targetItemIndex = itemIndex.Value as PapyrusVariableReference; } else if (itemIndex.Value != null) { targetItemIndex = itemIndex.Value; } if (mainProcessor.PapyrusAssembly.VersionTarget == PapyrusVersionTargets.Skyrim) { if ((targetItemIndex as int?) > 128) { targetItemIndex = 128; } } if (itemArray.Value is PapyrusVariableReference) { targetItemArray = itemArray.Value as PapyrusVariableReference; } if (newValue.Value is PapyrusVariableReference) { targetItemValue = newValue.Value as PapyrusVariableReference; } else if (newValue.Value != null) { targetItemValue = newValue.Value; } return (ArrayUtility.ArrayOf( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.ArraySetElement, targetItemArray, targetItemIndex, targetItemValue))); //return "ArraySetElement " + tar + " " + oidx + " " + val; } } if (InstructionHelper.IsStoreLocalVariable(instruction.OpCode.Code) || InstructionHelper.IsStoreFieldObject(instruction.OpCode.Code)) { if (instruction.Operand is FieldReference) { var fref = instruction.Operand as FieldReference; // if the EvaluationStack.Count == 0 // The previous instruction might have been a call that returned a value // Something we did not store... if (mainProcessor.EvaluationStack.Count == 0 && InstructionHelper.IsCallMethod(instruction.Previous.OpCode.Code)) { // If previous was a call, then we should have the evaluation stack with at least one item. // But it seem like we don't... Inject tempvar? } if (mainProcessor.EvaluationStack.Count > 0) { var obj = mainProcessor.EvaluationStack.Pop(); var definedField = mainProcessor.PapyrusType.Fields.FirstOrDefault( f => f.Name.Value == "::" + fref.Name.Replace('<', '_').Replace('>', '_')); if (definedField == null) { definedField = mainProcessor.GetDelegateField(fref); } if (mainProcessor.EvaluationStack.Count > 0) { var nextObj = mainProcessor.EvaluationStack.Peek(); if (nextObj != null && nextObj.TypeName != null && nextObj.TypeName.Contains("#")) { // Store into Struct field. definedField = nextObj.Value as PapyrusFieldDefinition; var structPropName = fref.Name; mainProcessor.EvaluationStack.Pop(); // Just pop it so it does not interfere with any other instructions return (ArrayUtility.ArrayOf( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.StructSet, definedField, // location mainProcessor.CreateVariableReferenceFromName(structPropName), // Struct Property/Field Name obj.Value // value ))); } } if (definedField != null) { var structRef = obj.Value as PapyrusStructFieldReference; if (structRef != null) { // StructGet -> TempVar // Var <- TempVar var structSource = structRef.StructSource as PapyrusFieldDefinition; var structField = structRef.StructVariable; var fieldType = GetStructFieldType(asmCollection, structSource, structField); // 1. Create Temp Var bool isStructAccess; var tempVar = mainProcessor.GetTargetVariable(instruction, null, out isStructAccess, fieldType, true); // 2. StructGet -> tempVar // 3. Assign var <- tempVar return(ArrayUtility.ArrayOf( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.StructGet, mainProcessor.CreateVariableReferenceFromName(tempVar), structSource, structField), mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.Assign, definedField, mainProcessor.CreateVariableReferenceFromName(tempVar)))); } if (obj.Value is PapyrusParameterDefinition) { var varRef = obj.Value as PapyrusParameterDefinition; // definedField.FieldVariable = varRef.; // CreatePapyrusInstruction(PapyrusOpCode.Assign, definedField.Name.Value, varRef.Name.Value) return (ArrayUtility.ArrayOf( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.Assign, definedField, varRef))); } if (obj.Value is PapyrusVariableReference) { var varRef = obj.Value as PapyrusVariableReference; // definedField.Value = varRef.Value; definedField.DefaultValue = varRef; definedField.DefaultValue.Type = PapyrusPrimitiveType.Reference; // CreatePapyrusInstruction(PapyrusOpCode.Assign, definedField.Name.Value, varRef.Name.Value) if (varRef.IsDelegateReference) { return(new PapyrusInstruction[0]); } return (ArrayUtility.ArrayOf( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.Assign, definedField, varRef))); } //definedField.FieldVariable.Value = // Utility.TypeValueConvert(definedField.FieldVariable.TypeName.Value, obj.Value); var targetValue = valueTypeConverter.Convert(definedField.DefaultValue.TypeName.Value, obj.Value); return (ArrayUtility.ArrayOf( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.Assign, definedField, targetValue))); // definedField.FieldVariable.Value // "Assign " + definedField.Name + " " + definedField.Value; } } } var index = (int)mainProcessor.GetNumericValue(instruction); object outVal = null; if (index < allVariables.Count) { if (mainProcessor.EvaluationStack.Count > 0) { var heapObj = mainProcessor.EvaluationStack.Pop(); var structRef = heapObj.Value as PapyrusStructFieldReference; if (structRef != null) { // Grabbing value from struct var structSource = structRef.StructSource as PapyrusFieldDefinition; var structField = structRef.StructVariable; var fieldType = GetStructFieldType(asmCollection, structSource, structField); // 1. Create Temp Var bool isStructAccess; var tempVar = mainProcessor.GetTargetVariable(instruction, null, out isStructAccess, fieldType, true); // 2. StructGet -> tempVar // 3. Assign var <- tempVar return(ArrayUtility.ArrayOf( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.StructGet, mainProcessor.CreateVariableReferenceFromName(tempVar), structSource, structField), mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.Assign, allVariables[index], mainProcessor.CreateVariableReferenceFromName(tempVar)))); } if (heapObj.Value is PapyrusFieldDefinition) { heapObj.Value = (heapObj.Value as PapyrusFieldDefinition).DefaultValue; } if (heapObj.Value is PapyrusVariableReference) { var varRef = heapObj.Value as PapyrusVariableReference; allVariables[index].Value = allVariables[index].Name.Value; //varRef.Name.Value; // "Assign " + allVariables[(int)index].Name.Value + " " + varRef.Name.Value; return (ArrayUtility.ArrayOf( mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.Assign, allVariables[index], varRef))); } // allVariables[index].Value outVal = valueTypeConverter.Convert(allVariables[index].TypeName.Value, heapObj.Value); } var valout = outVal; //allVariables[index].Value; //if (valout is string) //{ // stringValue = valout.ToString(); //} if (valout is PapyrusFieldDefinition) { return (ArrayUtility.ArrayOf(mainProcessor.CreatePapyrusInstruction( PapyrusOpCodes.Assign, allVariables[index], valout as PapyrusFieldDefinition))); } if (valout is PapyrusVariableReference) { return (ArrayUtility.ArrayOf(mainProcessor.CreatePapyrusInstruction( PapyrusOpCodes.Assign, allVariables[index], valout as PapyrusVariableReference))); } if (valout is PapyrusParameterDefinition) { return (ArrayUtility.ArrayOf(mainProcessor.CreatePapyrusInstruction( PapyrusOpCodes.Assign, allVariables[index], valout as PapyrusParameterDefinition))); } // "Assign " + allVariables[(int)index].Name.Value + " " + valoutStr; if (valout == null) { valout = "None"; } if (allVariables[index].IsDelegateReference) { // If this is a delegate reference, then we do not want to assign this value to anything. return(new PapyrusInstruction[0]); } return (ArrayUtility.ArrayOf(mainProcessor.CreatePapyrusInstruction(PapyrusOpCodes.Assign, allVariables[index], valout))); } } return(new PapyrusInstruction[0]); }
/// <summary> /// Processes the conditional instruction. /// </summary> /// <param name="mainProcessor">The main instruction processor.</param> /// <param name="instruction">The instruction.</param> /// <param name="overrideOpCode">The override op code.</param> /// <param name="tempVariable">The temporary variable.</param> /// <returns></returns> public IEnumerable <PapyrusInstruction> Process( IClrInstructionProcessor mainProcessor, Instruction instruction, Code overrideOpCode = Code.Nop, string tempVariable = null) { bool isStructAccess; var output = new List <PapyrusInstruction>(); //cast = null; var heapStack = mainProcessor.EvaluationStack; // TODO: GetConditional only applies on Integers and must add support for Float further on. var papyrusOpCode = Utility.GetPapyrusMathOrEqualityOpCode( overrideOpCode != Code.Nop ? overrideOpCode : instruction.OpCode.Code, false); if (heapStack.Count >= 2) //Utility.GetStackPopCount(instruction.OpCode.StackBehaviourPop)) { var numeratorObject = heapStack.Pop(); var denumeratorObject = heapStack.Pop(); var vars = mainProcessor.PapyrusMethod.GetVariables(); int varIndex; object numerator; object denumerator; if (numeratorObject.Value is PapyrusFieldDefinition) { numeratorObject.Value = (numeratorObject.Value as PapyrusFieldDefinition).DefaultValue; } if (denumeratorObject.Value is PapyrusFieldDefinition) { denumeratorObject.Value = (denumeratorObject.Value as PapyrusFieldDefinition).DefaultValue; } if (numeratorObject.Value is PapyrusVariableReference) { var varRef = numeratorObject.Value as PapyrusVariableReference; var refTypeName = varRef.TypeName?.Value; if (refTypeName == null) { refTypeName = "Int"; } numerator = varRef; // if not int or string, we need to cast it. if (!refTypeName.ToLower().Equals("int") && !refTypeName.ToLower().Equals("system.int32") && !refTypeName.ToLower().Equals("system.string") && !refTypeName.ToLower().Equals("string")) { var typeVariable = mainProcessor.GetTargetVariable(instruction, null, out isStructAccess, "Int"); output.Add(mainProcessor.CreatePapyrusCastInstruction(typeVariable, varRef)); // cast = "Cast " + typeVariable + " " + value1; } } else if (numeratorObject.Value is FieldReference) { numerator = mainProcessor.CreateVariableReferenceFromName( (numeratorObject.Value as FieldReference).Name); } else { numerator = mainProcessor.CreateVariableReference( Utility.GetPrimitiveTypeFromValue(numeratorObject.Value), numeratorObject.Value); } if (denumeratorObject.Value is PapyrusVariableReference) { var varRef = denumeratorObject.Value as PapyrusVariableReference; var refTypeName = varRef.TypeName.Value; denumerator = varRef; // if not int or string, we need to cast it. if (!refTypeName.ToLower().Equals("int") && !refTypeName.ToLower().Equals("system.int32") && !refTypeName.ToLower().Equals("system.string") && !refTypeName.ToLower().Equals("string")) { // CAST BOOL TO INT // var typeVariable = GetTargetVariable(instruction, null, "Int"); // cast = "Cast " + typeVariable + " " + value2; var typeVariable = mainProcessor.GetTargetVariable(instruction, null, out isStructAccess, "Int"); output.Add(mainProcessor.CreatePapyrusCastInstruction(typeVariable, varRef)); } } else if (denumeratorObject.Value is FieldReference) { denumerator = mainProcessor.CreateVariableReferenceFromName( (denumeratorObject.Value as FieldReference).Name); } else { denumerator = mainProcessor.CreateVariableReference( Utility.GetPrimitiveTypeFromValue(denumeratorObject.Value), denumeratorObject.Value); } if (!string.IsNullOrEmpty(tempVariable)) { output.Add(mainProcessor.CreatePapyrusInstruction(papyrusOpCode, mainProcessor.CreateVariableReferenceFromName(tempVariable), denumerator, numerator)); return(output); } // if (Utility.IsGreaterThan(code) || Utility.IsLessThan(code)) { var next = instruction.Next; // If the next one is a switch, it most likely // means that we want to apply some mathematical stuff // on our constant value so that we can properly do an equality // comparison. if (InstructionHelper.IsSwitch(next.OpCode.Code)) { var newTempVariable = mainProcessor.GetTargetVariable(instruction, null, out isStructAccess, "Int", true); mainProcessor.SwitchConditionalComparer = mainProcessor.CreateVariableReferenceFromName(newTempVariable); mainProcessor.SwitchConditionalComparer.Type = PapyrusPrimitiveType.Reference; mainProcessor.SwitchConditionalComparer.TypeName = "Int".Ref(mainProcessor.PapyrusAssembly); output.Add(mainProcessor.CreatePapyrusInstruction(papyrusOpCode, mainProcessor.SwitchConditionalComparer, denumerator, numerator)); return(output); } while (next != null && !InstructionHelper.IsStoreLocalVariable(next.OpCode.Code) && !InstructionHelper.IsStoreFieldObject(next.OpCode.Code) && !InstructionHelper.IsCallMethod(next.OpCode.Code)) { next = next.Next; } if (next != null && next.Operand is MethodReference) { // if none found, create a temp one. var methodRef = next.Operand as MethodReference; var tVar = mainProcessor.CreateTempVariable( methodRef.MethodReturnType.ReturnType.FullName != "System.Void" ? methodRef.MethodReturnType.ReturnType.FullName : "System.int"); var targetVar = tVar; mainProcessor.EvaluationStack.Push(new EvaluationStackItem { Value = tVar.Value, TypeName = tVar.TypeName.Value }); output.Add(mainProcessor.CreatePapyrusInstruction(papyrusOpCode, targetVar, denumerator, numerator)); return(output); } if (next == null) { // No intentions to store this value into a variable, // Its to be used in a function call. //return "NULLPTR " + denumerator + " " + numerator; return(output); } mainProcessor.SkipToOffset = next.Offset; if (next.Operand is FieldReference) { var field = mainProcessor.GetFieldFromStfld(next); var structRef = field as PapyrusStructFieldReference; if (structRef != null) { // output.Add(mainInstructionProcessor.CreatePapyrusInstruction(papyrusOpCode, field, denumerator, numerator)); // structRef. } else if (field != null) { output.Add(mainProcessor.CreatePapyrusInstruction(papyrusOpCode, field, denumerator, numerator)); return(output); // LastSaughtTypeName = fieldData.TypeName; } //if (field != null) //{ // output.Add(mainInstructionProcessor.CreatePapyrusInstruction(papyrusOpCode, field, denumerator, numerator)); // return output; // //return field.Name + " " + denumerator + " " + numerator; //} } var numericValue = mainProcessor.GetNumericValue(next); varIndex = (int)numericValue; } output.Add(mainProcessor.CreatePapyrusInstruction(papyrusOpCode, vars[varIndex], denumerator, numerator)); //return vars[varIndex].Name + " " + denumerator + " " + numerator; } else if (mainProcessor.PapyrusCompilerOptions == PapyrusCompilerOptions.Strict) { throw new StackUnderflowException(); } return(output); }