示例#1
0
        public Type(TypeReference typeReference, TypeDefinition typeDefinition, TypeRef dataType, TypeRef valueType, TypeRef objectType, StackValueType stackType)
        {
            TypeReferenceCecil  = typeReference;
            TypeDefinitionCecil = typeDefinition;
            DataTypeLLVM        = dataType;
            ObjectTypeLLVM      = objectType;
            StackType           = stackType;
            ValueTypeLLVM       = valueType;
            DefaultTypeLLVM     = stackType == StackValueType.Object ? LLVM.PointerType(ObjectTypeLLVM, 0) : DataTypeLLVM;

            switch (stackType)
            {
            case StackValueType.NativeInt:
                TypeOnStackLLVM = LLVM.PointerType(LLVM.Int8TypeInContext(LLVM.GetTypeContext(dataType)), 0);
                break;

            case StackValueType.Float:
                TypeOnStackLLVM = LLVM.DoubleTypeInContext(LLVM.GetTypeContext(dataType));
                break;

            case StackValueType.Int32:
                TypeOnStackLLVM = LLVM.Int32TypeInContext(LLVM.GetTypeContext(dataType));
                break;

            case StackValueType.Int64:
                TypeOnStackLLVM = LLVM.Int64TypeInContext(LLVM.GetTypeContext(dataType));
                break;

            case StackValueType.Value:
            case StackValueType.Object:
            case StackValueType.Reference:
                TypeOnStackLLVM = DefaultTypeLLVM;
                break;
            }
        }
示例#2
0
        private ValueRef AllocateObject(Type type, StackValueType stackValueType = StackValueType.Unknown)
        {
            if (stackValueType == StackValueType.Unknown)
            {
                stackValueType = type.StackType;
            }

            // Resolve class
            var @class = GetClass(type);

            if (stackValueType != StackValueType.Object)
            {
                // Value types are allocated on the stack
                return(LLVM.BuildAlloca(builder, type.DataType, string.Empty));
            }

            // TODO: Improve performance (better inlining, etc...)
            // Invoke malloc
            var typeSize        = LLVM.BuildIntCast(builder, LLVM.SizeOf(type.ObjectType), int32Type, string.Empty);
            var allocatedData   = LLVM.BuildCall(builder, allocObjectFunction, new[] { typeSize }, string.Empty);
            var allocatedObject = LLVM.BuildPointerCast(builder, allocatedData, LLVM.PointerType(type.ObjectType, 0), string.Empty);

            // Store vtable global into first field of the object
            var indices = new[]
            {
                LLVM.ConstInt(int32Type, 0, false),                                     // Pointer indirection
                LLVM.ConstInt(int32Type, (int)ObjectFields.RuntimeTypeInfo, false),     // Access RTTI
            };

            var vtablePointer = LLVM.BuildInBoundsGEP(builder, allocatedObject, indices, string.Empty);

            LLVM.BuildStore(builder, @class.GeneratedRuntimeTypeInfoGlobal, vtablePointer);
            return(allocatedObject);
        }
示例#3
0
 public void Push(StackValueType vtype, long *obj)
 {
     *(long *)Esp->VPoint = *obj;
     Esp->ValueType       = vtype;
     Esp++;
     EspI++;
 }
示例#4
0
        private ValueRef LoadValue(StackValueType stackType, ValueRef value, InstructionFlags instructionFlags)
        {
            // Load value from local (indirect values are kept as pointer)
            if (stackType == StackValueType.Value)
            {
                // Option1: Make a copy
                // TODO: Optimize stack allocation (reuse alloca slots, with help of FunctionStack)
                var result = LLVM.BuildAlloca(builderAlloca, LLVM.GetElementType(LLVM.TypeOf(value)), string.Empty);
                var valueCopy = LLVM.BuildLoad(builder, value, string.Empty);
                LLVM.BuildStore(builder, valueCopy, result);

                SetInstructionFlags(valueCopy, instructionFlags);
                
                return result;

                // Option2: Return pointer as is
                //return value;
            }
            else
            {
                var result = LLVM.BuildLoad(builder, value, string.Empty);
                SetInstructionFlags(result, instructionFlags);

                return result;
            }
        }
示例#5
0
        public void EvaluationStack_Push(StackValueType vtype, object value)
        {
            switch (vtype)
            {
            case StackValueType.Ref:
                EvaluationStack_Push(value);
                break;

            case StackValueType.Ptr:
                EvaluationStack_Push(value);
                break;

            case StackValueType.i8:
                EvaluationStack_Push((long)value);
                break;

            case StackValueType.r8:
                EvaluationStack_Push((double)value);
                break;

            case StackValueType.i4:
                EvaluationStack_Push((int)value);
                break;

            case StackValueType.r4:
                EvaluationStack_Push((float)value);
                break;
            }
        }
示例#6
0
 public void Push(StackValueType vtype, int *obj)
 {
     Esp->ValueType = vtype;
     *Esp->VPoint = *obj;
     Esp++;
     EspI++;
 }
