示例#1
0
文件: ILOp.cs 项目: Zino2201/Cosmos
        /// <summary>
        /// Emits cleanup code for when an exception occurred inside a method call.
        /// </summary>
        public static void EmitExceptionCleanupAfterCall(Assembler.Assembler aAssembler, uint aReturnSize, uint aStackSizeBeforeCall, uint aTotalArgumentSizeOfMethod)
        {
            XS.Comment("aStackSizeBeforeCall = " + aStackSizeBeforeCall);
              XS.Comment("aTotalArgumentSizeOfMethod = " + aTotalArgumentSizeOfMethod);
              XS.Comment("aReturnSize = " + aReturnSize);

              if (aReturnSize != 0)
              {
            // at least pop return size:
            XS.Comment("Cleanup return");

            // cleanup result values
            for (int i = 0; i < aReturnSize / 4; i++)
            {
              XS.Add(XSRegisters.ESP, 4);
            }
              }

              if (aStackSizeBeforeCall > (aTotalArgumentSizeOfMethod))
              {
            if (aTotalArgumentSizeOfMethod > 0)
            {
              var xExtraStack = aStackSizeBeforeCall - aTotalArgumentSizeOfMethod;
              XS.Comment("Cleanup extra stack");

              // cleanup result values
              for (int i = 0; i < xExtraStack / 4; i++)
              {
            XS.Add(XSRegisters.ESP, 4);
              }
            }
              }
        }
示例#2
0
    static void Main(string[] aArgs) {
      try {
        string xSrc = aArgs[0];

        var xGenerator = new AsmGenerator();

        //string[] xFiles;
        //if (Directory.Exists(xSrc))
        //{
        //  xFiles = Directory.GetFiles(xSrc, "*.xs");
        //}
        //else
        //{
        //  xFiles = new string[] { xSrc };
        //}
        //foreach (var xFile in xFiles)
        //{
        //  xGenerator.GenerateToFiles(xFile);
        //}

        var xAsm = new Assembler();
        var xStreamReader = new StringReader(@"namespace Test
            while byte ESI[0] != 0 {
              ! nop
            }
            ");
        var xResult = xGenerator.Generate(xStreamReader);
        Console.WriteLine("done");
      } catch (Exception ex) {
        Console.WriteLine(ex.ToString());
        Environment.Exit(1);
      }
    }
示例#3
0
    /// <summary>Parse the input X# source code file and generate the matching target assembly
    /// language.</summary>
    /// <param name="aReader">X# source code reader.</param>
    /// <returns>The resulting target assembler content. The returned object contains
    /// a code and a data block.</returns>
    public Assembler Generate(TextReader aReader)
    {
      if (aReader == null)
      {
        throw new ArgumentNullException(nameof(aReader));
      }
      mPatterns.EmitUserComments = EmitUserComments;
      mLineNo = 0;
      var xResult = new Assembler();
      try
      {
        // Read one X# source code line at a time and process it.
        while (true)
        {
          mLineNo++;
          string xLine = aReader.ReadLine();
          if (xLine == null)
          {
            break;
          }

          ProcessLine(xLine, mLineNo);
        }
        AssertLastFunctionComplete();
        return xResult;
      }
      finally
      {
        Assembler.ClearCurrentInstance();
      }
    }
示例#4
0
文件: Comment.cs 项目: Orvid/Cosmos
 public Comment( Assembler aAssembler, string aText )
     : base() //HACK
 {
   if (aText.StartsWith(";")) {
     aText = aText.TrimStart(';').TrimStart();
   }
   Text = String.Intern(aText);
 }
示例#5
0
    public static void Assemble(Assembler.Assembler aAssembler, uint aElementSize, MethodInfo aMethod, ILOpCode aOpCode, bool debugEnabled)
    {
      // stack     == the new value
      // stack + 1 == the index
      // stack + 2 == the array
      DoNullReferenceCheck(aAssembler, debugEnabled, (int)(8 + Align(aElementSize, 4)));

      uint xStackSize = aElementSize;
      if (xStackSize % 4 != 0)
      {
        xStackSize += 4 - xStackSize % 4;
      }

      // calculate element offset into array memory (including header)
      XS.Set(XSRegisters.EAX, XSRegisters.ESP, sourceDisplacement: (int)xStackSize); // the index
      XS.Set(XSRegisters.EDX, aElementSize);
      XS.Multiply(XSRegisters.EDX);
      XS.Add(XSRegisters.EAX, ObjectImpl.FieldDataOffset + 4);

      XS.Set(XSRegisters.EDX, XSRegisters.ESP, sourceDisplacement: (int)xStackSize + 8); // the array
      XS.Add(XSRegisters.EDX, XSRegisters.EAX);
      XS.Push(XSRegisters.EDX);

      XS.Pop(XSRegisters.ECX);
      for (int i = (int)(aElementSize / 4) - 1; i >= 0; i -= 1)
      {
        new Comment(aAssembler, "Start 1 dword");
        XS.Pop(XSRegisters.EBX);
        XS.Set(XSRegisters.ECX, XSRegisters.EBX, destinationIsIndirect: true);
        XS.Add(XSRegisters.ECX, 4);
      }
      switch (aElementSize % 4)
      {
        case 1:
          {
            new Comment(aAssembler, "Start 1 byte");
            XS.Pop(XSRegisters.EBX);
            XS.Set(XSRegisters.ECX, XSRegisters.BL, destinationIsIndirect: true);
            break;
          }
        case 2:
          {
            new Comment(aAssembler, "Start 1 word");
            XS.Pop(XSRegisters.EBX);
            XS.Set(XSRegisters.ECX, XSRegisters.BX, destinationIsIndirect: true);
            break;
          }
        case 0:
          {
            break;
          }
        default:
          throw new Exception("Remainder size " + (aElementSize % 4) + " not supported!");

      }
      XS.Add(XSRegisters.ESP, 12);
    }
示例#6
0
    private void DoExecute(Assembler.Assembler assembler, MethodInfo aMethod, ILOpCode aOpCode, OpType aTargetType, bool debugEnabled)
    {
      new Comment(assembler, $"Type = {aTargetType.Value}");
      if (aTargetType.Value.BaseType == typeof(ValueType))
      {

      }
      else if (aTargetType.Value.BaseType == typeof(object))
      {
        throw new NotImplementedException($"Constrained not implemented for {aTargetType.Value}");
      }
    }
示例#7
0
        private void DoExecute(Assembler.Assembler assembler, MethodInfo aMethod, ILOpCode aOpCode, OpType aTargetType, bool debugEnabled)
        {
            // If thisType is a reference type (as opposed to a value type) then
            //     ptr is dereferenced and passed as the ‘this’ pointer to the callvirt of method
            // If thisType is a value type and thisType implements method then
            //     ptr is passed unmodified as the ‘this’ pointer to a call of method implemented by thisType
            // If thisType is a value type and thisType does not implement method then
            //     ptr is dereferenced, boxed, and passed as the ‘this’ pointer to the callvirt of method

            new Comment(assembler, $"Type = {aTargetType.Value}");
            if (aTargetType.Value.BaseType == typeof (ValueType))
            {
                
            }
            else if (aTargetType.Value.BaseType == typeof (object))
            {
                throw new NotImplementedException($"Constrained not implemented for {aTargetType.Value}");
            }
        }
示例#8
0
文件: ILOp.cs 项目: Zino2201/Cosmos
 public static void DoNullReferenceCheck(Assembler.Assembler assembler, bool debugEnabled, uint stackOffsetToCheck)
 {
     if (stackOffsetToCheck != Align(stackOffsetToCheck, 4))
       {
     throw new Exception("Stack offset not aligned!");
       }
       if (debugEnabled)
       {
     new CPU.Compare {DestinationReg = CPU.RegistersEnum.ESP, DestinationDisplacement = (int) stackOffsetToCheck, DestinationIsIndirect = true, SourceValue = 0};
     XS.Jump(CPU.ConditionalTestEnum.NotEqual, ".AfterNullCheck");
     XS.ClearInterruptFlag();
     // don't remove the call. It seems pointless, but we need it to retrieve the EIP value
     XS.Call(".NullCheck_GetCurrAddress");
     XS.Label(".NullCheck_GetCurrAddress");
     XS.Pop(XSRegisters.EAX);
     new CPU.Mov {DestinationRef = ElementReference.New("DebugStub_CallerEIP"), DestinationIsIndirect = true, SourceReg = CPU.RegistersEnum.EAX};
     XS.Call("DebugStub_SendNullReferenceOccurred");
     XS.Halt();
     XS.Label(".AfterNullCheck");
       }
 }
示例#9
0
        public static void DoExecute(Cosmos.Assembler.Assembler Assembler, Type aDeclaringType, string xFieldId, bool aDerefExternalField, bool debugEnabled, Type aTypeOnStack)
        {
            var xOffset    = GetFieldOffset(aDeclaringType, xFieldId);
            var xFields    = GetFieldsInfo(aDeclaringType, false);
            var xFieldInfo = (from item in xFields
                              where item.Id == xFieldId
                              select item).Single();

            XS.Comment("Field: " + xFieldInfo.Id);
            XS.Comment("Type: " + xFieldInfo.FieldType.ToString());
            XS.Comment("Size: " + xFieldInfo.Size);
            XS.Comment("DeclaringType: " + aDeclaringType.FullName);
            XS.Comment("TypeOnStack: " + aTypeOnStack.FullName);
            XS.Comment("Offset: " + xOffset + " (includes object header)");

            if (aDeclaringType.IsValueType && aTypeOnStack == aDeclaringType)
            {
                #region Read struct value from stack

                // This is a 3-step process
                // 1. Move the actual value below the stack (negative to ESP)
                // 2. Move the value at the right spot of the stack (positive to stack)
                // 3. Adjust stack to remove the struct
                //
                // This is necessary, as the value could otherwise overwrite the struct too soon.

                var xTypeStorageSize  = GetStorageSize(aDeclaringType);
                var xFieldStorageSize = xFieldInfo.Size;

                // Step 1, Move the actual value below the stack (negative to ESP)
                CopyValue(ESP, -(int)xFieldStorageSize, ESP, xOffset, xFieldStorageSize);

                // Step 2 Move the value at the right spot of the stack (positive to stack)
                var xStackOffset = (int)(Align(xTypeStorageSize, 4) - xFieldStorageSize);
                CopyValue(ESP, xStackOffset, ESP, -(int)xFieldStorageSize, xFieldStorageSize);

                // Step 3 Adjust stack to remove the struct
                XS.Add(ESP, Align((uint)(xStackOffset), 4));

                #endregion Read struct value from stack
                return;
            }

            // pushed size is always 4 or 8
            var xSize = xFieldInfo.Size;
            if (TypeIsReferenceType(aTypeOnStack))
            {
                DoNullReferenceCheck(Assembler, debugEnabled, 4);
                XS.Add(ESP, 4);
            }
            else
            {
                DoNullReferenceCheck(Assembler, debugEnabled, 0);
            }
            XS.Pop(ECX);

            XS.Add(ECX, (uint)(xOffset));

            if (xFieldInfo.IsExternalValue && aDerefExternalField)
            {
                XS.Set(ECX, ECX, sourceIsIndirect: true);
            }

            for (int i = 1; i <= (xSize / 4); i++)
            {
                XS.Set(EAX, ECX, sourceDisplacement: (int)(xSize - (i * 4)));
                XS.Push(EAX);
            }

            XS.Set(EAX, 0);

            switch (xSize % 4)
            {
            case 1:
                XS.Set(AL, ECX, sourceIsIndirect: true);
                XS.Push(EAX);
                break;

            case 2:
                XS.Set(AX, ECX, sourceIsIndirect: true);
                XS.Push(EAX);
                break;

            case 3:     //For Release
                XS.Set(EAX, ECX, sourceIsIndirect: true);
                XS.ShiftRight(EAX, 8);
                XS.Push(EAX);
                break;

            case 0:
            {
                break;
            }

            default:
                throw new Exception(string.Format("Remainder size {0} {1:D} not supported!", xFieldInfo.FieldType.ToString(), xSize));
            }
        }
示例#10
0
 public Ldelem_Ref(Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
 public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo)
 {
     XS.EnableInterrupts();
 }
示例#12
0
 public abstract bool IsComplete(Assembler aAssembler);
示例#13
0
 public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo)
 {
   Exchange(BX, BX);
 }
