示例#1
0
文件: Type.cs 项目: PlumpMath/cilc
        private void EmitValueType()
        {
            Console.WriteLine("emitValueType");
            if (!_cilType.IsDefinition)
            {
                Trace.Assert(false, "type is a TypeReference");
                return;
            }

            TypeDefinition   td     = (TypeDefinition)_cilType;
            List <LLVM.Type> l      = new List <LLVM.Type>();
            uint             offset = 0;

            foreach (FieldDefinition f in td.Fields)
            {
                if (f.IsStatic)
                {
                    continue;
                }
                LLVM.Type ty = _module.GetLlvmType(f.FieldType);
                if (f.FieldType.MetadataType == MetadataType.Class)
                {
                    ty = ty.GetPointerTo();
                }
                l.Add(ty);
                _fieldsOffsets[f] = offset;
                offset++;
            }
            LLVM.StructType sty = LlvmType as LLVM.StructType;
            sty.SetBody(l.ToArray(), false);

            EmitFields();
        }
示例#2
0
        private void GetLlvmType()
        {
            LLVM.Type retTy = _module.GetLlvmType(_method.ReturnType);
            if (_method.ReturnType.MetadataType == MetadataType.Class)
            {
                retTy = retTy.GetPointerTo();
            }

            List <LLVM.Type> paramsTy = new List <LLVM.Type>();

            if (_method.HasThis)
            {
                paramsTy.Add(_module.GetLlvmType(_method.DeclaringType).GetPointerTo());
            }

            if (_method.HasParameters)
            {
                foreach (ParameterDefinition p in _method.Parameters)
                {
                    LLVM.Type ty = _module.GetLlvmType(p.ParameterType);
                    if (p.ParameterType.MetadataType == MetadataType.Class)
                    {
                        ty = ty.GetPointerTo();
                    }
                    paramsTy.Add(ty);
                }
            }

            // TODO false -> varArg
            _type = LLVM.FunctionType.Get(retTy, paramsTy.ToArray(), false);
        }
示例#3
0
        private void EmitOpCodeNewobj(MethodReference method)
        {
            Trace.Assert(method != null);
            TypeReference type = method.DeclaringType;

            Trace.Assert(type != null); // cannot be null, we are creating an obj

            LLVM.Type  ty     = Cil2Llvm.GetType(type);
            LLVM.Value size   = ConvertInteger(ty.Size, CLR.Native);
            LLVM.Value newobj = _builder.CreateCall(CLR.Newobj, size, "newobj");
            newobj.Dump();
            LLVM.Value obj = ConvertPointer(newobj, ty.GetPointerTo());
//obj.dump();

            _stack.Push(obj);
            //TODO: Trace.Assert(method.ReturnType == Void);
            EmitOpCodeCall(method);
            _stack.Push(obj);

/*
 *  // Cast to object type, call ctor and push on the stack
 *  //
 *  convertValue(newobj, PointerType::get(ClassTy, 0), bb);
 *  callMethod(newobj, token, bb);
 *  _Stack.push_back(newobj);
 */
        }
示例#4
0
文件: Type.cs 项目: PlumpMath/cilc
        private void GetLlvmType()
        {
            switch (_cilType.MetadataType)
            {
            case MetadataType.Void:
                _llType = CLR.Void;
                break;

            case MetadataType.Boolean:
                _llType = CLR.Bool;
                break;

            case MetadataType.Char:
                _llType = CLR.Char;
                break;

            case MetadataType.SByte:
                _llType = CLR.Int8;
                break;

            case MetadataType.Byte:
                _llType = CLR.Int8;
                break;

            case MetadataType.Int16:
                _llType = CLR.Int16;
                break;

            case MetadataType.Int32:
                _llType = CLR.Int32;
                break;

            case MetadataType.String:
                _llType = CLR.String;
                break;

            case MetadataType.Object:
                _llType = CLR.Object;
                break;

            case MetadataType.ValueType:
                _isValueType = true;
                _llType      = LLVM.StructType.Get(_module.LlvmModule.Context,
                                                   "type " + _cilType.FullName);
                break;

            case MetadataType.Class:
                _isClass = true;
                _llType  = LLVM.StructType.Get(_module.LlvmModule.Context,
                                               "type " + _cilType.FullName);
                break;

            default:
                Console.WriteLine(">> not primitive {0}, {1}", _cilType.MetadataType, _cilType.IsDefinition);
                break;
            }
        }