示例#7
0
        public Type(TypeReference typeReference, TypeRef dataType, TypeRef objectType, StackValueType stackType)
        {
            TypeReference = typeReference;
            DataType = dataType;
            ObjectType = objectType;
            StackType = stackType;
            DefaultType = stackType == StackValueType.Object ? LLVM.PointerType(ObjectType, 0) : DataType;
            StackType = stackType;

            switch (stackType)
            {
                case StackValueType.NativeInt:
                    TypeOnStack = LLVM.PointerType(LLVM.Int8TypeInContext(LLVM.GetTypeContext(dataType)), 0);
                    break;
                case StackValueType.Float:
                    TypeOnStack = LLVM.DoubleTypeInContext(LLVM.GetTypeContext(dataType));
                    break;
                case StackValueType.Int32:
                    TypeOnStack = LLVM.Int32TypeInContext(LLVM.GetTypeContext(dataType));
                    break;
                case StackValueType.Int64:
                    TypeOnStack = LLVM.Int64TypeInContext(LLVM.GetTypeContext(dataType));
                    break;
                case StackValueType.Value:
                case StackValueType.Object:
                case StackValueType.Reference:
                    TypeOnStack = DefaultType;
                    break;
            }
        }
示例#8
0
        public void Push(StackValueType vtype, int value)
        {
            var p = EvaluationStack[Esp++];

            p.ValueType = vtype;
            p.IntValue  = value;
        }
示例#9
0
        public Type(TypeReference typeReference, TypeDefinition typeDefinition, TypeRef dataType, TypeRef valueType, TypeRef objectType, StackValueType stackType)
        {
            TypeReferenceCecil = typeReference;
            TypeDefinitionCecil = typeDefinition;
            DataTypeLLVM = dataType;
            ObjectTypeLLVM = objectType;
            StackType = stackType;
            ValueTypeLLVM = valueType;
            DefaultTypeLLVM = stackType == StackValueType.Object ? LLVM.PointerType(ObjectTypeLLVM, 0) : DataTypeLLVM;

            switch (stackType)
            {
                case StackValueType.NativeInt:
                    TypeOnStackLLVM = LLVM.PointerType(LLVM.Int8TypeInContext(LLVM.GetTypeContext(dataType)), 0);
                    break;
                case StackValueType.Float:
                    TypeOnStackLLVM = LLVM.DoubleTypeInContext(LLVM.GetTypeContext(dataType));
                    break;
                case StackValueType.Int32:
                    TypeOnStackLLVM = LLVM.Int32TypeInContext(LLVM.GetTypeContext(dataType));
                    break;
                case StackValueType.Int64:
                    TypeOnStackLLVM = LLVM.Int64TypeInContext(LLVM.GetTypeContext(dataType));
                    break;
                case StackValueType.Value:
                case StackValueType.Object:
                case StackValueType.Reference:
                    TypeOnStackLLVM = DefaultTypeLLVM;
                    break;
            }
        }
示例#10
0
        private void StoreValue(StackValueType stackType, ValueRef value, ValueRef dest, InstructionFlags instructionFlags)
        {
            if (stackType == StackValueType.Value)
                value = LLVM.BuildLoad(builder, value, string.Empty);

            var store = LLVM.BuildStore(builder, value, dest);
            SetInstructionFlags(store, instructionFlags);
        }
示例#11
0
 public Type(TypeReference typeReference, TypeRef dataType, TypeRef objectType, StackValueType stackType)
 {
     TypeReference = typeReference;
     DataType      = dataType;
     ObjectType    = objectType;
     StackType     = stackType;
     DefaultType   = stackType == StackValueType.Object ? LLVM.PointerType(ObjectType, 0) : DataType;
     StackType     = stackType;
 }
示例#12
0
 public void EvaluationStack_Push(StackValueType vtype, object value)
 {
     if (vtype == StackValueType.i4)
     {
         Stack.Push(vtype, (int)value);
     }
     else
     {
         Stack.Push(vtype, value);
     }
 }
示例#13
0
        public void CopyFrom(StackItem stackItem)
        {
            Index    = stackItem.Index;
            IntValue = stackItem.IntValue;
            LValue   = stackItem.LValue;
            Ptr      = stackItem.Ptr;
#if JS
            VPoint = stackItem.VPoint;
#endif
            ValueType = stackItem.ValueType;
        }
示例#14
0
        public virtual void Ldc(ref StackValueType vtype, ref object value)
#endif
        {
            if (value is string)
            {
                value = Extensions.GetValueFromStr(value as string, vtype);
            }

            {
                EvaluationStack_Push(vtype, value);
            }
        }
示例#15
0
        /// <summary>
        /// 将位于指定数组索引处的 int8 类型的元素作为 int32 加载到计算堆栈的顶部。
        /// </summary>
        /// <param name="type"></param>
        public void Ldelem(StackValueType type)
        {
            var vs = EvaluationStack_Pop(2);

#if JS
            var array = (vs).Ptr.Object as Array;
            var index = (vs + 1).IntValue;
#else
            var array = ((StackObject)(vs)->Ptr.Target).Object as Array;
            var index = (vs + 1)->IntValue;
#endif
            EvaluationStack_Push(type, array.GetValue(index));
        }