示例#14
0
文件: Shr_Un.cs 项目: invisal/Cosmos
 public Shr_Un(Cosmos.Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
示例#15
0
文件: Comment.cs 项目: Orvid/Cosmos
 public override void UpdateAddress( Assembler aAssembler, ref ulong aAddress )
 {
     base.UpdateAddress( aAssembler, ref aAddress );
 }
示例#16
0
        public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo)
        {
            var xAssembler = aAssembler;
            var xMethodInfo = (MethodInfo) aMethodInfo;
            var xMethodBaseAsInfo = xMethodInfo.MethodBase as global::System.Reflection.MethodInfo;
            if (xMethodBaseAsInfo.ReturnType != typeof(void))
            {
                throw new Exception("Events with return type not yet supported!");
            }

            /*
            * EAX contains the GetInvocationList() array at the index at which it was last used
            * EDX contains the index at which the EAX is
            * EBX contains the number of items in the array
            * ECX contains the argument size
            */

            XS.ClearInterruptFlag();

            XS.Comment("Get Invoke list count");
            var xGetInvocationListMethod = typeof(MulticastDelegate).GetMethod("GetInvocationList");
            Ldarg.DoExecute(aAssembler, xMethodInfo, 0);
            XS.Call(LabelName.Get(xGetInvocationListMethod));
            XS.Add(ESP, 4);
            XS.Pop(EAX);
            XS.Add(EAX, 8);
            XS.Set(EBX, EAX, sourceIsIndirect: true);

            XS.Comment("Get invoke method");
            XS.Add(EAX, 8);
            XS.Set(EDI, EAX, sourceIsIndirect: true, sourceDisplacement: 4);

            XS.Comment("Get ArgSize");
            int xArgSizeOffset = Ldfld.GetFieldOffset(typeof(global::System.Delegate), "$$ArgSize$$");
            Ldarg.DoExecute(aAssembler, xMethodInfo, 0);
            XS.Add(ESP, 4);
            XS.Pop(ECX);
            XS.Add(ECX, (uint) xArgSizeOffset);
            XS.Set(ECX, ECX, sourceIsIndirect: true);

            XS.Comment("Set current invoke list index");
            XS.Set(EDX, 0);

            XS.Label(".BEGIN_OF_LOOP");
            {
                XS.Compare(EDX, EBX);
                XS.Jump(Assembler.x86.ConditionalTestEnum.GreaterThanOrEqualTo, ".END_OF_INVOKE");

                XS.PushAllRegisters();

                XS.Comment("Check if delegate has $this");
                XS.Set(EDI, EBP, sourceDisplacement: Ldarg.GetArgumentDisplacement(xMethodInfo, 0));
                XS.Add(EDI, 4);
                XS.Set(EDI, EDI, sourceDisplacement: Ldfld.GetFieldOffset(xMethodInfo.MethodBase.DeclaringType, "System.Object System.Delegate._target"));
                XS.Compare(EDI, 0);
                XS.Jump(Assembler.x86.ConditionalTestEnum.Zero, ".NO_THIS");
                XS.Label(".HAS_THIS");
                XS.Push(EDI);
                XS.Push(0);
                XS.Label(".NO_THIS");
                XS.Set(EDI, EAX, sourceIsIndirect: true, sourceDisplacement: 4);
                XS.Set(EDI, EDI, sourceDisplacement: Ldfld.GetFieldOffset(xMethodInfo.MethodBase.DeclaringType, "System.IntPtr System.Delegate._methodPtr"));

                XS.Comment("Check if delegate has args");
                XS.Compare(ECX, 0);
                XS.Jump(Assembler.x86.ConditionalTestEnum.Zero, ".NO_ARGS");
                XS.Label(".HAS_ARGS");
                XS.Sub(ESP, ECX);
                XS.Push(EDI);
                XS.Set(EDI, ESP);
                XS.Add(EDI, 4);
                XS.Set(ESI, EBP);
                XS.Add(ESI, 8);
                new Assembler.x86.Movs { Size = 8, Prefixes = Assembler.x86.InstructionPrefixes.Repeat };
                XS.Pop(EDI);
                XS.Label(".NO_ARGS");
                XS.Call(EDI);

                XS.PopAllRegisters();
                XS.Increment(EDX);
                XS.Jump(".BEGIN_OF_LOOP");
            }

            XS.Label(".END_OF_INVOKE");
            XS.Set(EDX, EBP, sourceDisplacement: Ldarg.GetArgumentDisplacement(xMethodInfo, 0));
            XS.Set(EDX, EDX, sourceDisplacement: Ldfld.GetFieldOffset(xMethodInfo.MethodBase.DeclaringType, "$$ReturnsValue$$"));
            XS.Compare(EDX, 0);
            XS.Jump(Assembler.x86.ConditionalTestEnum.Equal, ".NO_RETURN");

            XS.Label(".HAS_RETURN");
            XS.Exchange(EBP, EDX, destinationDisplacement: 8);
            XS.Exchange(EBP, EDX, destinationDisplacement: 4);
            XS.Exchange(EBP, EDX, destinationIsIndirect: true);
            XS.Push(EDX);
            XS.Set(ESP, EDI, destinationDisplacement: 12);

            XS.Label(".NO_RETURN");
            XS.EnableInterrupts();
        }
