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 static Item CompileNewClass(ByteCodeGenerator generator, NewNode.NewClassNode node) { node.Type = ClassLocator.Find(node.GetType(generator), generator.Manager.Imports); generator.Emit(OpCodeValue.@new, generator.Manager.AddConstantClass(node.GetType(generator) as DefinedType)); generator.Emit(OpCodeValue.dup); new PrimaryCompiler(new PrimaryNode.TermMethodExpression { Identifier = "<init>", Arguments = node.Arguments }).Compile(generator, new StackItem(generator, node.GetType(generator))); return new StackItem(generator, node.GetType(generator)); }
public void Compile(ByteCodeGenerator generator) { MethodTreeNode first = tree.FirstOrDefault(); if (first == null) { CompileSuperCall(generator); } else { if (first is PrimaryNode.TermConstructorCallExpression) { var call = first as PrimaryNode.TermConstructorCallExpression; CompileSuperCall(generator, call); tree.RemoveAt(0); } else { CompileSuperCall(generator); } } new BlockCompiler(tree).Compile(generator); generator.Emit(OpCodeValue.@return); }
public static void MakeStringBuffer(ByteCodeGenerator generator, Class sb) { var sbInit = (Method)sb.Constructors.First(x => x.Parameters.Count == 0); var sbIndex = generator.Manager.AddConstantClass(sb); generator.EmitNew(sbIndex, sb); generator.Emit(OpCodeValue.dup); new MemberItem(generator, sbInit, true).Invoke(); }
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(); } }
private Item CompileAssignOp(ByteCodeGenerator generator) { var lType = new TranslateNode { Child = node.Left }.GetType(generator, false, true); var rType = node.Right.GetType(generator, false, true); var type = lType.FindCommonType(rType); Item lhs; if (lType.Name == BuiltinTypes.String.Name) { var sb = BuiltinTypes.StringBuilder; AdditiveCompiler.MakeStringBuffer(generator, sb); lhs = new ExpressionCompiler(node.Left).Compile(generator); if (lhs.Width() > 0) { generator.Emit(OpCodeValue.dup_x1 + (byte)(3 * (lhs.Width() - 1))); } lhs.Load(); AdditiveCompiler.AppendStrings(generator, sb, node.Left); AdditiveCompiler.AppendStrings(generator, sb, node.Right.Child); AdditiveCompiler.BufferToString(generator, sb); } else { lhs = new ExpressionCompiler(node.Left).Compile(generator); lhs.Duplicate(); lhs.Coerce(type).Load(); new TranslationCompiler(node.Right, type).Compile(generator).Load(); if (node is AssignmentNode.AddAssignNode) { AdditiveCompiler.CompileAddition(generator, type); } else if (node is AssignmentNode.MinusAssignNode) { AdditiveCompiler.CompileSubtraction(generator, type); } else { throw new NotImplementedException(); } } return new AssignItem(generator, lhs); }
public Item Compile(ByteCodeGenerator generator) { if (node.Value == null) { if (generator.Method.ReturnType != PrimativeTypes.Void) { throw new InvalidOperationException(); } generator.Emit(OpCodeValue.@return); return new VoidItem(generator); } var value = new TranslationCompiler(node.Value, generator.Method.ReturnType).Compile(generator); value.Load(); CompileReturn(generator, value.Type); return new VoidItem(generator); }
private Item CompilePostOp(ByteCodeGenerator generator, Item item) { item.Duplicate(); if (item is LocalItem && TypeCodeHelper.Truncate(item.TypeCode) == ItemTypeCode.Int) { //var res = item.Load(); ((LocalItem)item).Incr(node is UnaryNode.PostIncNode ? 1 : -1); //return res; return item; } else { var res = item.Load(); item.Stash(item.TypeCode); generator.Emit(One(item.TypeCode)); if (node is UnaryNode.PostIncNode) { generator.Emit(OpAdd(item.Type)); } else if (node is UnaryNode.PostDecNode) { generator.Emit(OpSub(item.Type)); } var typeCode = TypeCodeHelper.TypeCode(item.Type); if (item.Type != PrimativeTypes.Int && TypeCodeHelper.Truncate(typeCode) == ItemTypeCode.Int) { generator.Emit(OpCodeValue.i2b + (byte)typeCode - (byte)ItemTypeCode.Byte); } item.Store(); return res; } }
private void CompileBody(CompileManager manager) { attributes = new List<CompileAttribute>(); generator = new ByteCodeGenerator(manager, method); foreach (Method.Parameter parameter in method.Parameters) { generator.DefineVariable(parameter.Name, parameter.Type); } new BlockCompiler(method.Body).Compile(generator); if (method.ReturnType.Name == "void") { generator.Emit(OpCodeValue.@return); } var code = new CompileAttributeCode { NameIndex = manager.AddConstantUtf8(new CompileAttributeCode().Name), Code = generator.GetBytes(), Attributes = new List<CompileAttribute>(), ExceptionTable = new List<CompileAttributeCode.ExceptionTableEntry>(), MaxLocals = generator.MaxVariables, MaxStack = generator.MaxStack }; var stackMapTable = generator.StackMapTable; if (stackMapTable != null) { stackMapTable.NameIndex = manager.AddConstantUtf8(stackMapTable.Name); code.Attributes.Add(stackMapTable); } attributes.Add(code); }
private Item CompilePreOp(ByteCodeGenerator generator, Item item) { if (item is LocalItem && TypeCodeHelper.Truncate(item.TypeCode) == ItemTypeCode.Int) { ((LocalItem)item).Incr(node is UnaryNode.PreIncNode ? 1 : -1); return item; } else { item.Load(); generator.Emit(One(item.TypeCode)); if (node is UnaryNode.PreIncNode) { generator.Emit(OpAdd(item.Type)); } else if (node is UnaryNode.PreDecNode) { generator.Emit(OpSub(item.Type)); } var typeCode = item.TypeCode; if (item.Type != PrimativeTypes.Int && TypeCodeHelper.Truncate(typeCode) == ItemTypeCode.Int) { generator.Emit(OpCodeValue.i2b + (byte)typeCode - (byte)ItemTypeCode.Byte); } return new AssignItem(generator, item); } }
private void CompileLong(ByteCodeGenerator generator) { generator.Emit(OpCodeValue.lcmp); }
private void CompileFloat(ByteCodeGenerator generator) { generator.Emit(OpCodeValue.fcmpl); }
private void CompileDouble(ByteCodeGenerator generator) { generator.Emit(OpCodeValue.dcmpl); }
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(); } }
private static Item TryInstance(ByteCodeGenerator generator, Type type, PrimaryNode.TermIdentifierExpression id) { if (type is Array) { if (id.Identifier == "length") { generator.Emit(OpCodeValue.arraylength); return new StackItem(generator, PrimativeTypes.Int); } } var definedType = type as DefinedType; if (definedType == null) return null; // try instance Field field = definedType.Fields.FirstOrDefault(x => x.Name == id.Identifier); if (field == null) { if (type is Class && ((Class)type).Super != null) { definedType.Resolve(generator.Manager.Imports); return TryInstance(generator, ((Class)type).Super, id); } return null; } bool nonVirtual = field.Modifiers.HasFlag(Modifier.Private); bool isStatic = field.Modifiers.HasFlag(Modifier.Static); return isStatic ? new StaticItem(generator, field) : (Item)new MemberItem(generator, field, nonVirtual); }