示例#16
0
        /// <summary>
        /// 存储所提供地址处的对象引用值
        /// </summary>
        /// <param name="type"></param>
        public void Stind(StackValueType type)
        {
            var vs  = Stack.Pop(2);
            var vsv = vs + 1;

#if JS
            switch (vs.ValueType)
            {
            case StackValueType.Array:
            {
                var array = vs.Ptr.Object as Array;
                array.SetValue(vsv.Value, vs.Index);
                break;
            }

            case StackValueType.i4:
            case StackValueType.r4:
            case StackValueType.i8:
            case StackValueType.r8:
            case StackValueType.Ref:
            {
                break;
            }

            default:
                throw new NotSupportedException();
            }
#else
            switch (vs->ValueType)
            {
            case StackValueType.Array:
            {
                var array = ((StackObject)vs->Ptr.Target).Object as Array;
                array.SetValue(vsv->Value, vs->Index);
                break;
            }

            case StackValueType.i4:
            case StackValueType.r4:
            case StackValueType.i8:
            case StackValueType.r8:
            case StackValueType.Ref:
            {
                break;
            }

            default:
                throw new NotSupportedException();
            }
#endif
        }
示例#17
0
        public void Push(StackValueType vtype, object value)
        {
            var p = EvaluationStack[Esp++];

            if (vtype == StackValueType.Ref || vtype == StackValueType.i4)
            {
                throw new NotSupportedException();
            }
            else
            {
                p.ValueType = vtype;
                p.VPoint    = value;
            }
        }
示例#18
0
        /// <summary>
        /// 将 int8 类型的值作为 int32 间接加载到计算堆栈上。
        /// </summary>
        /// <param name="type"></param>
        public void Ldind(StackValueType type)
        {
            var vs = Stack.Top();

#if JS
            switch (vs.ValueType)
            {
            case StackValueType.Array:
            {
                var array = vs.Ptr.Object as Array;
                vs.SetValue(type, array.GetValue(vs.Index));
                break;
            }

            case StackValueType.i4:
            case StackValueType.r4:
            case StackValueType.i8:
            case StackValueType.r8:
            case StackValueType.Ref:
            {
                break;
            }

            default:
                throw new NotSupportedException();
            }
#else
            switch (vs->ValueType)
            {
            case StackValueType.Array:
            {
                var array = ((StackObject)vs->Ptr.Target).Object as Array;
                vs->SetValue(type, array.GetValue(vs->Index));
                break;
            }

            case StackValueType.i4:
            case StackValueType.r4:
            case StackValueType.i8:
            case StackValueType.r8:
            case StackValueType.Ref:
            {
                break;
            }

            default:
                throw new NotSupportedException();
            }
#endif
        }
示例#19
0
        private ValueRef[] BuildFieldIndices(Field field, StackValueType stackValueType, Type type)
        {
            // Build indices for GEP
            var indices = new List <ValueRef>(3);

            if (stackValueType == StackValueType.Reference || stackValueType == StackValueType.Object || stackValueType == StackValueType.NativeInt)
            {
                // First pointer indirection
                indices.Add(LLVM.ConstInt(int32Type, 0, false));
            }

            if (stackValueType == StackValueType.Object)
            {
                // Access data
                indices.Add(LLVM.ConstInt(int32Type, (int)ObjectFields.Data, false));

                // For now, go through hierarchy and check that type match
                // Other options:
                // - cast
                // - store class depth (and just do a substraction)
                int depth  = 0;
                var @class = GetClass(type);
                while (@class != null)
                {
                    if (@class == field.DeclaringClass)
                    {
                        break;
                    }

                    @class = @class.BaseType;
                    depth++;
                }

                if (@class == null)
                {
                    throw new InvalidOperationException(string.Format("Could not find field {0} in hierarchy of {1}", field.FieldDefinition, type.TypeReference));
                }

                // Apply GEP indices to find right object (parent is always stored in first element)
                for (int i = 0; i < depth; ++i)
                {
                    indices.Add(LLVM.ConstInt(int32Type, 0, false));
                }
            }

            // Access the appropriate field
            indices.Add(LLVM.ConstInt(int32Type, (uint)field.StructIndex, false));
            return(indices.ToArray());
        }
示例#20
0
 public StackValueOperation(StackValueOperationType type, StackValueType valueType,
                            IEnumerable <StackValue> operands)
 {
     ProcessedValue = true;
     ValueType      = valueType;
     if (operands == null)
     {
         Operands = new List <StackValue>();
     }
     else
     {
         Operands = new List <StackValue>(operands);
     }
     OperationType = type;
 }
示例#21
0
 public StackValueOperation(StackValueOperationType type, StackValueType valueType,
                            IEnumerable<StackValue> operands)
 {
     ProcessedValue = true;
     ValueType = valueType;
     if (operands == null)
     {
         Operands = new List<StackValue>();
     }
     else
     {
         Operands = new List<StackValue>(operands);
     }
     OperationType = type;
 }