示例#17
0
文件: Callvirt.cs 项目: fanoI/Cosmos
        public static void DoExecute(Assembler.Assembler Assembler, MethodInfo aMethod, MethodBase aTargetMethod, uint aTargetMethodUID, ILOpCode aOp, bool debugEnabled)
        {
            string xCurrentMethodLabel = GetLabel(aMethod, aOp.Position);
            Type xPopType = aOp.StackPopTypes.Last();

            string xNormalAddress = "";
            if (aTargetMethod.IsStatic || !aTargetMethod.IsVirtual || aTargetMethod.IsFinal)
            {
                xNormalAddress = LabelName.Get(aTargetMethod);
            }

            uint xReturnSize = 0;
            var xMethodInfo = aTargetMethod as SysReflection.MethodInfo;
            if (xMethodInfo != null)
            {
                xReturnSize = Align(SizeOfType(xMethodInfo.ReturnType), 4);
            }

            uint xExtraStackSize = Call.GetStackSizeToReservate(aTargetMethod, xPopType);
            uint xThisOffset = 0;
            var xParameters = aTargetMethod.GetParameters();
            foreach (var xItem in xParameters)
            {
                xThisOffset += Align(SizeOfType(xItem.ParameterType), 4);
            }

            // This is finding offset to self? It looks like we dont need offsets of other
            // arguments, but only self. If so can calculate without calculating all fields
            // Might have to go to old data structure for the offset...
            // Can we add this method info somehow to the data passed in?
            // mThisOffset = mTargetMethodInfo.Arguments[0].Offset;

            XS.Comment("ThisOffset = " + xThisOffset);

            if (TypeIsReferenceType(xPopType))
            {
                DoNullReferenceCheck(Assembler, debugEnabled, (int)xThisOffset + 4);
            }
            else
            {
                DoNullReferenceCheck(Assembler, debugEnabled, (int)xThisOffset);
            }

            if (!String.IsNullOrEmpty(xNormalAddress))
            {
                if (xExtraStackSize > 0)
                {
                    XS.Sub(ESP, xExtraStackSize);
                }
                XS.Call(xNormalAddress);
            }
            else
            {
                /*
                * On the stack now:
                * $esp                 Params
                * $esp + mThisOffset   This
                */
                if ((xPopType.IsPointer) || (xPopType.IsByRef))
                {
                    xPopType = xPopType.GetElementType();
                    string xTypeId = GetTypeIDLabel(xPopType);
                    XS.Push(xTypeId, isIndirect: true);
                }
                else
                {
                    XS.Set(EAX, ESP, sourceDisplacement: (int)xThisOffset + 4);
                    XS.Push(EAX, isIndirect: true);
                }
                XS.Push(aTargetMethodUID);
                XS.Call(LabelName.Get(VTablesImplRefs.GetMethodAddressForTypeRef));
                if (xExtraStackSize > 0)
                {
                    xThisOffset -= xExtraStackSize;
                }

                /*
                 * On the stack now:
                 * $esp                 Params
                 * $esp + mThisOffset   This
                 */
                XS.Pop(ECX);

                XS.Label(xCurrentMethodLabel + ".AfterAddressCheck");

                if (TypeIsReferenceType(xPopType))
                {
                    /*
                    * On the stack now:
                    * $esp + 0              Params
                    * $esp + mThisOffset    This
                    */
                    // we need to see if $this is a boxed object, and if so, we need to box it
                    XS.Set(EAX, ESP, sourceDisplacement: (int)xThisOffset + 4);
                    XS.Compare(EAX, (int)InstanceTypeEnum.BoxedValueType, destinationIsIndirect: true, destinationDisplacement: 4, size: RegisterSize.Int32);

                    /*
                    * On the stack now:
                    * $esp                 Params
                    * $esp + mThisOffset   This
                    *
                    * ECX contains the method to call
                    * EAX contains the type pointer (not the handle!!)
                    */
                    XS.Jump(CPU.ConditionalTestEnum.NotEqual, xCurrentMethodLabel + ".NotBoxedThis");

                    /*
                    * On the stack now:
                    * $esp                 Params
                    * $esp + mThisOffset   This
                    *
                    * ECX contains the method to call
                    * EAX contains the type pointer (not the handle!!)
                    */
                    XS.Add(EAX, (uint)ObjectImpl.FieldDataOffset);
                    XS.Set(ESP, EAX, destinationDisplacement: (int)xThisOffset + 4);

                    /*
                    * On the stack now:
                    * $esp                 Params
                    * $esp + mThisOffset   Pointer to address inside box
                    *
                    * ECX contains the method to call
                    */
                }
                XS.Label(xCurrentMethodLabel + ".NotBoxedThis");
                if (xExtraStackSize > 0)
                {
                    XS.Sub(ESP, xExtraStackSize);
                }
                XS.Call(ECX);
                XS.Label(xCurrentMethodLabel + ".AfterNotBoxedThis");
            }
            EmitExceptionLogic(Assembler, aMethod, aOp, true,
                delegate
                {
                    var xStackOffsetBefore = aOp.StackOffsetBeforeExecution.Value;

                    uint xPopSize = 0;
                    foreach (var type in aOp.StackPopTypes)
                    {
                        xPopSize += Align(SizeOfType(type), 4);
                    }

                    var xResultSize = xReturnSize;
                    if (xResultSize % 4 != 0)
                    {
                        xResultSize += 4 - (xResultSize % 4);
                    }

                    EmitExceptionCleanupAfterCall(Assembler, xResultSize, xStackOffsetBefore, xPopSize);
                });
            XS.Label(xCurrentMethodLabel + ".NoExceptionAfterCall");
            XS.Comment("Argument Count = " + xParameters.Length);
        }
示例#18
0
文件: Ldstr.cs 项目: nstone101/Cosmos
 public LdStr(Cosmos.Assembler.Assembler aAsmblr) : base(aAsmblr)
 {
 }
示例#19
0
 public Ldsflda(Cosmos.Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
示例#20
0
 public Stind_I(Cosmos.Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
示例#21
0
        public static void Assemble(Cosmos.Assembler.Assembler aAssembler, int aSize, bool debugEnabled)
        {
            DoNullReferenceCheck(aAssembler, debugEnabled, Align((uint)aSize, 4));
            new Comment(aAssembler, "address at: [esp + " + aSize + "]");
            int xStorageSize = aSize;

            if (xStorageSize < 4)
            {
                xStorageSize = 4;
            }
            new CPUx86.Mov {
                DestinationReg = CPUx86.Registers.EBX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = xStorageSize
            };
            for (int i = 0; i < (aSize / 4); i++)
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = i * 4
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EBX, DestinationIsIndirect = true, DestinationDisplacement = i * 4, SourceReg = CPUx86.Registers.EAX
                };
            }
            switch (aSize % 4)
            {
            case 0:
            {
                break;
            }

            case 1:
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = ((aSize / 4) * 4)
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EBX, DestinationIsIndirect = true, SourceDisplacement = ((aSize / 4) * 4), SourceReg = CPUx86.Registers.AL
                };
                break;
            }

            case 2:
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = ((aSize / 4) * 4)
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EBX, DestinationIsIndirect = true, DestinationDisplacement = ((aSize / 4) * 4), SourceReg = CPUx86.Registers.AX
                };
                break;
            }

            case 3:
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = ((aSize / 4) * 4)
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EBX, DestinationIsIndirect = true, DestinationDisplacement = ((aSize / 4) * 4), SourceReg = CPUx86.Registers.AX
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = (((aSize / 4) * 4) + 2)
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EBX, DestinationIsIndirect = true, DestinationDisplacement = (((aSize / 4) * 4) + 2), SourceReg = CPUx86.Registers.AL
                };
                break;
            }

            default:
                throw new Exception("Error, shouldn't occur");
            }
            new CPUx86.Add {
                DestinationReg = CPUx86.Registers.ESP, SourceValue = ( uint )(xStorageSize + 4)
            };
        }
示例#22
0
文件: Ldc_I8.cs 项目: invisal/Cosmos
 public Ldc_I8(Cosmos.Assembler.Assembler aAsmblr) : base(aAsmblr)
 {
 }
示例#23
0
 public override bool IsComplete(Assembler aAssembler)
 {
     throw new NotImplementedException("Method not implemented for instruction " + this.GetType().FullName.Substring(typeof(Instruction).Namespace.Length + 1));
 }
