private void CompileReturn(ByteCodeGenerator generator, Type type)
        {
            var typeCode = TypeCodeHelper.Truncate(PrimativeTypes.TypeCode(type));

            switch (typeCode)
            {
                case ItemTypeCode.Int:
                    generator.Emit(OpCodeValue.ireturn);
                    break;
                case ItemTypeCode.Long:
                    generator.Emit(OpCodeValue.lreturn);
                    break;
                case ItemTypeCode.Float:
                    generator.Emit(OpCodeValue.freturn);
                    break;
                case ItemTypeCode.Double:
                    generator.Emit(OpCodeValue.dreturn);
                    break;
                case ItemTypeCode.Object:
                    generator.Emit(OpCodeValue.areturn);
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
        private UninitializedType(int tag, Type qtype, int offset)
        {
            Tag = tag;
            Type = qtype;

            Offset = offset;
        }
Beispiel #3
0
        public virtual Item Coerce(Type target)
        {
            var targetCode = TypeCodeHelper.TypeCode(target);

            if (TypeCode == targetCode)
                return this;

            Load();

            var typecode1 = TypeCodeHelper.Truncate(TypeCode);
            var targetcode1 = TypeCodeHelper.Truncate(targetCode);

            if (typecode1 != targetcode1)
            {
                var offset = targetcode1 > typecode1 ? targetcode1 - 1 : targetcode1;
                var opcode = (int)OpCodeValue.i2l + (int)typecode1 * 3 + offset;

                Generator.Emit((OpCodeValue)opcode);
            }
            if (targetCode != targetcode1)
            {
                var opcode = (int)OpCodeValue.i2b + targetCode - ItemTypeCode.Byte;

                Generator.Emit((OpCodeValue)opcode);
            }

            return TypeCodeHelper.StackItem(Generator, target);
        }
        public override Item Coerce(Type target)
        {
            var targetCode = TypeCodeHelper.TypeCode(target);

            if (TypeCode == targetCode)
            {
                return this;
            }

            switch (targetCode)
            {
                case ItemTypeCode.Int:
                    if (TypeCodeHelper.Truncate(TypeCode) == ItemTypeCode.Int)
                    {
                        return this;
                    }

                    return new ImmediateItem(Generator, PrimativeTypes.Int, Convert.ToInt32(value));
                case ItemTypeCode.Long:
                    return new ImmediateItem(Generator, PrimativeTypes.Long, Convert.ToInt64(value));
                case ItemTypeCode.Float:
                    return new ImmediateItem(Generator, PrimativeTypes.Float, Convert.ToSingle(value));
                case ItemTypeCode.Double:
                    return new ImmediateItem(Generator, PrimativeTypes.Double, Convert.ToDouble(value));
                case ItemTypeCode.Byte:
                    return new ImmediateItem(Generator, PrimativeTypes.Byte, Convert.ToInt32(value));
                case ItemTypeCode.Char:
                    return new ImmediateItem(Generator, PrimativeTypes.Char, Convert.ToInt32(value));
                case ItemTypeCode.Short:
                    return new ImmediateItem(Generator, PrimativeTypes.Short, Convert.ToInt32(value));
                default:
                    return base.Coerce(target);
            }
        }
        public static Item StackItem(ByteCodeGenerator generator, Type type)
        {
            if (type.Primitive)
            {
                if (TypeCode(type) == ItemTypeCode.Void)
                {
                    return new VoidItem(generator);
                }
            }

            return new StackItem(generator, type);
        }
        public static byte ArrayCode(Type elemType)
        {
            if (elemType == PrimativeTypes.Byte) return 8;
            if (elemType == PrimativeTypes.Boolean) return 4;
            if (elemType == PrimativeTypes.Short) return 9;
            if (elemType == PrimativeTypes.Char) return 5;
            if (elemType == PrimativeTypes.Int) return 10;
            if (elemType == PrimativeTypes.Long) return 11;
            if (elemType == PrimativeTypes.Float) return 6;
            if (elemType == PrimativeTypes.Double) return 7;
            if (elemType is Array) return 1;
            if (elemType is Class) return 0;

            throw new NotImplementedException();
        }
        public static Type FindCommonType(this Type c1, Type c2)
        {
            if (c1.IsAssignableTo(c2))
            {
                return c2;
            }
            if (c2.IsAssignableTo(c1))
            {
                return c1;
            }

            // No EASY common type found
            // will have to look harder??
            return null;
        }
Beispiel #8
0
        protected Item(ByteCodeGenerator generator, Type type)
        {
            Generator = generator;

            if (type is PlaceholderType)
            {
                type = ClassLocator.Find(type, generator.Manager.Imports);
            }

            var definedType = type as DefinedType;
            if (definedType != null)
            {
                definedType.Resolve(generator.Manager.Imports);
            }

            Type = type;
            TypeCode = TypeCodeHelper.TypeCode(type);
        }
        private static void CompileDivide(ByteCodeGenerator generator, Type type)
        {
            var typeCode = TypeCodeHelper.Truncate(PrimativeTypes.TypeCode(type));

            switch (typeCode)
            {
                case ItemTypeCode.Int:
                    generator.Emit(OpCodeValue.idiv);
                    break;
                case ItemTypeCode.Long:
                    generator.Emit(OpCodeValue.ldiv);
                    break;
                case ItemTypeCode.Float:
                    generator.Emit(OpCodeValue.fdiv);
                    break;
                case ItemTypeCode.Double:
                    generator.Emit(OpCodeValue.ddiv);
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
Beispiel #10
0
 public ClassItem(ByteCodeGenerator generator, Type type)
     : base(generator, type)
 {
 }
Beispiel #11
0
 public LocalItem(ByteCodeGenerator generator, Type type, short reg)
     : base(generator, type)
 {
     this.reg = reg;
     this.type = type;
 }
        private void EmitStackMapFrame()
        {
            if (lastFrame == null)
            {
                // first frame
                lastFrame = GetInitialFrame();
            }
            else if (lastFrame.PC == length)
            {
                // drop existing stackmap at this offset
                stackMapTableBuffer[--stackMapBufferSize] = null;
                lastFrame = frameBeforeLast;
                frameBeforeLast = null;
            }

            var frame = new StackMapFrame { PC = length };

            var localCount = 0;
            var locals = new Type[variableCount];
            for (var i = 0; i < variableCount; i++, localCount++)
            {
                var variable = GetVariable(i);

                if (variable == null || !variable.IsDefined) continue;

                var vtype = variable.Type;

                locals[i] = vtype;
                if (TypeCodeHelper.Width(vtype) > 1) i++;
            }

            frame.Locals = new Type[localCount];
            for (int i = 0, j = 0; i < variableCount; i++, j++)
            {
                Debug.Assert(j < localCount);
                frame.Locals[j] = locals[i];
                if (TypeCodeHelper.Width(locals[i]) > 1) i++;
            }

            var stackCount = 0;
            for (var i = 0; i < state.StackSize; i++)
            {
                if (state.GetStack(i) != null)
                {
                    stackCount++;
                }
            }

            frame.Stack = new Type[stackCount];
            stackCount = 0;
            for (var i = 0; i < state.StackSize; i++)
            {
                if (state.GetStack(i) != null)
                {
                    frame.Stack[stackCount++] = state.GetStack(i);
                }
            }

            if (stackMapTableBuffer == null)
            {
                stackMapTableBuffer = new CompileAttributeStackMapTable.StackMapFrame[20];
            }
            else if (stackMapTableBuffer.Length == stackMapBufferSize)
            {
                var newStackMapTableBuffer = new CompileAttributeStackMapTable.StackMapFrame[stackMapBufferSize << 1];

                Array.Copy(stackMapTableBuffer, 0, newStackMapTableBuffer, 0, stackMapBufferSize);

                stackMapTableBuffer = newStackMapTableBuffer;
            }
            stackMapTableBuffer[stackMapBufferSize++] = CompileAttributeStackMapTable.StackMapFrame.GetInstance(this, frame, lastFrame.PC, lastFrame.Locals);

            frameBeforeLast = lastFrame;
            lastFrame = frame;
        }
        public void EmitNew(short cp, Type type)
        {
            EmitOp(OpCodeValue.@new);

            if (!alive) return;
            EmitShort(cp);

            state.Push(UninitializedType.UninitializedObject(type, length - 3));
        }
        public Variable DefineVariable(string name, Type type)
        {
            if (variableCount >= variableList.Length)
                throw new StackOverflowException("Cannot define any more local variables!");

            type = ClassLocator.Find(type, Manager.Imports);

            short index = FindFreeVariableIndex();

            if (pendingJumps != null) ResolvePendingJumps();

            variableList[index] = new Variable(index, name, type);
            variableCount++;

            MaxVariables = Math.Max(MaxVariables, variableCount);

            return variableList[index];
        }
 public ImmediateItem(ByteCodeGenerator generator, Type type, object value)
     : base(generator, type)
 {
     this.value = value;
 }
 private static VerificationTypeInfo GetTypeInfo(ByteCodeGenerator generator, Type type)
 {
     //Top = 0,
     //Integer = 1,
     if (type == PrimativeTypes.Int) return new VerificationTypeInfo { Tag = VerificationType.Integer };
     //Float = 2,
     if (type == PrimativeTypes.Float) return new VerificationTypeInfo { Tag = VerificationType.Float };
     //Long = 4,
     if (type == PrimativeTypes.Long) return new VerificationTypeInfo { Tag = VerificationType.Long };
     //Double = 3,
     if (type == PrimativeTypes.Double) return new VerificationTypeInfo { Tag = VerificationType.Double };
     //Null = 5,
     //UninitializedThis = 6,
     //Object = 7,
     if (!type.Primitive)
     {
         return new VerificationTypeInfo
                    {
                        Tag = VerificationType.Object,
                        Value = generator.Manager.AddConstantClass(type as DefinedType)
                    };
     }
     //Uninitialized = 8
     throw new NotImplementedException();
 }
            internal static StackMapFrame GetInstance(ByteCodeGenerator generator, ByteCodeGenerator.StackMapFrame thisFrame, int prevPC, Type[] prevLocals)
            {
                var locals = thisFrame.Locals;
                var stack = thisFrame.Stack;
                var offsetDelta = thisFrame.PC - prevPC - 1;

                switch (stack.Length)
                {
                    case 1:
                        if (locals.Length == prevLocals.Length && Compare(prevLocals, locals) == 0)
                        {
                            return new StackMapFrame
                            {
                                Type = (byte)((offsetDelta < SameFrameSize) ? (SameFrameSize + offsetDelta) : SameLocals1StackItemExtended),
                                OffsetDelta = offsetDelta,
                                Stack = new List<VerificationTypeInfo> { GetTypeInfo(generator, stack[0]) }
                            };
                        }
                        break;
                    case 0:
                        {
                            var diffLength = Compare(prevLocals, locals);
                            if (diffLength == 0)
                            {
                                return new StackMapFrame
                                {
                                    Type = (byte)((offsetDelta < SameFrameSize) ? offsetDelta : SameFrameExtended),
                                    OffsetDelta = offsetDelta
                                };
                            }
                            if (-MaxLocalLengthDiff < diffLength && diffLength < 0)
                            {
                                // APPEND
                                var localDiff = new Type[-diffLength];
                                for (int i = prevLocals.Length, j = 0; i < locals.Length; i++, j++)
                                {
                                    localDiff[j] = locals[i];
                                }

                                return new StackMapFrame
                                {
                                    Type = (byte)(SameFrameExtended - diffLength),
                                    OffsetDelta = offsetDelta,
                                    Locals = localDiff.Select(x => GetTypeInfo(generator, x)).ToList()
                                };
                            }
                            if (0 < diffLength && diffLength < MaxLocalLengthDiff)
                            {
                                // CHOP
                                return new StackMapFrame
                                {
                                    Type = (byte)(SameFrameExtended - diffLength),
                                    OffsetDelta = offsetDelta
                                };
                            }
                        }
                        break;
                }
                // FULL_FRAME
                return new StackMapFrame
                {
                    Type = FullFrame,
                    OffsetDelta = offsetDelta,
                    Locals = locals.Select(x => GetTypeInfo(generator, x)).ToList(),
                    Stack = stack.Select(x => GetTypeInfo(generator, x)).ToList()
                };
            }
 public static ItemTypeCode Truncate(Type type)
 {
     return Truncate(TypeCode(type));
 }
        private OpCodeValue OpSub(Type type)
        {
            var typeCode = TypeCodeHelper.Truncate(PrimativeTypes.TypeCode(type));

            switch (typeCode)
            {
                case ItemTypeCode.Int:
                    return OpCodeValue.isub;
                case ItemTypeCode.Long:
                    return OpCodeValue.lsub;
                case ItemTypeCode.Float:
                    return OpCodeValue.fsub;
                case ItemTypeCode.Double:
                    return OpCodeValue.dsub;
                default:
                    throw new NotImplementedException();
            }
        }
        public void EmitCheckcast(short f, Type type)
        {
            EmitOp(OpCodeValue.checkcast);

            if (!alive) return;
            EmitShort(f);

            state.Pop(1); // object ref
            state.Push(type);
        }
        public void EmitAnewarray(short od, Type arrayType)
        {
            EmitOp(OpCodeValue.anewarray);
            if (!alive) return;

            EmitShort(od);

            state.Pop(1);
            state.Push(arrayType);
        }
 public static UninitializedType UninitializedObject(Type qtype, int offset)
 {
     return new UninitializedType(_uninitializedObject, qtype, offset);
 }
        public void EmitMultianewarray(byte ndims, short type, Type arrayType)
        {
            EmitOp(OpCodeValue.multianewarray);
            if (!alive) return;

            EmitShort(type);
            EmitByte(ndims);

            state.Pop(ndims);
            state.Push(arrayType);
        }
 public static UninitializedType UninitializedThis(Type qtype)
 {
     return new UninitializedType(_uninitializedThis, qtype, -1);
 }
        public void EmitNewarray(byte elemcode, Type arrayType)
        {
            EmitOp(OpCodeValue.newarray);
            if (!alive) return;

            EmitByte(elemcode);

            state.Pop(1); // count
            state.Push(arrayType);
        }
        public static ItemTypeCode TypeCode(Type type)
        {
            if (type.Primitive)
            {
                return PrimativeTypes.TypeCode(type);
            }

            return ItemTypeCode.Object;
        }
Beispiel #27
0
 public SelfItem(ByteCodeGenerator generator, Type scope, bool isSuper)
     : base(generator, scope)
 {
     this.isSuper = isSuper;
 }
 public static int Width(Type type)
 {
     return Width(TypeCode(type));
 }
        public short AddConstantClass(Type c)
        {
            if (c == null) return 0;

            var nameIndex = AddConstantUtf8(c.GetDescriptor(true));
            var classConst = ConstantPool.OfType<CompileConstantClass>().FirstOrDefault(x => x.NameIndex == nameIndex);

            if (classConst == null)
            {
                classConst = new CompileConstantClass { PoolIndex = nextConstantIndex++, NameIndex = nameIndex };

                ConstantPool.Add(classConst);
            }

            return classConst.PoolIndex;
        }
        internal static void CompileSubtraction(ByteCodeGenerator generator, Type type)
        {
            var typeCode = TypeCodeHelper.Truncate(PrimativeTypes.TypeCode(type));

            switch (typeCode)
            {
                case ItemTypeCode.Int:
                    generator.Emit(OpCodeValue.isub);
                    break;
                case ItemTypeCode.Long:
                    generator.Emit(OpCodeValue.lsub);
                    break;
                case ItemTypeCode.Float:
                    generator.Emit(OpCodeValue.fsub);
                    break;
                case ItemTypeCode.Double:
                    generator.Emit(OpCodeValue.dsub);
                    break;
                default:
                    throw new InvalidOperationException();
            }
        }