示例#22
0
        /// <summary>
        /// 用计算堆栈上的 native int 值替换给定索引处的数组元素。
        /// </summary>
        public void Stelem(StackValueType type)
        {
            var vs = EvaluationStack_Pop(3);

#if JS
            var array = vs.Ptr.Object as Array;
            var index = (vs + 1).IntValue;
            var optr  = (vs + 1 + 1);
            switch (optr.ValueType)
            {
            case StackValueType.Ref:
            {
                var obj = optr.Ptr.Object;
                array.SetValue(obj, index);
                break;
            }

            default:
            {
                var obj = optr.Value;
                array.SetValue(obj, index);
                break;
            }
            }
#else
            var array = ((StackObject)(vs)->Ptr.Target).Object as Array;
            var index = (vs + 1)->IntValue;


            var optr = (vs + 1 + 1);
            switch (optr->ValueType)
            {
            case StackValueType.Ref:
            {
                var obj = ((StackObject)optr->Ptr.Target).Object;
                array.SetValue(obj, index);
                break;
            }

            default:
            {
                var obj = optr->Value;
                array.SetValue(obj, index);
                break;
            }
            }
#endif
        }
示例#23
0
        public void SetValue(StackValueType vtype, object value)
        {
            switch (vtype)
            {
            case StackValueType.i4:
            {
                IntValue = (int)value;
                break;
            }

            case StackValueType.r4:
            case StackValueType.i8:
            case StackValueType.r8:
                VPoint = value;
                break;
            }
        }
示例#24
0
        public void SetValue(StackValueType vtype, object value, bool settype = false)
        {
            switch (vtype)
            {
            case StackValueType.i4:
            {
                IntValue = (int)value;
                break;
            }

            case StackValueType.r4:
            {
                var v = (float)value;
                *(float *)VPoint = v;
                break;
            }

            case StackValueType.i8:
            {
                var v = (long)value;
                *(long *)VPoint = v;
                break;
            }

            case StackValueType.r8:
            {
                var v = (double)value;
                *(double *)VPoint = v;
                break;
            }

            case  StackValueType.Ref:
            {
                Ptr = StackObject.NewObject(value);
                break;
            }
            }

            if (settype)
            {
                ValueType = vtype;
            }
        }
示例#25
0
        public Class(Type type, TypeReference typeReference, TypeRef dataType, TypeRef objectType, StackValueType stackType)
        {
            Type          = type;
            TypeReference = typeReference;
            DataType      = dataType;
            ObjectType    = objectType;
            StackType     = stackType;
            DefaultType   = stackType == StackValueType.Object ? LLVM.PointerType(ObjectType, 0) : DataType;
            Fields        = new Dictionary <FieldDefinition, Field>();
            VirtualTable  = new List <Function>();
            Functions     = new List <Function>();
            Interfaces    = new HashSet <Class>();

            switch (stackType)
            {
            case StackValueType.NativeInt:
                TypeOnStack = LLVM.PointerType(LLVM.Int8TypeInContext(LLVM.GetTypeContext(dataType)), 0);
                break;

            case StackValueType.Float:
                TypeOnStack = LLVM.DoubleTypeInContext(LLVM.GetTypeContext(dataType));
                break;

            case StackValueType.Int32:
                TypeOnStack = LLVM.Int32TypeInContext(LLVM.GetTypeContext(dataType));
                break;

            case StackValueType.Int64:
                TypeOnStack = LLVM.Int64TypeInContext(LLVM.GetTypeContext(dataType));
                break;

            case StackValueType.Value:
            case StackValueType.Object:
                TypeOnStack = DefaultType;
                break;

            default:
                throw new NotImplementedException();
            }
        }
示例#26
0
        public static object GetValueFromStr(string str, StackValueType vtype)
        {
            object value = null;

            switch (vtype)
            {
            case StackValueType.i8:
                value = long.Parse(str);
                break;

            case StackValueType.r8:
                value = double.Parse(str);
                break;

            case StackValueType.i4:
                if (str.StartsWith("0x"))
                {
                    value = System.Convert.ToInt32(str, 16);
                }
                else if (str.StartsWith("M") || str.StartsWith("m"))
                {
                    value = (-int.Parse(str));
                }
                else
                {
                    value = int.Parse(str);
                }

                break;

            case StackValueType.r4:
                value = float.Parse(str);
                break;
            }

            return(value);
        }
示例#27
0
 public void PushType(StackValueType vtype)
 {
     Esp->ValueType = vtype;
 }
示例#28
0
        private ValueRef AllocateObject(Type type, StackValueType stackValueType = StackValueType.Unknown)
        {
            if (stackValueType == StackValueType.Unknown)
                stackValueType = type.StackType;

            // Resolve class
            var @class = GetClass(type);

            if (stackValueType != StackValueType.Object)
            {
                // Value types are allocated on the stack
                return LLVM.BuildAlloca(builderAlloca, type.DataTypeLLVM, string.Empty);
            }

            // TODO: Improve performance (better inlining, etc...)
            // Invoke malloc
            var typeSize = LLVM.BuildIntCast(builder, LLVM.SizeOf(type.ObjectTypeLLVM), nativeIntLLVM, string.Empty);
            var allocatedData = LLVM.BuildCall(builder, allocObjectFunctionLLVM, new[] { typeSize }, string.Empty);
            var allocatedObject = LLVM.BuildPointerCast(builder, allocatedData, LLVM.PointerType(type.ObjectTypeLLVM, 0), string.Empty);

            SetupVTable(allocatedObject, @class);
            return allocatedObject;
        }