示例#24
0
文件: Box.cs 项目: fanoI/Cosmos
 public Box(Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
示例#25
0
 protected ILOp(Cosmos.Assembler.Assembler aAsmblr)
 {
     Assembler = aAsmblr;
 }
示例#26
0
 public Unbox_Any(Cosmos.Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
 public Localloc(Cosmos.Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
示例#28
0
 public static void EmitExceptionLogic(Cosmos.Assembler.Assembler aAssembler, MethodInfo aMethodInfo, ILOpCode aCurrentOpCode, bool aDoTest, Action aCleanup)
 {
     EmitExceptionLogic(aAssembler, aMethodInfo, aCurrentOpCode, aDoTest, aCleanup, ILOp.GetLabel(aMethodInfo, aCurrentOpCode.NextPosition));
 }
示例#29
0
 public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo)
 {
     new Assembler.x86.Sti();
 }
示例#30
0
        public static void EmitExceptionLogic(Cosmos.Assembler.Assembler aAssembler, MethodInfo aMethodInfo, ILOpCode aCurrentOpCode, bool aDoTest, Action aCleanup, string aJumpTargetNoException)
        {
            string xJumpTo = null;

            if (aCurrentOpCode != null && aCurrentOpCode.CurrentExceptionHandler != null)
            {
                // todo add support for nested handlers, see comment in Engine.cs
                //if (!((aMethodInfo.CurrentHandler.HandlerOffset < aCurrentOpOffset) || (aMethodInfo.CurrentHandler.HandlerLength + aMethodInfo.CurrentHandler.HandlerOffset) <= aCurrentOpOffset)) {
                new Comment(String.Format("CurrentOffset = {0}, HandlerStartOffset = {1}", aCurrentOpCode.Position, aCurrentOpCode.CurrentExceptionHandler.HandlerOffset));
                if (aCurrentOpCode.CurrentExceptionHandler.HandlerOffset > aCurrentOpCode.Position)
                {
                    switch (aCurrentOpCode.CurrentExceptionHandler.Flags)
                    {
                    case ExceptionHandlingClauseOptions.Clause: {
                        xJumpTo = ILOp.GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionHandler.HandlerOffset);
                        break;
                    }

                    case ExceptionHandlingClauseOptions.Finally: {
                        xJumpTo = ILOp.GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionHandler.HandlerOffset);
                        break;
                    }

                    default: {
                        throw new Exception("ExceptionHandlerType '" + aCurrentOpCode.CurrentExceptionHandler.Flags.ToString() + "' not supported yet!");
                    }
                    }
                }
            }
            // if aDoTest is true, we check ECX for exception flags
            if (!aDoTest)
            {
                //new CPU.Call("_CODE_REQUESTED_BREAK_");
                if (xJumpTo == null)
                {
                    Jump_Exception(aMethodInfo);
                }
                else
                {
                    new CPU.Jump {
                        DestinationLabel = xJumpTo
                    };
                }
            }
            else
            {
                new CPU.Test {
                    DestinationReg = CPU.Registers.ECX, SourceValue = 2
                };

                if (aCleanup != null)
                {
                    new CPU.ConditionalJump {
                        Condition = CPU.ConditionalTestEnum.Equal, DestinationLabel = aJumpTargetNoException
                    };
                    aCleanup();
                    if (xJumpTo == null)
                    {
                        new CPU.ConditionalJump {
                            Condition = CPU.ConditionalTestEnum.NotEqual, DestinationLabel = GetMethodLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException
                        };
                    }
                    else
                    {
                        new CPU.ConditionalJump {
                            Condition = CPU.ConditionalTestEnum.NotEqual, DestinationLabel = xJumpTo
                        };
                    }
                }
                else
                {
                    if (xJumpTo == null)
                    {
                        new CPU.ConditionalJump {
                            Condition = CPU.ConditionalTestEnum.NotEqual, DestinationLabel = GetMethodLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException
                        };
                    }
                    else
                    {
                        new CPU.ConditionalJump {
                            Condition = CPU.ConditionalTestEnum.NotEqual, DestinationLabel = xJumpTo
                        };
                    }
                }
            }
        }
示例#31
0
 public abstract void WriteText(Assembler aAssembler, TextWriter aOutput);
示例#32
0
        public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
        {
            // IDT is already initialized but just for base hooks, and asm only.
            // ie Int 1, 3 and GPF
            // This routine updates the IDT now that we have C# running to allow C# hooks to handle
            // the other INTs

            // We are updating the IDT, disable interrupts
            new CPUx86.ClearInterruptFlag();

            for (int i = 0; i < 256; i++)
            {
                // These are already mapped, don't remap them.
                // Maybe in the future we can look at ones that are present
                // and skip them, but some we may want to overwrite anyways.
                if (i == 1 || i == 3)
                {
                    continue;
                }

                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceRef = CPUAll.ElementReference.New("__ISR_Handler_" + i.ToString("X2"))
                };
                new CPUx86.Mov
                {
                    DestinationRef          = CPUAll.ElementReference.New("_NATIVE_IDT_Contents"),
                    DestinationIsIndirect   = true,
                    DestinationDisplacement = ((i * 8) + 0),
                    SourceReg = CPUx86.Registers.AL
                };
                new CPUx86.Mov
                {
                    DestinationRef          = CPUAll.ElementReference.New("_NATIVE_IDT_Contents"),
                    DestinationIsIndirect   = true,
                    DestinationDisplacement = ((i * 8) + 1),
                    SourceReg = CPUx86.Registers.AH
                };
                new CPUx86.Mov
                {
                    DestinationRef          = CPUAll.ElementReference.New("_NATIVE_IDT_Contents"),
                    DestinationIsIndirect   = true,
                    DestinationDisplacement = ((i * 8) + 2),
                    SourceValue             = 0x8,
                    Size = 8
                };

                new CPUx86.Mov
                {
                    DestinationRef          = CPUAll.ElementReference.New("_NATIVE_IDT_Contents"),
                    DestinationIsIndirect   = true,
                    DestinationDisplacement = ((i * 8) + 5),
                    SourceValue             = 0x8E,
                    Size = 8
                };
                new CPUx86.ShiftRight {
                    DestinationReg = CPUx86.Registers.EAX, SourceValue = 16
                };
                new CPUx86.Mov
                {
                    DestinationRef          = CPUAll.ElementReference.New("_NATIVE_IDT_Contents"),
                    DestinationIsIndirect   = true,
                    DestinationDisplacement = ((i * 8) + 6),
                    SourceReg = CPUx86.Registers.AL
                };
                new CPUx86.Mov
                {
                    DestinationRef          = CPUAll.ElementReference.New("_NATIVE_IDT_Contents"),
                    DestinationIsIndirect   = true,
                    DestinationDisplacement = ((i * 8) + 7),
                    SourceReg = CPUx86.Registers.AH
                };
            }

            new CPUx86.Jump {
                DestinationLabel = "__AFTER__ALL__ISR__HANDLER__STUBS__"
            };
            var xInterruptsWithParam = new int[] { 8, 10, 11, 12, 13, 14 };

            for (int j = 0; j < 256; j++)
            {
                new CPUAll.Label("__ISR_Handler_" + j.ToString("X2"));
                new CPUx86.Call {
                    DestinationLabel = "__INTERRUPT_OCCURRED__"
                };

                if (Array.IndexOf(xInterruptsWithParam, j) == -1)
                {
                    new CPUx86.Push {
                        DestinationValue = 0
                    };
                }
                new CPUx86.Push {
                    DestinationValue = (uint)j
                };
                new CPUx86.Pushad();

                new CPUx86.Sub {
                    DestinationReg = CPUx86.Registers.ESP, SourceValue = 4
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP
                };                                                                                          // preserve old stack address for passing to interrupt handler

                // store floating point data
                new CPUx86.And {
                    DestinationReg = CPUx86.Registers.ESP, SourceValue = 0xfffffff0
                };                                                                                  // fxsave needs to be 16-byte alligned
                new CPUx86.Sub {
                    DestinationReg = CPUx86.Registers.ESP, SourceValue = 512
                };                                                                           // fxsave needs 512 bytes
                new CPUx86.x87.FXSave {
                    DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true
                };                                                                                             // save the registers
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.ESP
                };

                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };                                                         //
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };                                                         // pass old stack address (pointer to InterruptContext struct) to the interrupt handler
                                                                           //new CPUx86.Move("eax",
                                                                           //                "esp");
                                                                           //new CPUx86.Push("eax");
                new CPUx86.JumpToSegment {
                    Segment = 8, DestinationLabel = "__ISR_Handler_" + j.ToString("X2") + "_SetCS"
                };
                new CPUAll.Label("__ISR_Handler_" + j.ToString("X2") + "_SetCS");
                MethodBase xHandler = GetInterruptHandler((byte)j);
                if (xHandler == null)
                {
                    xHandler = GetMethodDef(typeof(INTs).Assembly, typeof(INTs).FullName, "HandleInterrupt_Default", true);
                }
                new CPUx86.Call {
                    DestinationLabel = CPUAll.LabelName.Get(xHandler)
                };
                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EAX
                };
                new CPUx86.x87.FXStore {
                    DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true
                };

                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.ESP, SourceReg = CPUx86.Registers.EAX
                };                                                                                          // this restores the stack for the FX stuff, except the pointer to the FX data
                new CPUx86.Add {
                    DestinationReg = CPUx86.Registers.ESP, SourceValue = 4
                };                                                                         // "pop" the pointer

                new CPUx86.Popad();

                new CPUx86.Add {
                    DestinationReg = CPUx86.Registers.ESP, SourceValue = 8
                };
                new CPUAll.Label("__ISR_Handler_" + j.ToString("X2") + "_END");
                new CPUx86.IRET();
            }
            new CPUAll.Label("__INTERRUPT_OCCURRED__");
            new CPUx86.Return();
            new CPUAll.Label("__AFTER__ALL__ISR__HANDLER__STUBS__");
            new CPUx86.Noop();
            new CPUx86.Mov {
                DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EBP, SourceIsIndirect = true, SourceDisplacement = 8
            };
            new CPUx86.Compare {
                DestinationReg = CPUx86.Registers.EAX, SourceValue = 0
            };
            new CPUx86.ConditionalJump {
                Condition = CPUx86.ConditionalTestEnum.Zero, DestinationLabel = ".__AFTER_ENABLE_INTERRUPTS"
            };

            // reload interrupt list
            new CPUx86.Mov {
                DestinationReg = CPUx86.Registers.EAX, SourceRef = Cosmos.Assembler.ElementReference.New("_NATIVE_IDT_Pointer")
            };
            new CPUx86.Mov {
                DestinationRef = CPUAll.ElementReference.New("static_field__Cosmos_Core_CPU_mInterruptsEnabled"), DestinationIsIndirect = true, SourceValue = 1
            };
            new CPUx86.Lidt {
                DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true
            };
            // Reenable interrupts
            new CPUx86.Sti();

            new CPUAll.Label(".__AFTER_ENABLE_INTERRUPTS");
        }