示例#5
0
文件: Type.cs 项目: PlumpMath/cilc
        public Type(TypeReference tr, Module mod)
        {
            _module  = mod;
            _cilType = tr;
            _llType  = null;

            _emitted       = _isValueType = _isClass = false;
            _fieldsOffsets = new Dictionary <FieldDefinition, uint>();
        }
示例#6
0
文件: Type.cs 项目: tytouf/cilc
        public Type(TypeReference tr, Module mod)
        {
            _module  = mod;
            _cilType = tr;
            _llType  = null;

            _emitted = _isValueType = _isClass = false;
            _fieldsOffsets = new Dictionary<FieldDefinition, uint>();
        }
示例#7
0
 private LLVM.Value ConvertToType(LLVM.Value v, LLVM.Type toType)
 {
     LLVM.Type vType = v.Type;
     if (vType.isPointer() && toType.isPointer())
     {
         return(ConvertPointer(v, toType));
     }
     Console.WriteLine("v was not converted to toType");
     return(v); // TODO, FIXME
 }
示例#8
0
        private void EmitOpCodeRet()
        {
            LLVM.Type retTy = _method.Function.GetReturnType();

            if (retTy.Equals(CLR.Void))
            {
                Trace.Assert(_stack.Count == 0);
                _builder.CreateRetVoid();
            }
            else
            {
                // TODO.FIXME must deref return Value
                Trace.Assert(_stack.Count >= 1);
                LLVM.Value ret = _stack.Pop();
                _builder.CreateRet(ConvertToType(ret, retTy));
            }
        }
示例#9
0
        private void EmitOpCodeCall(MethodReference method)
        {
            Trace.Assert(method != null);

            List <LLVM.Type> argsTy = new List <LLVM.Type>();

            if (method.HasThis)
            {
                argsTy.Add(Cil2Llvm.GetType(method.DeclaringType).GetPointerTo());
            }

            if (method.HasParameters)
            {
                foreach (ParameterDefinition p in method.Parameters)
                {
                    argsTy.Add(Cil2Llvm.GetType(p.ParameterType));
                }
            }

            Trace.Assert(_stack.Count >= argsTy.Count);
            LLVM.Value[] args = new LLVM.Value[argsTy.Count];

            for (int i = argsTy.Count - 1; i >= 0; i--)
            {
                args[i] = ConvertToType(_stack.Pop(), argsTy[i]);
            }

            LLVM.Value ret   = _builder.CreateCall(Cil2Llvm.GetMethod(method), args);
            LLVM.Type  retTy = Cil2Llvm.GetType(method.ReturnType);

            if (!retTy.Equals(CLR.Void))
            {
                _stack.Push(ret);
            }

/*
 *  // Cast to object type, call ctor and push on the stack
 *  //
 *  convertValue(newobj, PointerType::get(ClassTy, 0), bb);
 *  callMethod(newobj, token, bb);
 *  _Stack.push_back(newobj);
 */
        }
示例#10
0
文件: Type.cs 项目: tytouf/cilc
 private void GetLlvmType()
 {
     switch(_cilType.MetadataType) {
     case MetadataType.Void:
         _llType = CLR.Void;
         break;
     case MetadataType.Boolean:
         _llType = CLR.Bool;
         break;
     case MetadataType.Char:
         _llType = CLR.Char;
         break;
     case MetadataType.SByte:
         _llType = CLR.Int8;
         break;
     case MetadataType.Byte:
         _llType = CLR.Int8;
         break;
     case MetadataType.Int16:
         _llType = CLR.Int16;
         break;
     case MetadataType.Int32:
         _llType = CLR.Int32;
         break;
     case MetadataType.String:
         _llType = CLR.String;
         break;
     case MetadataType.Object:
         _llType = CLR.Object;
         break;
     case MetadataType.ValueType:
         _isValueType = true;
         _llType = LLVM.StructType.Get(_module.LlvmModule.Context,
                                     "type " + _cilType.FullName);
         break;
     case MetadataType.Class:
         _isClass = true;
         _llType = LLVM.StructType.Get(_module.LlvmModule.Context,
                                     "type " + _cilType.FullName);
         break;
     default:
         Console.WriteLine(">> not primitive {0}, {1}", _cilType.MetadataType, _cilType.IsDefinition);
         break;
     }
 }