示例#29
0
        /// <summary>
        /// 存储所提供地址处的对象引用值
        /// </summary>
        /// <param name="type"></param>
        public void Stind(StackValueType type)
        {
            var vs  = Stack.Pop(2);
            var vsv = vs + 1;

#if JS
            switch (vs.ValueType)
            {
            case StackValueType.Array:
            {
                var array = vs.Ptr.Object as Array;
                array.SetValue(vsv.Value, vs.Index);
                break;
            }

            case StackValueType.i4:
            case StackValueType.r4:
            case StackValueType.i8:
            case StackValueType.r8:
            case StackValueType.Ref:
            {
                break;
            }

            default:
                throw new NotSupportedException();
            }
#else
            if (vs->ValueType == StackValueType.Ref)
            {
                var value = StackObject.ToObject(vs);
                if (value is IntPtr)
                {
                    var si = (StackItem *)((IntPtr)value).ToPointer();
                    vs = si;
                }
                else
                {
                }
            }

            switch (vs->ValueType)
            {
            case StackValueType.Array:
            {
                var array = ((StackObject)vs->Ptr.Target).Object as Array;
                array.SetValue(vsv->Value, vs->Index);
                break;
            }

            case StackValueType.i4:
            case StackValueType.r4:
            case StackValueType.i8:
            case StackValueType.r8:
            {
                vs->SetValue(vsv->ValueType, vsv->Value, true);
                break;
            }

            case StackValueType.Ref:
            {
                break;
            }

            default:
                throw new NotSupportedException();
            }
#endif
        }
示例#30
0
        /// <summary>
        /// 将 int8 类型的值作为 int32 间接加载到计算堆栈上。
        /// </summary>
        /// <param name="type"></param>
        public void Ldind(StackValueType type)
        {
            var vs = Stack.Pop();

#if JS
            switch (vs.ValueType)
            {
            case StackValueType.Array:
            {
                var array = vs.Ptr.Object as Array;
                vs.SetValue(type, array.GetValue(vs.Index));
                break;
            }

            case StackValueType.i4:
            case StackValueType.r4:
            case StackValueType.i8:
            case StackValueType.r8:
            case StackValueType.Ref:
            {
                break;
            }

            default:
                throw new NotSupportedException();
            }
#else
            if (vs->ValueType == StackValueType.Ref)
            {
                var value = StackObject.ToObject(vs);
                if (value is IntPtr)
                {
                    var si = (StackItem *)((IntPtr)value).ToPointer();
                    vs = si;
                }
                else
                {
                }
            }

            switch (vs->ValueType)
            {
            case StackValueType.Array:
            {
                var array = ((StackObject)vs->Ptr.Target).Object as Array;
                vs->SetValue(type, array.GetValue(vs->Index));
                break;
            }

            case StackValueType.i4:
                EvaluationStack_Push((int)(vs)->Value);
                break;

            case StackValueType.r4:
                EvaluationStack_Push((float)(vs)->Value);
                break;

            case StackValueType.i8:
                EvaluationStack_Push((long)(vs)->Value);
                break;

            case StackValueType.r8:
            {
                EvaluationStack_Push((double)(vs)->Value);
                break;
            }

            case StackValueType.Ref:
            {
                break;
            }

            default:
                throw new NotSupportedException();
            }
#endif
        }