示例#33
0
文件: Comment.cs 项目: Orvid/Cosmos
 public override bool IsComplete( Assembler aAssembler )
 {
     return true;
 }
示例#34
0
 public Ldelem_Ref(Cosmos.Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
示例#35
0
        public override void WriteText(Assembler aAssembler, TextWriter aOutput)
        {
            if (RawAsm != null)
            {
                aOutput.WriteLine(RawAsm);
                return;
            }

            if (RawDefaultValue != null)
            {
                if (RawDefaultValue.Length == 0)
                {
                    aOutput.Write(Name);
                    aOutput.Write(":");
                    return;
                }
                if ((from item in RawDefaultValue
                     group item by item
                     into i
                     select i).Count() > 1 || RawDefaultValue.Length < 250)
                {
                    if (IsGlobal)
                    {
                        aOutput.Write("global ");
                        aOutput.WriteLine(Name);
                    }
                    aOutput.Write(Name);
                    aOutput.Write(" db ");
                    for (int i = 0; i < (RawDefaultValue.Length - 1); i++)
                    {
                        aOutput.Write(RawDefaultValue[i]);
                        aOutput.Write(", ");
                    }
                    aOutput.Write(RawDefaultValue.Last());
                }
                else
                {
                    aOutput.Write("global ");
                    aOutput.WriteLine(Name);
                    aOutput.Write(Name);
                    aOutput.Write(": TIMES ");
                    aOutput.Write(RawDefaultValue.Length);
                    aOutput.Write(" db ");
                    aOutput.Write(RawDefaultValue[0]);
                }
                return;
            }
            if (UntypedDefaultValue != null)
            {
                if (IsGlobal)
                {
                    aOutput.Write("global ");
                    aOutput.WriteLine(Name);
                }
                aOutput.Write(Name);

                if (UntypedDefaultValue[0] is Int64 || UntypedDefaultValue[0] is UInt64 || UntypedDefaultValue[0] is Double)
                {
                    aOutput.Write(" dq ");
                }
                else
                {
                    aOutput.Write(" dd ");
                }

                Func <object, string> xGetTextForItem = delegate(object aItem)
                {
                    var xElementRef = aItem as ElementReference;
                    if (xElementRef == null)
                    {
                        return((aItem ?? 0).ToString());
                    }

                    if (xElementRef.Offset == 0)
                    {
                        return(xElementRef.Name);
                    }
                    return(xElementRef.Name + " + " + xElementRef.Offset);
                };
                for (int i = 0; i < (UntypedDefaultValue.Length - 1); i++)
                {
                    aOutput.Write(xGetTextForItem(UntypedDefaultValue[i]));
                    aOutput.Write(", ");
                }
                aOutput.Write(xGetTextForItem(UntypedDefaultValue.Last()));
                return;
            }

            if (StringValue != null)
            {
                aOutput.Write(Name);
                aOutput.Write(" ");
                aOutput.Write(Size);
                aOutput.Write(" ");
                aOutput.Write(StringValue);
                return;
            }

            throw new Exception("Situation unsupported!");
        }
示例#36
0
        public static void Assemble(Cosmos.Assembler.Assembler aAssembler, uint aElementSize, bool isSigned, bool debugEnabled)
        {
            DoNullReferenceCheck(aAssembler, debugEnabled, 4);
            //if (aElementSize <= 0 || aElementSize > 8 || (aElementSize > 4 && aElementSize < 8))
            //{
            //    throw new Exception("Unsupported size for Ldelem_Ref: " + aElementSize);
            //}

            new CPUx86.Pop {
                DestinationReg = CPUx86.Registers.EAX
            };
            new CPUx86.Mov {
                DestinationReg = CPUx86.Registers.EDX, SourceValue = aElementSize
            };
            new CPUx86.Multiply {
                DestinationReg = CPUx86.Registers.EDX
            };

            new CPUx86.Add {
                DestinationReg = CPUx86.Registers.EAX, SourceValue = (ObjectImpl.FieldDataOffset + 4)
            };

            if (aElementSize > 4)
            {
                // we start copying the last bytes
                new CPUx86.Add {
                    DestinationReg = CPUx86.Registers.EAX, SourceValue = aElementSize - 4
                };
            }

            // pop the array
            new CPUx86.Pop {
                DestinationReg = CPUx86.Registers.EDX
            };
            // convert to real memory address
            new CPUx86.Mov {
                DestinationReg = CPUx86.Registers.EDX, SourceReg = CPUx86.RegistersEnum.EDX, SourceIsIndirect = true
            };

            new CPUx86.Add {
                DestinationReg = CPUx86.Registers.EDX, SourceReg = CPUx86.Registers.EAX
            };

            var xSizeLeft = aElementSize;

            while (xSizeLeft > 0)
            {
                var xCurrentStep = Math.Min(xSizeLeft, 4);
                if (xSizeLeft % 4 != 0)
                {
                    xCurrentStep = xSizeLeft % 4;
                }
                xSizeLeft = xSizeLeft - xCurrentStep;
                switch (xCurrentStep)
                {
                case 1:
                    if (isSigned)
                    {
                        new CPUx86.MoveSignExtend {
                            DestinationReg = CPUx86.Registers.ECX, Size = 8, SourceReg = CPUx86.Registers.EDX, SourceIsIndirect = true
                        };
                    }
                    else
                    {
                        new CPUx86.MoveZeroExtend {
                            DestinationReg = CPUx86.Registers.ECX, Size = 8, SourceReg = CPUx86.Registers.EDX, SourceIsIndirect = true
                        };
                    }
                    new CPUx86.Push {
                        DestinationReg = CPUx86.Registers.ECX
                    };
                    break;

                case 2:
                    if (isSigned)
                    {
                        new CPUx86.MoveSignExtend {
                            DestinationReg = CPUx86.Registers.ECX, Size = 16, SourceReg = CPUx86.Registers.EDX, SourceIsIndirect = true
                        };
                    }
                    else
                    {
                        new CPUx86.MoveZeroExtend {
                            DestinationReg = CPUx86.Registers.ECX, Size = 16, SourceReg = CPUx86.Registers.EDX, SourceIsIndirect = true
                        };
                    }
                    new CPUx86.Push {
                        DestinationReg = CPUx86.Registers.ECX
                    };
                    break;

                case 4:
                    // copy a full dword
                    new CPUx86.Push {
                        DestinationReg = CPUx86.Registers.EDX, DestinationIsIndirect = true
                    };
                    new CPUx86.Sub {
                        DestinationReg = CPUx86.RegistersEnum.EDX, SourceValue = 4
                    };                                                                     // move to previous 4 bytes
                    break;
                    //case 8:
                    //    new CPUx86.Push {DestinationReg = CPUx86.Registers.EDX, DestinationDisplacement = 4, DestinationIsIndirect = true};
                    //    new CPUx86.Push {DestinationReg = CPUx86.Registers.EDX, DestinationIsIndirect = true};
                    //    break;
                }
            }
        }
示例#37
0
 public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo)
 {
   DisableInterrupts();
   // bochs magic break
   //Exchange(BX, BX);
   Halt();
 }
示例#38
0
文件: Stfld.cs 项目: xsword911/Cosmos
        public static void DoExecute(Cosmos.Assembler.Assembler aAssembler, MethodInfo aMethod, SysReflection.FieldInfo aField, bool debugEnabled)
        {
            bool xNeedsGC = aField.DeclaringType.IsClass && !aField.DeclaringType.IsValueType;

            DoExecute(aAssembler, aMethod, aField.GetFullName(), aField.DeclaringType, xNeedsGC, debugEnabled);
        }
