Esempio n. 1
0
    static IEnumerable <LazyString> Impl_Starg_S(MethodInfo method, Instruction instruction)
    {
        var parameters = method.Definition.Parameters;
        var paramCount = parameters.Count;

        yield return(SetGlobal(Variables.Temporary, ArraySlice(
                                   GetGlobal(Variables.ParameterStack),
                                   () => "0",
                                   () => paramCount.ToString())));

        foreach (var action in ParameterStack.Pop(paramCount))
        {
            yield return(action);
        }

        foreach (var i in Enumerable.Range(0, paramCount))
        {
            var push = ParameterStack.Push(
                instruction.Operand == parameters[i] ?
                VariableStack.GetLastElement(0) :
                ArraySubscript(GetGlobal(Variables.Temporary), i));
            foreach (var action in push)
            {
                yield return(action);
            }
        }

        foreach (var action in VariableStack.Pop(1))
        {
            yield return(action);
        }
    }
Esempio n. 2
0
    Dictionary <OpCode, ToWorkshopActionFunc> CreateToWorkshopActionsDict()
    {
        var dict = new Dictionary <OpCode, ToWorkshopActionFunc>();

        // default opcode is for the skip chain (see InsertSkipChainInstructions)
        dict[OpCodes.No]            = Impl_SkipChainActions;
        dict[OpCodes.Nop]           = Impl_Nop;
        dict[OpCodes.Ldlen]         = Impl_UnimplementedOp;
        dict[OpCodes.Ldelema]       = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_I1]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_U1]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_I2]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_U2]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_I4]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_U4]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_I8]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_I]      = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_R4]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_R8]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_Ref]    = Impl_UnimplementedOp;
        dict[OpCodes.Stelem_I]      = Impl_UnimplementedOp;
        dict[OpCodes.Stelem_I1]     = Impl_UnimplementedOp;
        dict[OpCodes.Stelem_I2]     = Impl_UnimplementedOp;
        dict[OpCodes.Stelem_I4]     = Impl_UnimplementedOp;
        dict[OpCodes.Stelem_I8]     = Impl_UnimplementedOp;
        dict[OpCodes.Stelem_R4]     = Impl_UnimplementedOp;
        dict[OpCodes.Stelem_R8]     = Impl_UnimplementedOp;
        dict[OpCodes.Stelem_Ref]    = Impl_UnimplementedOp;
        dict[OpCodes.Ldelem_Any]    = Impl_UnimplementedOp;
        dict[OpCodes.Stelem_Any]    = Impl_UnimplementedOp;
        dict[OpCodes.Newarr]        = Impl_UnimplementedOp;
        dict[OpCodes.Box]           = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U_Un] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I_Un] = Impl_UnimplementedOp;
        dict[OpCodes.Cpobj]         = Impl_UnimplementedOp;
        dict[OpCodes.Ldobj]         = Impl_UnimplementedOp;
        dict[OpCodes.Ldstr]         = Impl_UnimplementedOp;
        dict[OpCodes.Newobj]        = Impl_UnimplementedOp;
        dict[OpCodes.Castclass]     = Impl_UnimplementedOp;
        dict[OpCodes.Isinst]        = Impl_UnimplementedOp;
        dict[OpCodes.Conv_R_Un]     = Impl_UnimplementedOp;
        dict[OpCodes.Unbox]         = Impl_UnimplementedOp;
        dict[OpCodes.Throw]         = Impl_UnimplementedOp;
        dict[OpCodes.Ldfld]         = Impl_UnimplementedOp;
        dict[OpCodes.Ldflda]        = Impl_UnimplementedOp;
        dict[OpCodes.Unbox_Any]     = Impl_UnimplementedOp;
        dict[OpCodes.Stfld]         = Impl_UnimplementedOp;
        dict[OpCodes.Ldsflda]       = Impl_UnimplementedOp;
        dict[OpCodes.Stsfld]        = (method, instruction) => new[]
        {
            SetGlobalAtIndex(Variables.StaticFields, GetStaticFieldIndex(instruction.Operand), VariableStack.GetLastElement(0))
        }.Concat(VariableStack.Pop(1));

        dict[OpCodes.Stobj]          = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I1_Un] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I2_Un] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I4_Un] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I8_Un] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U1_Un] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U2_Un] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U4_Un] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U8_Un] = Impl_UnimplementedOp;

        dict[OpCodes.Ldsfld] = (method, instruction) =>
        {
            var index = GetStaticFieldIndex(instruction.Operand);
            return(VariableStack.Push(ArraySubscript(GetGlobal(Variables.StaticFields), () => index.ToString())));
        };

        dict[OpCodes.Callvirt]    = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I1] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I2] = Impl_UnimplementedOp;
        dict[OpCodes.Cgt_Un]      = Impl_UnimplementedOp;
        dict[OpCodes.Clt]         = Impl_UnimplementedOp;
        dict[OpCodes.Clt_Un]      = Impl_UnimplementedOp;
        dict[OpCodes.Ldftn]       = Impl_UnimplementedOp;
        dict[OpCodes.Ldvirtftn]   = Impl_UnimplementedOp;
        dict[OpCodes.Ldarg]       = Impl_UnimplementedOp;
        dict[OpCodes.Ldarga]      = Impl_UnimplementedOp;
        dict[OpCodes.Starg]       = Impl_UnimplementedOp;
        dict[OpCodes.Ldloc]       = Impl_UnimplementedOp;
        dict[OpCodes.Ldloca]      = Impl_UnimplementedOp;
        dict[OpCodes.Stloc]       = Impl_UnimplementedOp;
        dict[OpCodes.Localloc]    = Impl_UnimplementedOp;
        dict[OpCodes.Endfilter]   = Impl_UnimplementedOp;
        dict[OpCodes.Unaligned]   = Impl_UnimplementedOp;
        dict[OpCodes.Volatile]    = Impl_UnimplementedOp;
        dict[OpCodes.Tail]        = Impl_UnimplementedOp;
        dict[OpCodes.Initobj]     = Impl_UnimplementedOp;
        dict[OpCodes.Constrained] = Impl_UnimplementedOp;
        dict[OpCodes.Cpblk]       = Impl_UnimplementedOp;
        dict[OpCodes.Initblk]     = Impl_UnimplementedOp;
        dict[OpCodes.Rethrow]     = Impl_UnimplementedOp;
        dict[OpCodes.Sizeof]      = Impl_UnimplementedOp;
        dict[OpCodes.Cgt]         = Impl_UnimplementedOp;
        dict[OpCodes.Ceq]         = Impl_UnimplementedOp;
        dict[OpCodes.Arglist]     = Impl_UnimplementedOp;
        dict[OpCodes.Conv_U]      = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U2] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I4] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U4] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I8] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U8] = Impl_UnimplementedOp;
        dict[OpCodes.Refanyval]   = Impl_UnimplementedOp;
        dict[OpCodes.Ckfinite]    = Impl_UnimplementedOp;
        dict[OpCodes.Mkrefany]    = Impl_UnimplementedOp;
        dict[OpCodes.Ldtoken]     = Impl_UnimplementedOp;
        dict[OpCodes.Conv_U2]     = Impl_UnimplementedOp;
        dict[OpCodes.Conv_U1]     = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U1] = Impl_UnimplementedOp;
        dict[OpCodes.Conv_I]      = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_U]  = Impl_UnimplementedOp;
        dict[OpCodes.Add_Ovf]     = Impl_UnimplementedOp;
        dict[OpCodes.Add_Ovf_Un]  = Impl_UnimplementedOp;
        dict[OpCodes.Mul_Ovf]     = Impl_UnimplementedOp;
        dict[OpCodes.Mul_Ovf_Un]  = Impl_UnimplementedOp;
        dict[OpCodes.Sub_Ovf]     = Impl_UnimplementedOp;
        dict[OpCodes.Sub_Ovf_Un]  = Impl_UnimplementedOp;
        dict[OpCodes.Endfinally]  = Impl_UnimplementedOp;
        dict[OpCodes.Leave]       = Impl_UnimplementedOp;
        dict[OpCodes.Leave_S]     = Impl_UnimplementedOp;
        dict[OpCodes.Stind_I]     = Impl_UnimplementedOp;
        dict[OpCodes.Conv_Ovf_I]  = Impl_UnimplementedOp;
        dict[OpCodes.Refanytype]  = Impl_UnimplementedOp;
        dict[OpCodes.Conv_U8]     = Impl_UnimplementedOp;
        dict[OpCodes.Conv_R8]     = Impl_UnimplementedOp;
        dict[OpCodes.Ldc_I4_7]    = Impl_UnimplementedOp;
        dict[OpCodes.Ldc_I4_8]    = Impl_UnimplementedOp;
        dict[OpCodes.Ldc_I4_S]    = (method, instruction) => VariableStack.Push(() => ((System.SByte)instruction.Operand).ToString());
        dict[OpCodes.Ldc_I4]      = (method, instruction) => VariableStack.Push(() => ((int)instruction.Operand).ToString());
        dict[OpCodes.Ldc_I8]      = Impl_UnimplementedOp;
        dict[OpCodes.Ldc_R4]      = (method, instruction) => VariableStack.Push(() => ((float)instruction.Operand).ToString());
        dict[OpCodes.Ldc_R8]      = (method, instruction) => VariableStack.Push(() => ((double)instruction.Operand).ToString());
        dict[OpCodes.Dup]         = (method, instruction) => VariableStack.Push(VariableStack.GetLastElement(0));
        dict[OpCodes.Pop]         = (method, instruction) => VariableStack.Pop(1);
        dict[OpCodes.Jmp]         = Impl_UnimplementedOp;
        dict[OpCodes.Call]        = Impl_Call;
        dict[OpCodes.Calli]       = Impl_UnimplementedOp;

        dict[OpCodes.Ret] = (method, instruction) => CallStack.Pop(1).
                            // if it's a workshop event, then it needs the max num of local variables (since it's called at runtime)
                            Concat(LocalsStack.Pop(GetCustomAttributeData <WorkshopEventAttribute>(method) != null ? m_maxNumLocalVariables : GetNumLocalVariables(method.Definition))).
                            Concat(ParameterStack.Pop(method.Definition.Parameters.Count)).
                            // (loop instead of abort so you can call functions recursively)
                            Concat(new LazyString[] { () => "Loop;" });

        dict[OpCodes.Br_S] = (method, instruction) => Impl_Jump_If(method, instruction, 0, () => "True");

        dict[OpCodes.Brfalse_S] = (method, instruction) => Impl_Jump_If(method, instruction, 1, Equal(ArraySubscript(GetGlobal(Variables.Temporary), () => "0"), () => "0"));
        dict[OpCodes.Brtrue_S]  = (method, instruction) => Impl_Jump_If(method, instruction, 1, NotEqual(ArraySubscript(GetGlobal(Variables.Temporary), () => "0"), () => "0"));

        dict[OpCodes.Beq_S] = (method, instruction) => Impl_Jump_If_Compare(method, instruction, "==");
        dict[OpCodes.Bge_S] = (method, instruction) => Impl_Jump_If_Compare(method, instruction, ">=");
        dict[OpCodes.Bgt_S] = (method, instruction) => Impl_Jump_If_Compare(method, instruction, ">");
        dict[OpCodes.Ble_S] = (method, instruction) => Impl_Jump_If_Compare(method, instruction, "<=");
        dict[OpCodes.Blt_S] = (method, instruction) => Impl_Jump_If_Compare(method, instruction, "<");

        dict[OpCodes.Bne_Un_S] = (method, instruction) => Impl_Jump_If(method, instruction, NotEqual);
        dict[OpCodes.Bge_Un_S] = dict[OpCodes.Bge_S];

        dict[OpCodes.Ldc_I4_6] = Impl_UnimplementedOp;
        dict[OpCodes.Ldc_I4_5] = (method, Instruction) => VariableStack.Push(() => "5");
        dict[OpCodes.Ldc_I4_4] = Impl_UnimplementedOp;
        dict[OpCodes.Ldc_I4_3] = Impl_UnimplementedOp;
        dict[OpCodes.Break]    = Impl_UnimplementedOp;

        dict[OpCodes.Ldarg_0] = (method, instruction) =>
                                VariableStack.Push(ParameterStack.GetLastElement(method.Definition.Parameters.Count - 1));
        dict[OpCodes.Ldarg_1] = (method, instruction) =>
                                VariableStack.Push(ParameterStack.GetLastElement(method.Definition.Parameters.Count - 2));
        dict[OpCodes.Ldarg_2] = (method, instruction) =>
                                VariableStack.Push(ParameterStack.GetLastElement(method.Definition.Parameters.Count - 3));
        dict[OpCodes.Ldarg_3] = (method, instruction) =>
                                VariableStack.Push(ParameterStack.GetLastElement(method.Definition.Parameters.Count - 4));

        dict[OpCodes.Ldloc_0]   = (method, instruction) => VariableStack.Push(LocalsStack.GetLastElement(GetLocalVariableStackOffset(method, 0)));
        dict[OpCodes.Ldloc_1]   = (method, instruction) => VariableStack.Push(LocalsStack.GetLastElement(GetLocalVariableStackOffset(method, 1)));
        dict[OpCodes.Ldloc_2]   = (method, instruction) => VariableStack.Push(LocalsStack.GetLastElement(GetLocalVariableStackOffset(method, 2)));
        dict[OpCodes.Ldloc_3]   = (method, instruction) => VariableStack.Push(LocalsStack.GetLastElement(GetLocalVariableStackOffset(method, 3)));
        dict[OpCodes.Stloc_0]   = (method, instruction) => Impl_Stloc(method, 0);
        dict[OpCodes.Stloc_1]   = (method, instruction) => Impl_Stloc(method, 1);
        dict[OpCodes.Bgt_Un_S]  = Impl_UnimplementedOp;
        dict[OpCodes.Stloc_2]   = (method, instruction) => Impl_Stloc(method, 2);
        dict[OpCodes.Ldarg_S]   = Impl_UnimplementedOp;
        dict[OpCodes.Ldarga_S]  = Impl_UnimplementedOp;
        dict[OpCodes.Starg_S]   = Impl_Starg_S;
        dict[OpCodes.Ldloc_S]   = (method, instruction) => VariableStack.Push(LocalsStack.GetLastElement(GetLocalVariableStackOffset(method, ((VariableDefinition)instruction.Operand).Index)));
        dict[OpCodes.Ldloca_S]  = Impl_UnimplementedOp;
        dict[OpCodes.Stloc_S]   = (method, instruction) => Impl_Stloc(method, ((VariableDefinition)instruction.Operand).Index);
        dict[OpCodes.Ldnull]    = Impl_UnimplementedOp;
        dict[OpCodes.Ldc_I4_M1] = Impl_UnimplementedOp;
        dict[OpCodes.Ldc_I4_0]  = (method, instruction) => VariableStack.Push(() => "0");
        dict[OpCodes.Ldc_I4_1]  = (method, instruction) => VariableStack.Push(() => "1");
        dict[OpCodes.Ldc_I4_2]  = (method, Instruction) => VariableStack.Push(() => "2");
        dict[OpCodes.Stloc_3]   = (method, instruction) => Impl_Stloc(method, 3);
        dict[OpCodes.Conv_U4]   = Impl_UnimplementedOp;
        dict[OpCodes.Ble_Un_S]  = (method, instruction) => Impl_Jump_If_Compare(method, instruction, "<=");
        dict[OpCodes.Br]        = (method, instruction) => Impl_Jump_If(method, instruction, 0, () => "True");
        dict[OpCodes.Stind_I8]  = Impl_UnimplementedOp;
        dict[OpCodes.Stind_R4]  = Impl_UnimplementedOp;
        dict[OpCodes.Stind_R8]  = Impl_UnimplementedOp;

        dict[OpCodes.Add]       = (method, instruction) => DoBinaryOp(Add);
        dict[OpCodes.Sub]       = (method, instruction) => DoBinaryOp(Subtract);
        dict[OpCodes.Mul]       = (method, instruction) => DoBinaryOp(Mul);
        dict[OpCodes.Div]       = (method, instruction) => DoBinaryOp(Div);
        dict[OpCodes.Div_Un]    = Impl_UnimplementedOp;
        dict[OpCodes.Rem]       = (method, instruction) => DoBinaryOp(Mod);
        dict[OpCodes.Rem_Un]    = Impl_UnimplementedOp;
        dict[OpCodes.And]       = (method, instruction) => DoBinaryOp(And);
        dict[OpCodes.Or]        = (method, instruction) => DoBinaryOp(Or);
        dict[OpCodes.Xor]       = Impl_UnimplementedOp;
        dict[OpCodes.Shl]       = Impl_UnimplementedOp;
        dict[OpCodes.Shr]       = Impl_UnimplementedOp;
        dict[OpCodes.Shr_Un]    = Impl_UnimplementedOp;
        dict[OpCodes.Neg]       = Impl_UnimplementedOp;
        dict[OpCodes.Not]       = Impl_UnimplementedOp;
        dict[OpCodes.Conv_I1]   = Impl_UnimplementedOp;
        dict[OpCodes.Conv_I2]   = Impl_UnimplementedOp;
        dict[OpCodes.Conv_I4]   = Impl_UnimplementedOp;
        dict[OpCodes.Conv_I8]   = Impl_UnimplementedOp;
        dict[OpCodes.Conv_R4]   = Impl_Nop; // shouldn't need to convert int to real
        dict[OpCodes.Stind_I4]  = Impl_UnimplementedOp;
        dict[OpCodes.Stind_I2]  = Impl_UnimplementedOp;
        dict[OpCodes.Stind_I1]  = Impl_UnimplementedOp;
        dict[OpCodes.Stind_Ref] = Impl_UnimplementedOp;

        dict[OpCodes.Brfalse] = (method, instruction) => dict[OpCodes.Brfalse_S](method, instruction);
        dict[OpCodes.Brtrue]  = (method, instruction) => dict[OpCodes.Brtrue_S](method, instruction);

        dict[OpCodes.Beq]       = Impl_UnimplementedOp;
        dict[OpCodes.Bge]       = Impl_UnimplementedOp;
        dict[OpCodes.Bgt]       = Impl_UnimplementedOp;
        dict[OpCodes.Ble]       = Impl_UnimplementedOp;
        dict[OpCodes.Blt]       = (method, instruction) => Impl_Jump_If_Compare(method, instruction, "<");
        dict[OpCodes.Bne_Un]    = Impl_UnimplementedOp;
        dict[OpCodes.Bge_Un]    = Impl_UnimplementedOp;
        dict[OpCodes.Bgt_Un]    = Impl_UnimplementedOp;
        dict[OpCodes.Ble_Un]    = Impl_UnimplementedOp;
        dict[OpCodes.Blt_Un_S]  = (method, instruction) => Impl_Jump_If_Compare(method, instruction, "<");
        dict[OpCodes.Blt_Un]    = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_I1]  = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_U1]  = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_I2]  = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_U2]  = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_I4]  = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_U4]  = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_I8]  = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_I]   = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_R4]  = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_R8]  = Impl_UnimplementedOp;
        dict[OpCodes.Ldind_Ref] = Impl_UnimplementedOp;
        dict[OpCodes.Switch]    = Impl_UnimplementedOp;
        dict[OpCodes.Readonly]  = Impl_UnimplementedOp;

        return(dict);
    }