示例#11
0
 private LLVM.Value ConvertInteger(LLVM.Value v, LLVM.Type toType)
 {
     Trace.Assert(v.Type.isInteger() && toType.isInteger());
     return(_builder.CreateIntCast(v, toType)); // signed cast
 }
示例#12
0
 private LLVM.Value ConvertPointer(LLVM.Value v, LLVM.Type toType)
 {
     Trace.Assert(v.Type.isPointer() && toType.isPointer());
     return(_builder.CreateBitCast(v, toType));
 }
示例#13
0
        public void EmitBody()
        {
            uint             hasThis = 0;
            MethodDefinition meth    = _method.Method as MethodDefinition;

            LLVM.Function func = _method.Function;

            // Process parameters
            //
            if (meth.HasThis)
            {
                LLVM.Value val = func.GetParam(0);
                val.Name = "this";
                _params.Add(val);
                hasThis = 1;
            }
            for (uint i = 0; i < meth.Parameters.Count; i++)
            {
                LLVM.Value val = func.GetParam(i + hasThis);
                val.Name = meth.Parameters[(int)i].Name;
                _params.Add(val);
            }

            MethodBody body = meth.Body;

            if (body == null)
            {
                // Method may not have a body. For instance in the case of
                // external methods
                return; // end here
            }
            LLVM.BasicBlock bb = new LLVM.BasicBlock(func, "IL_0000");
            _builder.PositionAtEnd(bb);

            // Process local variables
            //
            if (body.HasVariables)
            {
                _variables = new List <LLVM.Value>();
                foreach (VariableDefinition variable in body.Variables)
                {
                    LLVM.Type ty = Cil2Llvm.GetType(variable.VariableType);

                    // FIXME: check when we want to use pointers and when we
                    // want to use primitive type. Do we want to use struct
                    // for ValueTypes ?
                    //
                    if (!variable.VariableType.IsPrimitive &&
                        !variable.VariableType.IsValueType)
                    {
                        ty = ty.GetPointerTo();
                    }
                    string name = "V_";
                    if (variable.Name.Length != 0)
                    {
                        name = variable.Name;
                    }
                    LLVM.Value val = _builder.CreateAlloca(ty, name);
                    _variables.Add(val);
                }
            }

            // parse all flowcontrol instructions a first time to create
            // basic blocks with the labels these instructions point to.
            //
            List <int> labels = new List <int>();

            foreach (Instruction inst in body.Instructions)
            {
                if (inst.OpCode.OperandType == OperandType.InlineBrTarget ||
                    inst.OpCode.OperandType == OperandType.ShortInlineBrTarget)
                {
                    if (inst.OpCode.FlowControl == FlowControl.Cond_Branch)
                    {
                        labels.Add(inst.Next.Offset);
                    }
                    Instruction br = inst.Operand as Instruction;
                    labels.Add(br.Offset);
                }
            }
            labels.Sort();

            foreach (int offset in labels)
            {
                LLVM.BasicBlock lbl = func.AppendBasicBlock("IL_" + offset.ToString("x4"));
                _labels[offset] = lbl;
            }

            var  lEnum     = labels.GetEnumerator();
            bool hasLabels = lEnum.MoveNext();

            foreach (Instruction inst in body.Instructions)
            {
                Console.WriteLine("{0}", inst);

                if (hasLabels && lEnum.Current == inst.Offset)
                {
                    LLVM.BasicBlock lbl = _labels[inst.Offset];
                    Console.WriteLine("offset " + inst.Offset);
                    if (!bb.HasTerminator)
                    {
                        _builder.CreateBr(lbl);
                    }
                    _builder.PositionAtEnd(lbl);
                    bb = lbl;
                    while (lEnum.Current == inst.Offset &&
                           (hasLabels = lEnum.MoveNext()))
                    {
                    }
                }

//TODO: pre-select instruction by type (flowcontrol, ...)

                if (inst.OpCode == OpCodes.Nop)
                {
                }                               /* Nothing */
                else if (inst.OpCode == OpCodes.Break)
                {
                    EmitUnimplemented();
                }
                else if (inst.OpCode == OpCodes.Ldarg_0)
                {
                    EmitOpCodeLdarg(0);
                }
                else if (inst.OpCode == OpCodes.Ldarg_1)
                {
                    EmitOpCodeLdarg(1);
                }
                else if (inst.OpCode == OpCodes.Ldarg_2)
                {
                    EmitOpCodeLdarg(2);
                }
                else if (inst.OpCode == OpCodes.Ldarg_3)
                {
                    EmitOpCodeLdarg(3);
                }
                else if (inst.OpCode == OpCodes.Ldloc_0)
                {
                    EmitOpCodeLdloc(0);
                }
                else if (inst.OpCode == OpCodes.Ldloc_1)
                {
                    EmitOpCodeLdloc(1);
                }
                else if (inst.OpCode == OpCodes.Ldloc_2)
                {
                    EmitOpCodeLdloc(2);
                }
                else if (inst.OpCode == OpCodes.Ldloc_3)
                {
                    EmitOpCodeLdloc(3);
                }
                else if (inst.OpCode == OpCodes.Stloc_0)
                {
                    EmitOpCodeStloc(0);
                }
                else if (inst.OpCode == OpCodes.Stloc_1)
                {
                    EmitOpCodeStloc(1);
                }
                else if (inst.OpCode == OpCodes.Stloc_2)
                {
                    EmitOpCodeStloc(2);
                }
                else if (inst.OpCode == OpCodes.Stloc_3)
                {
                    EmitOpCodeStloc(3);
                }
                else if (inst.OpCode == OpCodes.Ldnull)
                {
                    EmitUnimplemented();
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_M1)
                {
                    EmitOpCodeLdc(4, Convert.ToInt64(-1));
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_0)
                {
                    EmitOpCodeLdc(4, 0);
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_1)
                {
                    EmitOpCodeLdc(4, 1);
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_2)
                {
                    EmitOpCodeLdc(4, 2);
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_3)
                {
                    EmitOpCodeLdc(4, 3);
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_4)
                {
                    EmitOpCodeLdc(4, 4);
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_5)
                {
                    EmitOpCodeLdc(4, 5);
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_6)
                {
                    EmitOpCodeLdc(4, 6);
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_7)
                {
                    EmitOpCodeLdc(4, 7);
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_8)
                {
                    EmitOpCodeLdc(4, 8);
                }
                else if (inst.OpCode == OpCodes.Dup)
                {
                    EmitOpCodeDup();
                }
                else if (inst.OpCode == OpCodes.Pop)
                {
                    EmitOpCodePop();
                }
                else if (inst.OpCode == OpCodes.Ret)
                {
                    EmitOpCodeRet();
                }

/*
 *          case 0x46:  // ldind.i1
 *          case 0x47:  // ldind.u1
 *          case 0x48:  // ldind.i2
 *          case 0x49:  // ldind.u2
 *          case 0x4A:  // ldind.i4
 *          case 0x4B:  // ldind.u4
 *          case 0x4C:  // ldind.i8,u8
 *          case 0x4D:  // ldind.i
 *          case 0x4E:  // ldind.r4
 *          case 0x4F:  // ldind.r8
 *          case 0x50:  // ldind.ref
 *          case 0x51:  // stind.ref
 *          case 0x52:  // stind.i1
 *          case 0x53:  // stind.i2
 *          case 0x54:  // stind.i4
 *          case 0x55:  // stind.i8
 *          case 0x56:  // stind.r4
 *          case 0x57:  // stind.r8
 */
                else if (inst.OpCode == OpCodes.Call)
                {
                    EmitOpCodeCall(inst.Operand as MethodReference);
                }

                else if (inst.OpCode == OpCodes.Add)
                {
                    EmitOpCodeAdd();
                }
                else if (inst.OpCode == OpCodes.Sub)
                {
                    EmitOpCodeSub();
                }
                else if (inst.OpCode == OpCodes.Mul)
                {
                    EmitOpCodeMul();
                }
                else if (inst.OpCode == OpCodes.Div)
                {
                    EmitOpCodeDiv();
                }
                else if (inst.OpCode == OpCodes.Div_Un)
                {
                    EmitOpCodeDivUn();
                }

                else if (inst.OpCode == OpCodes.And)
                {
                    EmitOpCodeAnd();
                }
                else if (inst.OpCode == OpCodes.Or)
                {
                    EmitOpCodeOr();
                }
                else if (inst.OpCode == OpCodes.Xor)
                {
                    EmitOpCodeXor();
                }
                else if (inst.OpCode == OpCodes.Not)
                {
                    EmitOpCodeNot();
                }

                else if (inst.OpCode == OpCodes.Ldfld)
                {
                    EmitOpCodeLdfld(inst.Operand as FieldReference);
                }
                else if (inst.OpCode == OpCodes.Stfld)
                {
                    EmitOpCodeStfld(inst.Operand as FieldReference);
                }

                else if (inst.OpCode == OpCodes.Bge)
                {
                    EmitOpCodeBge(inst);
                }
                else if (inst.OpCode == OpCodes.Ble)
                {
                    EmitOpCodeBle(inst);
                }
#if UNIMPLEMENTED
/*
 *          case 0x5D:  // rem
 *          case 0x5E:  // rem.un
 *          case 0x62:  // shl
 *          case 0x63:  // shr
 *          case 0x64:  // shr.un
 *          case 0x65:  // neg
 *          case 0x67:  // conv.i1
 *          case 0x68:  // conv.i2
 *          case 0x69:  // conv.i4
 *          case 0x6A:  // conv.i8
 *          case 0x6B:  // conv.r4
 *          case 0x6C:  // conv.r8
 *          case 0x6D:  // conv.u4
 *          case 0x6E:  // conv.u8
 *          case 0x76:  // conv.r.un
 *          case 0x82:  // conv.ovf.i1.un
 *          case 0x83:  // conv.ovfi.i2.un
 *          case 0x84:  // conv.ovf.i4.un
 *          case 0x85:  // conv.ovf.i8.un
 *          case 0x86:  // conv.ovf.u1.un
 *          case 0x87:  // conv.ovf.u2.un
 *          case 0x88:  // conv.ovf.u4.un
 *          case 0x89:  // conv.ovf.u8.un
 *          case 0x8A:  // conv.ovf.i.un
 *          case 0x8B:  // conv.ovf.u.un
 *          case 0xB3:  // conv.ovf.i1
 *          case 0xB4:  // conv.ovf.u1
 *          case 0xB5:  // conv.ovfi.i2
 *          case 0xB6:  // conv.ovf.u2
 *          case 0xB7:  // conv.ovf.i4
 *          case 0xB8:  // conv.ovf.u4
 *          case 0xB9:  // conv.ovf.i8
 *          case 0xBA:  // conv.ovf.u8
 *          case 0xC3:  // ckfinite
 *          case 0xD1:  // conv.u2
 *          case 0xD2:  // conv.u1
 *          case 0xD3:  // conv.i (native int)
 *          case 0xD4:  // conv.ovf.i
 *          case 0xD5:  // conv.ovf.u
 *          case 0xD6:  // add.ovf
 *          case 0xD7:  // add.ovf.un
 *          case 0xD8:  // mul.ovf
 *          case 0xD9:  // mul.ovf.un
 *          case 0xDA:  // sub.ovf
 *          case 0xDB:  // sub.ovf.un
 *          case 0xDC:  // endfault, endfinally
 *          case 0xDD:  // leave
 *          case 0xDE:  // leave.s
 *          case 0xDF:  // stind.i
 *          case 0xE0:  // conv.u (native int)
 *
 */
#endif
                else if (inst.OpCode == OpCodes.Newobj)
                {
                    EmitOpCodeNewobj(inst.Operand as MethodReference);
                }
                else if (inst.OpCode == OpCodes.Ldc_I4_S)
                {
                    EmitOpCodeLdc(4, Convert.ToInt64(inst.Operand));
                }
                else if (inst.OpCode == OpCodes.Ldc_I4)
                {
                    EmitOpCodeLdc(4, Convert.ToInt64(inst.Operand));
                }
                else
                {
                    EmitUnimplemented();
                }
            }
        }