示例#39
0
    public static void Assemble(Assembler.Assembler aAssembler, uint aElementSize, bool isSigned, MethodInfo aMethod, ILOpCode aOpCode, bool debugEnabled)
    {
      //  stack     = index
      //  stack + 2 = array
      DoNullReferenceCheck(aAssembler, debugEnabled, 8);

      // calculate element offset into array memory (including header)
      XS.Pop(EAX);
      XS.Set(EDX, aElementSize);
      XS.Multiply(EDX);
      XS.Add(EAX, ObjectImpl.FieldDataOffset + 4);

      if (aElementSize > 4)
      {
        // we start copying the last bytes
        XS.Add(EAX, aElementSize - 4);
      }

      // pop the array now
      XS.Add(ESP, 4);
      XS.Pop(EDX);

      XS.Add(EDX, EAX);

      var xSizeLeft = aElementSize;
      while (xSizeLeft > 0)
      {
        var xCurrentStep = Math.Min(xSizeLeft, 4);
        if (xSizeLeft % 4 != 0)
        {
          xCurrentStep = xSizeLeft % 4;
        }

        xSizeLeft = xSizeLeft - xCurrentStep;
        switch (xCurrentStep)
        {
          case 1:
            if (isSigned)
            {
              new CPUx86.MoveSignExtend { DestinationReg = CPUx86.RegistersEnum.ECX, Size = 8, SourceReg = CPUx86.RegistersEnum.EDX, SourceIsIndirect = true };
            }
            else
            {
              new CPUx86.MoveZeroExtend { DestinationReg = CPUx86.RegistersEnum.ECX, Size = 8, SourceReg = CPUx86.RegistersEnum.EDX, SourceIsIndirect = true };
            }
            XS.Push(ECX);
            break;
          case 2:
            if (isSigned)
            {
              new CPUx86.MoveSignExtend { DestinationReg = CPUx86.RegistersEnum.ECX, Size = 16, SourceReg = CPUx86.RegistersEnum.EDX, SourceIsIndirect = true };
            }
            else
            {
              new CPUx86.MoveZeroExtend { DestinationReg = CPUx86.RegistersEnum.ECX, Size = 16, SourceReg = CPUx86.RegistersEnum.EDX, SourceIsIndirect = true };
            }
            XS.Push(ECX);
            break;
          case 4:
            // copy a full dword
            XS.Push(EDX, isIndirect: true);
            XS.Sub(EDX, 4); // move to previous 4 bytes
            break;
            //case 8:
            //    new CPUx86.Push {DestinationReg = CPUx86.Registers.EDX, DestinationDisplacement = 4, DestinationIsIndirect = true};
            //    XS.Push(XSRegisters.EDX, isIndirect: true);
            //    break;
        }
      }
    }
示例#40
0
文件: Stfld.cs 项目: xsword911/Cosmos
        public static void DoExecute(Cosmos.Assembler.Assembler aAssembler, MethodInfo aMethod, string aFieldId, Type aDeclaringObject, bool aNeedsGC, bool debugEnabled)
        {
            var xType        = aMethod.MethodBase.DeclaringType;
            int xExtraOffset = aNeedsGC ? 12 : 0;

            var xFields    = GetFieldsInfo(aDeclaringObject);
            var xFieldInfo = (from item in xFields
                              where item.Id == aFieldId
                              select item).Single();
            var xActualOffset = xFieldInfo.Offset + xExtraOffset;
            var xSize         = xFieldInfo.Size;

            new Comment("Field: " + xFieldInfo.Id);
            new Comment("Type: " + xFieldInfo.FieldType.ToString());
            new Comment("Size: " + xFieldInfo.Size);

            uint xRoundedSize = Align(xSize, 4);

            DoNullReferenceCheck(aAssembler, debugEnabled, xRoundedSize);

            new CPUx86.Mov {
                DestinationReg = CPUx86.Registers.ECX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true, SourceDisplacement = (int)xRoundedSize
            };
            if (debugEnabled)
            {
                new CPUx86.Push {
                    DestinationReg = CPUx86.RegistersEnum.ECX
                };
                new CPUx86.Pop {
                    DestinationReg = CPUx86.RegistersEnum.ECX
                };
            }
            new CPUx86.Add {
                DestinationReg = CPUx86.Registers.ECX, SourceValue = (uint)(xActualOffset)
            };
            //TODO: Can't we use an x86 op to do a byte copy instead and be faster?
            for (int i = 0; i < (xSize / 4); i++)
            {
                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EAX
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.ECX, DestinationIsIndirect = true, DestinationDisplacement = (int)((i * 4)), SourceReg = CPUx86.Registers.EAX
                };
            }

            switch (xSize % 4)
            {
            case 1: {
                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EAX
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.ECX, DestinationIsIndirect = true, DestinationDisplacement = (int)((xSize / 4) * 4), SourceReg = CPUx86.Registers.AL
                };
                break;
            }

            case 2: {
                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EAX
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.ECX, DestinationIsIndirect = true, DestinationDisplacement = (int)((xSize / 4) * 4), SourceReg = CPUx86.Registers.AX
                };
                break;
            }

            case 3: {
                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EAX
                };
                // move 2 lower bytes
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.ECX, DestinationIsIndirect = true, DestinationDisplacement = (int)((xSize / 4) * 4), SourceReg = CPUx86.Registers.AX
                };
                // shift third byte to lowest
                new CPUx86.ShiftRight {
                    DestinationReg = CPUx86.Registers.EAX, SourceValue = 16
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.ECX, DestinationIsIndirect = true, DestinationDisplacement = (int)((xSize / 4) * 4) + 2, SourceReg = CPUx86.Registers.AL
                };
                break;
            }

            case 0: {
                break;
            }

            default:
                throw new Exception("Remainder size " + (xSize % 4) + " not supported!");
            }

#if !SKIP_GC_CODE
            if (aNeedsGC)
            {
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.ECX
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
                new CPUx86.Call {
                    DestinationLabel = LabelName.Get(GCImplementationRefs.DecRefCountRef)
                };
                new CPUx86.Call {
                    DestinationLabel = LabelName.Get(GCImplementationRefs.DecRefCountRef)
                };
            }
#endif
            new CPUx86.Add {
                DestinationReg = CPUx86.Registers.ESP, SourceValue = 4
            };
        }
示例#41
0
 public Constrained(Assembler.Assembler aAsmblr) : base(aAsmblr)
 {
 }
示例#42
0
 public Stsfld(Cosmos.Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
示例#43
0
文件: Optimizer.cs 项目: Orvid/Cosmos
    public static Assembler Optimize(Assembler asmb)
    {
      return asmb;
      Assembler asmblr = asmb;
      List<Instruction> instr = asmb.Instructions;
      //List<DataMember> dmbrs = asmb.DataMembers;

      SortedDictionary<string, Instruction> labels = new SortedDictionary<string, Instruction>();
      List<Instruction> comments = new List<Instruction>();
      List<String> usedLabels = new List<string>();
      usedLabels.Add("KernelStart");
      foreach (Instruction ins in instr) {
        if (ins is Label) {
          if (((Label)ins).IsGlobal) {
            usedLabels.Add(((Label)ins).QualifiedName);
          }
          labels.Add(((Label)ins).QualifiedName, ins);
        } else if (ins is x86.JumpToSegment) {
          if (((x86.JumpToSegment)ins).DestinationRef != null) {
            usedLabels.Add(((x86.JumpToSegment)ins).DestinationRef.Name);
          } else {
            usedLabels.Add(((x86.JumpToSegment)ins).DestinationLabel);
          }
        } else if (ins is x86.JumpBase) {
          usedLabels.Add(((x86.JumpBase)ins).DestinationLabel);
        } else if (ins is x86.Call) {
          usedLabels.Add(((x86.Call)ins).DestinationLabel);
        } else if (ins is x86.Push) {
          if (((x86.Push)ins).DestinationRef != null) {
            usedLabels.Add(((x86.Push)ins).DestinationRef.Name);
          }
        } else if (ins is x86.Mov) {
          if (((x86.Mov)ins).SourceRef != null) {
            usedLabels.Add(((x86.Mov)ins).SourceRef.Name);
          }
        }
      }
      foreach (string s in usedLabels) {
        labels.Remove(s);
      }
      usedLabels = null;
      instr.RemoveAll(
          delegate(Instruction inst) {
            if (inst is Comment)
              return true;
            else if (inst is Label) {
              if (labels.ContainsKey(((Label)inst).QualifiedName))
                return true;
              return false;
            }
            return false;
          }
      );
      labels = null;
      comments = null;




      asmblr.Instructions = instr;
      //asmblr.DataMembers = dmbrs;
      return asmblr;

    }
示例#44
0
        public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aCurrentMethod, MethodBase aTargetMethod, ILOpCode aOp, string currentLabel, string nextLabel, bool debugEnabled)
        {
            var    xMethodInfo    = aTargetMethod as SysReflection.MethodInfo;
            string xNormalAddress = LabelName.Get(aTargetMethod);
            var    xParameters    = aTargetMethod.GetParameters();

            // todo: implement exception support
            uint xExtraStackSize = GetStackSizeToReservate(aTargetMethod);

            if (!aTargetMethod.IsStatic)
            {
                uint xThisOffset = 0;
                foreach (var xItem in xParameters)
                {
                    xThisOffset += Align(SizeOfType(xItem.ParameterType), 4);
                }
                var stackOffsetToCheck = xThisOffset;
                if (TypeIsReferenceType(aTargetMethod.DeclaringType))
                {
                    DoNullReferenceCheck(Assembler, debugEnabled, (int)stackOffsetToCheck + 4);
                }
                else
                {
                    DoNullReferenceCheck(Assembler, debugEnabled, (int)stackOffsetToCheck);
                }
            }

            if (xExtraStackSize > 0)
            {
                XS.Sub(XSRegisters.ESP, (uint)xExtraStackSize);
            }
            XS.Call(xNormalAddress);

            uint xReturnSize = 0;

            if (xMethodInfo != null)
            {
                xReturnSize = SizeOfType(xMethodInfo.ReturnType);
            }
            if (aCurrentMethod != null)
            {
                EmitExceptionLogic(Assembler, aCurrentMethod, aOp, true,
                                   delegate
                {
                    var xStackOffsetBefore = aOp.StackOffsetBeforeExecution.Value;

                    uint xPopSize = 0;
                    foreach (var type in aOp.StackPopTypes)
                    {
                        xPopSize += Align(SizeOfType(type), 4);
                    }

                    var xResultSize = xReturnSize;
                    if (xResultSize % 4 != 0)
                    {
                        xResultSize += 4 - (xResultSize % 4);
                    }

                    ILOp.EmitExceptionCleanupAfterCall(Assembler, xResultSize, xStackOffsetBefore, xPopSize);
                }, nextLabel);
            }
        }
