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; }
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; }
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(); } }
public ClassItem(ByteCodeGenerator generator, Type type) : base(generator, type) { }
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; }
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(); } }