示例#31
0
        /// <summary>
        /// 将位于计算堆栈顶部的值转换为Type
        /// </summary>
        /// <param name="type"></param>
        public void Conv(StackValueType type)
        {
            var v = EvaluationStack_Pop();

#if JS
            object value = v.IntValue;
            if (v.ValueType != StackValueType.i4)
            {
                value = v.VPoint;
            }
#if !BRIDGE
            value = Convert.ChangeType(value, conveTypes[(int)type]);
#else
            switch (type)
            {
            case StackValueType.u1:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                    value = (int)(byte)v.IntValue;
                    break;

                case StackValueType.i8:
                    value = (int)(byte)v.ValueLong;
                    break;

                case StackValueType.r4:
                    value = (int)(byte)v.ValueFloat;
                    break;

                case StackValueType.r8:
                    value = (int)(byte)v.ValueDouble;
                    break;
                }
                break;

            case StackValueType.i1:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                    value = (int)(sbyte)v.IntValue;
                    break;

                case StackValueType.i8:
                    value = (int)(sbyte)v.ValueLong;
                    break;

                case StackValueType.r4:
                    value = (int)(sbyte)v.ValueFloat;
                    break;

                case StackValueType.r8:
                    value = (int)(sbyte)v.ValueDouble;
                    break;
                }
                break;

            case StackValueType.u2:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                    value = (int)(ushort)v.IntValue;
                    break;

                case StackValueType.i8:
                    value = (int)(ushort)v.ValueLong;
                    break;

                case StackValueType.r4:
                    value = (int)(ushort)v.ValueFloat;
                    break;

                case StackValueType.r8:
                    value = (int)(ushort)v.ValueDouble;
                    break;
                }
                break;

            case StackValueType.i2:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                    value = (int)(short)v.IntValue;
                    break;

                case StackValueType.i8:
                    value = (int)(short)v.ValueLong;
                    break;

                case StackValueType.r4:
                    value = (int)(short)v.ValueFloat;
                    break;

                case StackValueType.r8:
                    value = (int)(short)v.ValueDouble;
                    break;
                }
                break;

            case StackValueType.u4:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                    value = (int)(uint)v.IntValue;
                    break;

                case StackValueType.i8:
                    value = (int)(uint)v.ValueLong;
                    break;

                case StackValueType.r4:
                    value = (int)(uint)v.ValueFloat;
                    break;

                case StackValueType.r8:
                    value = (int)(uint)v.ValueDouble;
                    break;
                }
                break;

            case StackValueType.i4:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                    value = (int)v.IntValue;
                    break;

                case StackValueType.i8:
                    value = (int)v.ValueLong;
                    break;

                case StackValueType.r4:
                    value = (int)v.ValueFloat;
                    break;

                case StackValueType.r8:
                    value = (int)v.ValueDouble;
                    break;
                }
                break;

            case StackValueType.r4:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                {
                    value = (float)v.IntValue;

                    break;
                }

                case StackValueType.i8:
                {
                    value = (float)v.ValueLong;

                    break;
                }

                case StackValueType.r4:
                {
                    value = (float)v.ValueFloat;

                    break;
                }

                case StackValueType.r8:
                {
                    value = (float)v.ValueDouble;

                    break;
                }
                }
                break;

            case StackValueType.u8:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                {
                    value = (ulong)v.IntValue;

                    break;
                }

                case StackValueType.i8:
                {
                    value = (ulong)v.ValueLong;

                    break;
                }

                case StackValueType.r4:
                {
                    value = (ulong)v.ValueFloat;

                    break;
                }

                case StackValueType.r8:
                {
                    value = (ulong)v.ValueDouble;

                    break;
                }
                }
                break;

            case StackValueType.i8:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                {
                    value = (long)v.IntValue;

                    break;
                }

                case StackValueType.i8:
                {
                    value = (long)v.ValueLong;

                    break;
                }

                case StackValueType.r4:
                {
                    value = (long)v.ValueFloat;

                    break;
                }

                case StackValueType.r8:
                {
                    value = (long)v.ValueDouble;

                    break;
                }
                }
                break;

            case StackValueType.r8:
                switch (v.ValueType)
                {
                case StackValueType.i4:
                {
                    value = (double)v.IntValue;

                    break;
                }

                case StackValueType.i8:
                {
                    value = (double)v.ValueLong;

                    break;
                }

                case StackValueType.r4:
                {
                    value = (double)v.ValueFloat;

                    break;
                }

                case StackValueType.r8:
                {
                    value = (double)v.ValueDouble;

                    break;
                }
                }
                break;
            }
#endif
            switch (type)
            {
            case StackValueType.i8:
            case StackValueType.r8:
            case StackValueType.r4:
                EvaluationStack_Push(type, value);
                break;

            default:
                EvaluationStack_Push(type, (int)value);
                break;
            }