示例#45
0
文件: ILOp.cs 项目: Zino2201/Cosmos
        public static void EmitExceptionLogic(Assembler.Assembler aAssembler, MethodInfo aMethodInfo, ILOpCode aCurrentOpCode, bool aDoTest, Action aCleanup, string aJumpTargetNoException = null)
        {
            if (aJumpTargetNoException == null)
              {
            aJumpTargetNoException = GetLabel(aMethodInfo, aCurrentOpCode.NextPosition);
              }
              string xJumpTo = null;
              if (aCurrentOpCode != null && aCurrentOpCode.CurrentExceptionHandler != null) {
            // todo add support for nested handlers, see comment in Engine.cs
            //if (!((aMethodInfo.CurrentHandler.HandlerOffset < aCurrentOpOffset) || (aMethodInfo.CurrentHandler.HandlerLength + aMethodInfo.CurrentHandler.HandlerOffset) <= aCurrentOpOffset)) {
            XS.Comment(String.Format("CurrentOffset = {0}, HandlerStartOffset = {1}", aCurrentOpCode.Position, aCurrentOpCode.CurrentExceptionHandler.HandlerOffset));
            if (aCurrentOpCode.CurrentExceptionHandler.HandlerOffset > aCurrentOpCode.Position) {
              switch (aCurrentOpCode.CurrentExceptionHandler.Flags) {
            case ExceptionHandlingClauseOptions.Clause: {
                xJumpTo = GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionHandler.HandlerOffset);
                break;
              }
            case ExceptionHandlingClauseOptions.Finally: {
                xJumpTo = GetLabel(aMethodInfo, aCurrentOpCode.CurrentExceptionHandler.HandlerOffset);
                break;
              }
            default: {
                throw new Exception("ExceptionHandlerType '" + aCurrentOpCode.CurrentExceptionHandler.Flags.ToString() + "' not supported yet!");
              }
              }
            }
              }
              // if aDoTest is true, we check ECX for exception flags
              if (!aDoTest) {
            //new CPU.Call("_CODE_REQUESTED_BREAK_");
            if (xJumpTo == null) {
              Jump_Exception(aMethodInfo);
            } else {
              XS.Jump(xJumpTo);
            }

              } else {
            XS.Test(XSRegisters.ECX, 2);

            if (aCleanup != null) {
              XS.Jump(CPU.ConditionalTestEnum.Equal, aJumpTargetNoException);
              aCleanup();
              if (xJumpTo == null) {
            XS.Jump(CPU.ConditionalTestEnum.NotEqual, GetMethodLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException);
              } else {
            XS.Jump(CPU.ConditionalTestEnum.NotEqual, xJumpTo);
              }
            } else {
              if (xJumpTo == null) {
            XS.Jump(CPU.ConditionalTestEnum.NotEqual, GetMethodLabel(aMethodInfo) + AppAssembler.EndOfMethodLabelNameException);
              } else {
            XS.Jump(CPU.ConditionalTestEnum.NotEqual, xJumpTo);
              }
            }
              }
        }
 public abstract void WriteData( Assembler aAssembler, Stream aOutput );
示例#47
0
 public virtual void UpdateAddress(Assembler aAssembler, ref ulong aAddress)
 {
     StartAddress = aAddress;
 }
 public abstract void WriteText( Assembler aAssembler, TextWriter aOutput );
示例#49
0
 public override void WriteText(Assembler aAssembler, System.IO.TextWriter aOutput)
 {
     aOutput.Write(Code);
 }
示例#50
0
 public override void UpdateAddress(Assembler aAssembler, ref ulong aAddress)
 {
     base.UpdateAddress(aAssembler, ref aAddress);
 }
示例#51
0
文件: Callvirt.cs 项目: fanoI/Cosmos
 public Callvirt(Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
示例#52
0
文件: ILOp.cs 项目: Orvid/Cosmos
 protected ILOp(Cosmos.Assembler.Assembler aAsmblr) {
   Assembler = aAsmblr;
 }
示例#53
0
文件: Newarr.cs 项目: fanoI/Cosmos
 public Newarr(Assembler.Assembler aAsmblr)
     : base(aAsmblr)
 {
 }
示例#54
0
文件: Ldflda.cs 项目: zer09/Cosmos
        public static void DoExecute(Cosmos.Assembler.Assembler Assembler, MethodInfo aMethod, Type aDeclaringType, string aField, bool aDerefValue, bool aDebugEnabled, Type aTypeOnStack)
        {
            var xFieldInfo = ResolveField(aDeclaringType, aField, true);

            DoExecute(Assembler, aMethod, aDeclaringType, xFieldInfo, aDerefValue, aDebugEnabled, aTypeOnStack);
        }
示例#55
0
 public AppAssembler(int aComPort, string assemblerLogFile)
 {
     Assembler = CreateAssembler(aComPort);
     mLog = new StreamWriter(assemblerLogFile, false);
     InitILOps();
 }
示例#56
0
文件: Comment.cs 项目: Orvid/Cosmos
 public override void WriteText( Assembler aAssembler, System.IO.TextWriter aOutput )
 {
     aOutput.Write( "; " );
     aOutput.Write( Text );
 }
示例#57
0
 public override bool IsComplete(Assembler aAssembler)
 {
     return(true);
 }
示例#58
0
 public abstract void WriteData(Assembler aAssembler, Stream aOutput);
示例#59
0
 public override bool IsComplete(Assembler aAssembler) {
   throw new NotImplementedException("Method not implemented for instruction " + this.GetType().FullName.Substring(typeof(Instruction).Namespace.Length + 1));
 }
示例#60
0
        public static void Assemble(Cosmos.Assembler.Assembler aAssembler, MethodInfo aMethod, OpMethod xMethod, string currentLabel, Type objectType, MethodBase constructor)
        {
            // call cctor:
            if (aMethod != null)
            {
                var xCctor = (objectType.GetConstructors(BindingFlags.Static | BindingFlags.NonPublic) ?? new ConstructorInfo[0]).SingleOrDefault();
                if (xCctor != null)
                {
                    new CPUx86.Call
                    {
                        DestinationLabel = LabelName.Get(xCctor)
                    };
                    ILOp.EmitExceptionLogic(aAssembler, aMethod, xMethod, true, null, ".AfterCCTorExceptionCheck");
                    new Label(".AfterCCTorExceptionCheck");
                }
            }

            if (objectType.IsValueType)
            {
                #region Valuetypes

                new Comment("ValueType");

                /*
                 * Current sitation on stack:
                 *   $ESP       Arg
                 *   $ESP+..    other items
                 *
                 * What should happen:
                 *  + The stack should be increased to allow space to contain:
                 *         + .ctor arguments
                 *         + struct _pointer_ (ref to start of emptied space)
                 *         + empty space for struct
                 *  + arguments should be copied to the new place
                 *  + old place where arguments were should be cleared
                 *  + pointer should be set
                 *  + call .ctor
                 */

                // Size of return value - we need to make room for this on the stack.
                uint xStorageSize = Align(SizeOfType(objectType), 4);
                new Comment("StorageSize: " + xStorageSize);
                if (xStorageSize == 0)
                {
                    throw new Exception("ValueType storage size cannot be 0.");
                }

                //var xStorageSize = aCtorDeclTypeInfo.StorageSize;

                uint xArgSize       = 0;
                var  xParameterList = constructor.GetParameters();
                foreach (var xParam in xParameterList)
                {
                    xArgSize = xArgSize + Align(SizeOfType(xParam.ParameterType), 4);
                }
                new Comment("ArgSize: " + xArgSize);

                // Set ESP so we can push the struct ptr
                int xShift = (int)(xArgSize - xStorageSize);
                new Comment("Shift: " + xShift);
                if (xShift < 0)
                {
                    new CPUx86.Sub {
                        DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)Math.Abs(xShift)
                    };
                }
                else if (xShift > 0)
                {
                    new CPUx86.Add {
                        DestinationReg = CPUx86.Registers.ESP, SourceValue = (uint)xShift
                    };
                }

                // push struct ptr
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.ESP
                };

                // Shift args
                foreach (var xParam in xParameterList)
                {
                    uint xArgSizeForThis = Align(SizeOfType(xParam.ParameterType), 4);
                    for (int i = 1; i <= xArgSizeForThis / 4; i++)
                    {
                        new CPUx86.Push {
                            DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)xStorageSize
                        };
                    }
                }

                new Call(aAssembler).Execute(aMethod, xMethod);

                // Need to put these *after* the call because the Call pops the args from the stack
                // and we have mucked about on the stack, so this makes it right before the next
                // op.

                #endregion Valuetypes
            }
            else
            {
                // If not ValueType, then we need gc

                var xParams = constructor.GetParameters();

                // array length + 8
                bool xHasCalcSize = false;

                #region Special string handling
                // try calculating size:
                if (constructor.DeclaringType == typeof(string))
                {
                    if (xParams.Length == 1 &&
                        xParams[0].ParameterType == typeof(char[]))
                    {
                        xHasCalcSize = true;
                        new CPUx86.Mov {
                            DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true
                        };

                        // EAX contains a memory handle now, lets dereference it to a pointer
                        new CPUx86.Mov {
                            DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.RegistersEnum.EAX, SourceIsIndirect = true
                        };
                        new CPUx86.Mov {
                            DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true, SourceDisplacement = 8
                        };
                        new CPUx86.Mov {
                            DestinationReg = CPUx86.Registers.EDX, SourceValue = 2
                        };
                        new CPUx86.Multiply {
                            DestinationReg = CPUx86.Registers.EDX
                        };
                        new CPUx86.Push {
                            DestinationReg = CPUx86.Registers.EAX
                        };
                    }
                    else if (xParams.Length == 3 &&
                             (xParams[0].ParameterType == typeof(char[]) || xParams[0].ParameterType == typeof(char *)) &&
                             xParams[1].ParameterType == typeof(int) &&
                             xParams[2].ParameterType == typeof(int))
                    {
                        xHasCalcSize = true;
                        new CPUx86.Mov {
                            DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true
                        };
                        new CPUx86.ShiftLeft {
                            DestinationReg = CPUx86.Registers.EAX, SourceValue = 1
                        };
                        new CPUx86.Push {
                            DestinationReg = CPUx86.Registers.EAX
                        };
                    }
                    else if (xParams.Length == 2 &&
                             xParams[0].ParameterType == typeof(char) &&
                             xParams[1].ParameterType == typeof(int))
                    {
                        xHasCalcSize = true;
                        new CPUx86.Mov {
                            DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceIsIndirect = true
                        };
                        new CPUx86.ShiftLeft {
                            DestinationReg = CPUx86.Registers.EAX, SourceValue = 1
                        };
                        new CPUx86.Push {
                            DestinationReg = CPUx86.Registers.EAX
                        };
                    }
                    else
                    {
                        throw new NotImplementedException("In NewObj, a string ctor implementation is missing!");
                    }
                }
                #endregion Special string handling

                uint xMemSize   = GetStorageSize(objectType);
                int  xExtraSize = 12; // additional size for set values after alloc
                new CPUx86.Push {
                    DestinationValue = (uint)(xMemSize + xExtraSize)
                };
                if (xHasCalcSize)
                {
                    new CPUx86.Pop {
                        DestinationReg = CPUx86.Registers.EAX
                    };
                    new CPUx86.Add {
                        DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EAX
                    };
                }

                // todo: probably we want to check for exceptions after calling Alloc
                new CPUx86.Call {
                    DestinationLabel = LabelName.Get(GCImplementationRefs.AllocNewObjectRef)
                };
                new Label(".AfterAlloc");
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true
                };

                // it's on the stack now 3 times. Once from the Alloc return value, twice from the pushes

                //? ?? uint xObjSize;// = 0;
                //int xGCFieldCount = ( from item in aCtorDeclTypeInfo.Fields.Values
                //where item.NeedsGC
                //select item ).Count();

                //int xGCFieldCount = ( from item in aCtorDeclTypeInfo.Fields.Values
                //where item.NeedsGC
                //select item ).Count();
                int xGCFieldCount = objectType.GetFields().Count(x => x.FieldType.IsValueType);

                // todo: use a cleaner approach here. this class shouldnt assemble the string
                string strTypeId = GetTypeIDLabel(constructor.DeclaringType);

                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EAX
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.EAX, SourceIsIndirect = true
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EBX, SourceRef = Cosmos.Assembler.ElementReference.New(strTypeId), SourceIsIndirect = true
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EBX
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceValue = (uint)InstanceTypeEnum.NormalObject, Size = 32
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, DestinationIsIndirect = true, DestinationDisplacement = 8, SourceValue = (uint)xGCFieldCount, Size = 32
                };
                uint xSize = (uint)(from item in xParams
                                    let xQSize = Align(SizeOfType(item.ParameterType), 4)
                                                 select(int) xQSize).Take(xParams.Length).Sum();

                foreach (var xParam in xParams)
                {
                    uint xParamSize = Align(SizeOfType(xParam.ParameterType), 4);
                    new Comment(aAssembler, String.Format("Arg {0}: {1}", xParam.Name, xParamSize));
                    for (int i = 0; i < xParamSize; i += 4)
                    {
                        new CPUx86.Push {
                            DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)(xSize + 4)
                        };
                    }
                }

                new CPUx86.Call {
                    DestinationLabel = LabelName.Get(constructor)
                };
                // should the complete error handling happen by ILOp.EmitExceptionLogic?
                if (aMethod != null)
                {
                    // todo: only happening for real methods now, not for ctor's ?
                    new CPUx86.Test {
                        DestinationReg = CPUx86.Registers.ECX, SourceValue = 2
                    };
                    string xNoErrorLabel = currentLabel + ".NoError" + LabelName.LabelCount.ToString();
                    new CPUx86.ConditionalJump {
                        Condition = CPUx86.ConditionalTestEnum.Equal, DestinationLabel = xNoErrorLabel
                    };

                    //for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ )
                    //{
                    //    new CPUx86.Add
                    //    {
                    //        DestinationReg = CPUx86.Registers.ESP,
                    //        SourceValue = ( aCtorMethodInfo.Arguments[ i ].Size % 4 == 0
                    //             ? aCtorMethodInfo.Arguments[ i ].Size
                    //             : ( ( aCtorMethodInfo.Arguments[ i ].Size / 4 ) * 4 ) + 1 )
                    //    };
                    //}
                    PushAlignedParameterSize(constructor);

                    // an exception occurred, we need to cleanup the stack, and jump to the exit
                    new CPUx86.Add {
                        DestinationReg = CPUx86.Registers.ESP, SourceValue = 4
                    };

                    //new Comment(aAssembler, "[ Newobj.Execute cleanup start count = " + aAssembler.Stack.Count.ToString() + " ]");
                    //foreach( var xStackInt in Assembler.Stack )
                    //{
                    //    new CPUx86.Add { DestinationReg = CPUx86.Registers.ESP, SourceValue = ( uint )xStackInt.Size };
                    //}

                    new Comment(aAssembler, "[ Newobj.Execute cleanup end ]");
                    Jump_Exception(aMethod);
                    new Label(xNoErrorLabel);
                }
                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EAX
                };

                //for( int i = 1; i < aCtorMethodInfo.Arguments.Length; i++ )
                //{
                //    new CPUx86.Add
                //    {
                //        DestinationReg = CPUx86.Registers.ESP,
                //        SourceValue = ( aCtorMethodInfo.Arguments[ i ].Size % 4 == 0
                //             ? aCtorMethodInfo.Arguments[ i ].Size
                //             : ( ( aCtorMethodInfo.Arguments[ i ].Size / 4 ) * 4 ) + 1 )
                //    };
                //}
                PushAlignedParameterSize(constructor);

                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
            }
        }