#else
            var rv = new StackItem();
            rv.VPoint = &rv.IntValue;
            switch (type)
            {
            case StackValueType.u1:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                    rv.IntValue = (byte)v->IntValue;
                    break;

                case StackValueType.i8:
                    rv.IntValue = (byte)v->ValueLong;
                    break;

                case StackValueType.r4:
                    rv.IntValue = (byte)v->ValueFloat;
                    break;

                case StackValueType.r8:
                    rv.IntValue = (byte)v->ValueDouble;
                    break;
                }
                break;

            case StackValueType.i1:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                    rv.IntValue = (sbyte)v->IntValue;
                    break;

                case StackValueType.i8:
                    rv.IntValue = (sbyte)v->ValueLong;
                    break;

                case StackValueType.r4:
                    rv.IntValue = (sbyte)v->ValueFloat;
                    break;

                case StackValueType.r8:
                    rv.IntValue = (sbyte)v->ValueDouble;
                    break;
                }
                break;

            case StackValueType.u2:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                    rv.IntValue = (ushort)v->IntValue;
                    break;

                case StackValueType.i8:
                    rv.IntValue = (ushort)v->ValueLong;
                    break;

                case StackValueType.r4:
                    rv.IntValue = (ushort)v->ValueFloat;
                    break;

                case StackValueType.r8:
                    rv.IntValue = (ushort)v->ValueDouble;
                    break;
                }
                break;

            case StackValueType.i2:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                    rv.IntValue = (short)v->IntValue;
                    break;

                case StackValueType.i8:
                    rv.IntValue = (short)v->ValueLong;
                    break;

                case StackValueType.r4:
                    rv.IntValue = (short)v->ValueFloat;
                    break;

                case StackValueType.r8:
                    rv.IntValue = (short)v->ValueDouble;
                    break;
                }
                break;

            case StackValueType.u4:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                    rv.IntValue = (int)(uint)v->IntValue;
                    break;

                case StackValueType.i8:
                    rv.IntValue = (int)(uint)v->ValueLong;
                    break;

                case StackValueType.r4:
                    rv.IntValue = (int)(uint)v->ValueFloat;
                    break;

                case StackValueType.r8:
                    rv.IntValue = (int)(uint)v->ValueDouble;
                    break;
                }
                break;

            case StackValueType.i4:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                    rv.IntValue = (int)v->IntValue;
                    break;

                case StackValueType.i8:
                    rv.IntValue = (int)v->ValueLong;
                    break;

                case StackValueType.r4:
                    rv.IntValue = (int)v->ValueFloat;
                    break;

                case StackValueType.r8:
                    rv.IntValue = (int)v->ValueDouble;
                    break;
                }
                break;

            case StackValueType.r4:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                {
                    var f = (float)v->IntValue;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.i8:
                {
                    var f = (float)v->ValueLong;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.r4:
                {
                    var f = (float)v->ValueFloat;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.r8:
                {
                    var f = (float)v->ValueDouble;
                    rv.VPoint = (int *)&f;
                    break;
                }
                }
                break;

            case StackValueType.u8:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                {
                    var f = (ulong)v->IntValue;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.i8:
                {
                    var f = (ulong)v->ValueLong;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.r4:
                {
                    var f = (ulong)v->ValueFloat;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.r8:
                {
                    var f = (ulong)v->ValueDouble;
                    rv.VPoint = (int *)&f;
                    break;
                }
                }
                break;

            case StackValueType.i8:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                {
                    var f = (long)v->IntValue;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.i8:
                {
                    var f = (long)v->ValueLong;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.r4:
                {
                    var f = (long)v->ValueFloat;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.r8:
                {
                    var f = (long)v->ValueDouble;
                    rv.VPoint = (int *)&f;
                    break;
                }
                }
                break;

            case StackValueType.r8:
                switch (v->ValueType)
                {
                case StackValueType.i4:
                {
                    var f = (double)v->IntValue;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.i8:
                {
                    var f = (double)v->ValueLong;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.r4:
                {
                    var f = (double)v->ValueFloat;
                    rv.VPoint = (int *)&f;
                    break;
                }

                case StackValueType.r8:
                {
                    var f = (double)v->ValueDouble;
                    rv.VPoint = (int *)&f;
                    break;
                }
                }
                break;
            }
            EvaluationStack_Push(&rv);
#endif
        }
示例#32
0
        private ValueRef[] BuildFieldIndices(Field field, StackValueType stackValueType, Type type)
        {
            // Build indices for GEP
            var indices = new List<ValueRef>(3);

            if (stackValueType == StackValueType.Reference || stackValueType == StackValueType.Object || stackValueType == StackValueType.NativeInt)
            {
                // First pointer indirection
                indices.Add(LLVM.ConstInt(int32Type, 0, false));
            }

            if (stackValueType == StackValueType.Object)
            {
                // Access data
                indices.Add(LLVM.ConstInt(int32Type, (int)ObjectFields.Data, false));

                // For now, go through hierarchy and check that type match
                // Other options:
                // - cast
                // - store class depth (and just do a substraction)
                int depth = 0;
                var @class = GetClass(type);
                while (@class != null)
                {
                    if (@class == field.DeclaringClass)
                        break;

                    @class = @class.BaseType;
                    depth++;
                }

                if (@class == null)
                    throw new InvalidOperationException(string.Format("Could not find field {0} in hierarchy of {1}", field.FieldDefinition, type.TypeReference));

                // Apply GEP indices to find right object (parent is always stored in first element)
                for (int i = 0; i < depth; ++i)
                    indices.Add(LLVM.ConstInt(int32Type, 0, false));
            }

            // Access the appropriate field
            indices.Add(LLVM.ConstInt(int32Type, (uint)field.StructIndex, false));
            return indices.ToArray();
        }
示例#33
0
 public StackValue(StackValueType stackType, Type type, ValueRef value)
 {
     StackType = stackType;
     Type      = type;
     Value     = value;
 }
示例#34
0
        private ValueRef ComputeFieldAddress(BuilderRef builder, Field field, StackValueType objectStackType, ValueRef objectValue, ref InstructionFlags instructionFlags)
        {
            objectValue = ConvertReferenceToExpectedType(builder, objectStackType, objectValue, field.DeclaringType);
            Type type = field.DeclaringType;

            // Build indices for GEP
            var indices = new List<ValueRef>(3);

            if (objectStackType == StackValueType.Reference || objectStackType == StackValueType.Object || objectStackType == StackValueType.Value || objectStackType == StackValueType.NativeInt)
            {
                // First pointer indirection
                indices.Add(LLVM.ConstInt(int32LLVM, 0, false));
            }

            bool isCustomLayout = IsCustomLayout(type.TypeDefinitionCecil);

            if (objectStackType == StackValueType.Object)
            {
                // Access data
                indices.Add(LLVM.ConstInt(int32LLVM, (int)ObjectFields.Data, false));

                if (!isCustomLayout)
                {
                    // For now, go through hierarchy and check that type match
                    // Other options:
                    // - cast
                    // - store class depth (and just do a substraction)
                    int depth = 0;
                    var @class = GetClass(type);
                    while (@class != null)
                    {
                        if (@class.Type == field.DeclaringType)
                            break;

                        @class = @class.BaseType;
                        depth++;
                    }

                    if (@class == null)
                        throw new InvalidOperationException(string.Format("Could not find field {0} in hierarchy of {1}", field.FieldDefinition, type.TypeReferenceCecil));

                    // Apply GEP indices to find right object (parent is always stored in first element)
                    for (int i = 0; i < depth; ++i)
                        indices.Add(LLVM.ConstInt(int32LLVM, 0, false));
                }
            }

            // Access the appropriate field
            indices.Add(LLVM.ConstInt(int32LLVM, (uint)field.StructIndex, false));

            // Find field address using GEP
            var fieldAddress = LLVM.BuildInBoundsGEP(builder, objectValue, indices.ToArray(), string.Empty);

            // Cast to real field type (if stored in a custom layout array)
            if (isCustomLayout)
            {
                fieldAddress = LLVM.BuildPointerCast(builder, fieldAddress, LLVM.PointerType(field.Type.DefaultTypeLLVM, 0), string.Empty);

                // Check if non aligned
                if (field.StructIndex % 4 != 0)
                    instructionFlags = InstructionFlags.Unaligned;
            }

            return fieldAddress;
        }
示例#35
0
        private ValueRef AllocateObject(Type type, StackValueType stackValueType = StackValueType.Unknown)
        {
            if (stackValueType == StackValueType.Unknown)
                stackValueType = type.StackType;

            // Resolve class
            var @class = GetClass(type);

            if (stackValueType != StackValueType.Object)
            {
                // Value types are allocated on the stack
                return LLVM.BuildAlloca(builder, type.DataType, string.Empty);
            }

            // TODO: Improve performance (better inlining, etc...)
            // Invoke malloc
            var typeSize = LLVM.BuildIntCast(builder, LLVM.SizeOf(type.ObjectType), int32Type, string.Empty);
            var allocatedData = LLVM.BuildCall(builder, allocObjectFunction, new[] { typeSize }, string.Empty);
            var allocatedObject = LLVM.BuildPointerCast(builder, allocatedData, LLVM.PointerType(type.ObjectType, 0), string.Empty);

            // Store vtable global into first field of the object
            var indices = new[]
            {
                LLVM.ConstInt(int32Type, 0, false),                                     // Pointer indirection
                LLVM.ConstInt(int32Type, (int)ObjectFields.RuntimeTypeInfo, false),     // Access RTTI
            };

            var vtablePointer = LLVM.BuildInBoundsGEP(builder, allocatedObject, indices, string.Empty);
            LLVM.BuildStore(builder, @class.GeneratedRuntimeTypeInfoGlobal, vtablePointer);
            return allocatedObject;
        }
示例#36
0
        /// <summary>
        /// 压入数据 压入Evaluation Stack中
        /// </summary>
        /// <param name="vtype"></param>
        /// <param name="value"></param>
#if BRIDGE
        public virtual void Ldc(StackValueType vtype, object value)
示例#37
0
        /// <summary>
        /// 合并指令 把一个值压入局部变量
        /// </summary>
        /// <param name="type">压入类型</param>
        /// <param name="lv">值</param>
        /// <param name="si">局部变量索引</param>
        public virtual void LdcStloc(ref StackValueType vtype, ref object value, ref int si)
        {
            long  ptr    = 0;
            long *pvalue = &ptr;

            if (value is string)
            {
                var str = value as string;
                switch (vtype)
                {
                case StackValueType.i8:
                    value = long.Parse(str);
                    *pvalue = (long)value;

                    break;

                case StackValueType.r8:

                    value = double.Parse(str);

                    break;

                case StackValueType.i4:

                    if (str.StartsWith("0x"))
                    {
                        value = System.Convert.ToInt32(str, 16);
                    }
                    else if (str.StartsWith("M") || str.StartsWith("m"))
                    {
                        value = (-int.Parse(str));
                    }
                    else
                    {
                        value = int.Parse(str);
                    }

                    break;

                case StackValueType.r4:

                    value = float.Parse(str);

                    break;
                }
            }

            {
                switch (vtype)
                {
                case StackValueType.i8:

                    *pvalue = (long)value;
                    break;

                case StackValueType.r8:
                {
                    var dv = (double)value;
                    pvalue = (long *)&dv;
                }
                break;

                case StackValueType.i4:
                {
                    var dv = (int)value;
                    pvalue = (long *)&dv;
                }
                break;

                case StackValueType.r4:
                {
                    var dv = (float)value;
                    pvalue = (long *)&dv;
                }
                break;
                }
            }

#if JS
            CallStack[(Csp + si)].IntValue = lv;
#else
            *(long *)(Csp + si)->VPoint = *pvalue;
            (Csp + si)->ValueType       = vtype;
#endif
        }
示例#38
0
        private ValueRef ConvertReferenceToExpectedType(BuilderRef builder, StackValueType stackValueType, ValueRef value, Type type)
        {
            var expectedType = stackValueType == StackValueType.Object
                ? LLVM.PointerType(type.ObjectTypeLLVM, 0)
                : LLVM.PointerType(type.ValueTypeLLVM, 0);

            if (LLVM.TypeOf(value) == expectedType)
                return value;

            return LLVM.BuildPointerCast(builder, value, expectedType, string.Empty);
        }