public override void Write(JavaWriter wtr) { Write(wtr, tag, sizeof(ushort)); ushort constantIndex; if (value is int intValue) { constantIndex = wtr.ConstInteger(intValue); } else if (value is float floatValue) { constantIndex = wtr.ConstFloat(floatValue); } else if (value is long longValue) { constantIndex = wtr.ConstLong(longValue); } else if (value is double doubleValue) { constantIndex = wtr.ConstDouble(doubleValue); } else if (value is string stringValue) { constantIndex = wtr.ConstString(stringValue); } else { throw wtr.Where.Exception($"invalid constant value"); } wtr.Write16(constantIndex); }
bool FillInstruction_Jump(JavaWriter wtr, Instruction inst, byte op, int offset) { if (inst.Data is ushort && op < 0xC8) // insts with 2-byte offsets { inst.Bytes = new byte[3]; inst.Bytes[0] = op; } else if (inst.Data is ushort && op == 0xC8) { inst.Bytes = new byte[5]; inst.Bytes[0] = op; } else if (inst.Data is int[] words && op >= 0xAA && op <= 0xAB) { int n = words.Length; if (n > 16384 || (op == 0xAA && (n <= 3 || n != 3 + words[2] - words[1] + 1)) || (op == 0xAB && (n <= 2 || n != 2 + words[1] * 2))) { throw wtr.Where.Exception("invalid data in switch instruction"); } inst.Bytes = new byte[4 - (offset & 3) + n * 4]; inst.Bytes[0] = op; }
public override void Write(JavaWriter wtr) { wtr.Where.Push(tag); wtr.Write16(wtr.ConstUtf8(tag)); wtr.Fork(); wtr.Write16(maxStack); wtr.Write16(maxLocals); wtr.Write32((uint)code.Length); wtr.WriteBlock(code); if (exceptions == null) { wtr.Write16(0); } else { wtr.Write16(exceptions.Length); for (int i = 0; i < exceptions.Length; i++) { wtr.Write16(exceptions[i].start); wtr.Write16(exceptions[i].endPlus1); wtr.Write16(exceptions[i].handler); wtr.Write16((exceptions[i].catchType == null) ? 0 : wtr.ConstClass(exceptions[i].catchType)); } } attributes.Write(wtr); wtr.Join(); wtr.Where.Pop(); }
internal JavaConstant.MethodHandle ToConstant(JavaWriter wtr) { int referenceIndex = -1; if (Kind <= HandleKind.PutStatic) { referenceIndex = wtr.ConstField(Class, Field); } else if (Kind <= HandleKind.NewInvokeSpecial) { if (IsInterfaceMethod) { referenceIndex = wtr.ConstInterfaceMethod(Class, Method); } else { referenceIndex = wtr.ConstMethod(Class, Method); } } else if (Kind == HandleKind.InvokeInterface && IsInterfaceMethod) { referenceIndex = wtr.ConstInterfaceMethod(Class, Method); } if (referenceIndex == -1) { throw wtr.Where.Exception("invalid method handle"); } return(new JavaConstant.MethodHandle((byte)Kind, (ushort)referenceIndex)); }
int FillInstructions(JavaWriter wtr) { int codeLength = 0; foreach (var inst in Instructions) { if (inst.Bytes != null) { codeLength += inst.Bytes.Length; continue; } byte op = inst.Opcode; byte kind = instOperandType[op]; bool ok; wtr.Where.Push($"opcode 0x{op:X2} label 0x{inst.Label:X4}"); if ((kind & 0x80) != 0) { ok = FillInstruction_Const(wtr, inst, op); } else if ((kind & 0x40) != 0) { ok = FillInstruction_Jump(wtr, inst, op, codeLength); } else if ((kind & 0x10) != 0) { ok = FillInstruction_Local(wtr, inst, op); } else { ok = FillInstruction_Special(wtr, inst, op); } if (!ok) { throw wtr.Where.Exception($"unsupported instruction {op:X2} (or operand) at offset {codeLength:X4} (line {inst.Line})"); } if (inst.Bytes != null) { codeLength += inst.Bytes.Length; } else { codeLength++; } wtr.Where.Pop(); } return(codeLength); }
public override void Write(JavaWriter wtr) { wtr.Write16(wtr.ConstUtf8(tag)); wtr.Fork(); wtr.Write16(frames.Length); for (int i = 0; i < frames.Length; i++) { byte type = frames[i].type; wtr.Write8(type); if (type >= 247) { wtr.Write16(frames[i].deltaOffset); } var locals = frames[i].locals; if (locals == null) { wtr.Write16(0); } else { wtr.Write16(locals.Length); for (int j = 0; j < locals.Length; j++) { byte localType = locals[j].type; wtr.Write8(localType); if (localType >= 7 && localType <= 8) { wtr.Write16(locals[j].extra); } } } var stack = frames[i].stack; if (stack == null) { wtr.Write16(0); } else { wtr.Write16(stack.Length); for (int j = 0; j < stack.Length; j++) { byte stackType = stack[j].type; wtr.Write8(stackType); if (stackType >= 7 && stackType <= 8) { wtr.Write16(stack[j].extra); } } } } wtr.Join(); }
public void Write(JavaWriter wtr) { wtr.Write16(set.Count); foreach (var attr in set) { wtr.Where.Push($"attribute '{attr.GetType().Name}'"); attr.Write(wtr); wtr.Where.Pop(); } }
bool FillInstruction_Special(JavaWriter wtr, Instruction inst, byte op) { if (op == 0xBC) { inst.Bytes = new byte[2]; inst.Bytes[0] = op; inst.Bytes[1] = (byte)inst.Data; } return(true); }
public override void Write(JavaWriter wtr) { var blk = BitConverter.GetBytes(value); if (BitConverter.IsLittleEndian) { Array.Reverse(blk); } wtr.Write8(tag); wtr.WriteBlock(blk); }
public void Write(JavaWriter wtr) { int n = pool.Count; wtr.Write16((ushort)n); for (int i = 1; i < n; i++) { pool[i]?.Write(wtr); } editable = false; }
public override void Write(JavaWriter wtr) { int numLines = lines.Length; Write(wtr, tag, sizeof(ushort) * (1 + 2 * numLines)); wtr.Write16(numLines); for (int i = 0; i < numLines; i++) { wtr.Write16(lines[i].offset); wtr.Write16(lines[i].lineNumber); } }
public override void Write(JavaWriter wtr) { int length = sizeof(ushort) // classes.Length + classes.Length * sizeof(ushort); Write(wtr, tag, length); wtr.Write16(classes.Length); for (int i = 0; i < classes.Length; i++) { wtr.Write16(wtr.ConstClass(classes[i])); } }
public override void Write(JavaWriter wtr) { int length = sizeof(ushort) // number of entries + vars.Length * sizeof(ushort) * 5; Write(wtr, tag, length); wtr.Write16(vars.Length); for (int i = 0; i < vars.Length; i++) { wtr.Write16(vars[i].offset); wtr.Write16(vars[i].length); wtr.Write16(wtr.ConstUtf8(vars[i].nameAndType.Name)); wtr.Write16(wtr.ConstUtf8(vars[i].nameAndType.Type.ToDescriptor())); wtr.Write16(vars[i].index); } }
public override void Write(JavaWriter wtr) { int length = sizeof(ushort) // classes.Length + classes.Length * sizeof(ushort) * 4; Write(wtr, tag, length); wtr.Write16(classes.Length); for (int i = 0; i < classes.Length; i++) { wtr.Write16(wtr.ConstClass(classes[i].InnerLongName)); ushort v = (classes[i].OuterLongName == null) ? (ushort)0 : wtr.ConstClass(classes[i].OuterLongName); wtr.Write16(v); v = (classes[i].InnerShortName == null) ? (ushort)0 : wtr.ConstUtf8(classes[i].InnerShortName); wtr.Write16(v); wtr.Write16((ushort)classes[i].Flags); } }
/* * JavaFieldWriter */ public void Write(JavaWriter wtr) { wtr.Where.Push($"field '{Name}'"); wtr.Write16((ushort)Flags); wtr.Write16(wtr.ConstUtf8(Name)); wtr.Write16(wtr.ConstUtf8(Type.ToDescriptor())); if (Constant != null) { var attributes = new JavaAttributeSet(); attributes.Put(new JavaAttribute.ConstantValue(Constant)); attributes.Write(wtr); } else { wtr.Write16(0); // attributes } wtr.Where.Pop(); }
public void Write(JavaWriter wtr) { wtr.Where.Push($"method '{Name}'"); wtr.Write16((ushort)Flags); wtr.Write16(wtr.ConstUtf8(Name)); wtr.Write16(wtr.ConstUtf8(ToDescriptor())); var attributes = new JavaAttributeSet(); if (Code != null) { var codeAttr = new JavaAttribute.Code(); Code.Write(wtr, codeAttr); attributes.Put(codeAttr); } attributes.Write(wtr); wtr.Where.Pop(); }
public void Write(JavaWriter wtr, JavaAttribute.Code codeAttr) { wtr.Where.Push("method body"); int codeLength = FillInstructions(wtr); if (codeLength > 0xFFFE) { throw wtr.Where.Exception("output method is too large"); } var labelToOffsetMap = FillJumpTargets(wtr); codeAttr.code = new byte[codeLength]; FillCodeAttr(codeAttr.code); codeAttr.maxStack = (ushort)MaxStack; codeAttr.maxLocals = (ushort)MaxLocals; WriteExceptionData(codeAttr, labelToOffsetMap); if (StackMap != null) { var attr = StackMap.ToAttribute(wtr, labelToOffsetMap); if (attr != null) { codeAttr.attributes.Put(attr); } } if (DebugLocals != null) { var attr = new JavaAttribute.LocalVariableTable(DebugLocals, codeLength); codeAttr.attributes.Put(attr); } FillLineNumbers(codeAttr); wtr.Where.Pop(); }
void FillInstruction_LocalIncrement(JavaWriter wtr, Instruction inst, byte op) { ushort var = (ushort)((uint)inst.Data & 0xFFFF); ushort inc = (ushort)((uint)inst.Data >> 16); if (var <= 255 && inc <= 255) { inst.Bytes = new byte[3]; inst.Bytes[0] = op; inst.Bytes[1] = (byte)var; inst.Bytes[2] = (byte)inc; } else { inst.Bytes = new byte[5]; inst.Bytes[0] = op; inst.Bytes[1] = (byte)(var >> 8); inst.Bytes[2] = (byte)var; inst.Bytes[3] = (byte)(inc >> 8); inst.Bytes[4] = (byte)inc; } }
public override void Write(JavaWriter wtr) { wtr.Write8(tag); wtr.Write8(referenceKind); wtr.Write16(referenceIndex); }
public void Write(JavaWriter wtr, byte tag) { wtr.Write8(tag); wtr.Write16(classIndex); wtr.Write16(nameAndTypeIndex); }
public override void Write(JavaWriter wtr) { base.Write(wtr, tag); }
void FillInstruction_ConstLoad(JavaWriter wtr, Instruction inst) { int constantIndex = -1; byte op = 0; if (inst.Data is long vLong) { if (FillInstruction_ConstLoad_Long(inst, vLong)) { return; } constantIndex = wtr.ConstLong(vLong); op = 0x14; } else if (inst.Data is double vDouble) { if (FillInstruction_ConstLoad_Double(inst, vDouble)) { return; } constantIndex = wtr.ConstDouble(vDouble); op = 0x14; } else { if (inst.Class != null) { if (inst.Data is JavaFieldRef vField) { constantIndex = wtr.ConstField(inst.Class, vField); } else if (inst.Data is JavaMethodRef vMethod) { constantIndex = wtr.ConstMethod(inst.Class, vMethod); } else if (inst.Data == null) { constantIndex = wtr.ConstClass(inst.Class); } } else if (inst.Data is int vInteger) { if (FillInstruction_ConstLoad_Integer(inst, vInteger)) { return; } constantIndex = wtr.ConstInteger(vInteger); } else if (inst.Data is float vFloat) { if (FillInstruction_ConstLoad_Float(inst, vFloat)) { return; } constantIndex = wtr.ConstFloat(vFloat); } else if (inst.Data is string vString) { constantIndex = wtr.ConstString(vString); } op = (byte)((constantIndex <= 255) ? 0x12 : 0x13); inst.Opcode = op; } if (constantIndex == -1) { throw wtr.Where.Exception("invalid constant in ldc/ldc_w/ldc2_w instruction"); } if (op == 0x12) { inst.Bytes = new byte[2]; inst.Bytes[1] = (byte)constantIndex; } else { inst.Bytes = new byte[3]; inst.Bytes[1] = (byte)(constantIndex >> 8); inst.Bytes[2] = (byte)constantIndex; } inst.Bytes[0] = op; }
bool FillInstruction_Local(JavaWriter wtr, Instruction inst, byte op) { if (op == 0x84) { FillInstruction_LocalIncrement(wtr, inst, op); return(true); } ushort var = (ushort)(int)inst.Data; if (var <= 3 && op != 0xA9) // if not 'ret' and small var { if (op == 0x15) // iload { inst.Opcode = (byte)(0x1A + var); } else if (op == 0x16) // lload { inst.Opcode = (byte)(0x1E + var); } else if (op == 0x17) // fload { inst.Opcode = (byte)(0x22 + var); } else if (op == 0x18) // dload { inst.Opcode = (byte)(0x26 + var); } else if (op == 0x19) // aload { inst.Opcode = (byte)(0x2A + var); } else if (op == 0x36) // istore { inst.Opcode = (byte)(0x3B + var); } else if (op == 0x37) // lstore { inst.Opcode = (byte)(0x3F + var); } else if (op == 0x38) // fstore { inst.Opcode = (byte)(0x43 + var); } else if (op == 0x39) // dstore { inst.Opcode = (byte)(0x47 + var); } else if (op == 0x3A) // astore { inst.Opcode = (byte)(0x4B + var); } else { return(false); } } else if (var <= 255) { inst.Bytes = new byte[2]; inst.Bytes[0] = op; inst.Bytes[1] = (byte)var; } else { inst.Bytes = new byte[4]; inst.Bytes[0] = 0xC4; // wide inst.Bytes[1] = op; inst.Bytes[2] = (byte)(var >> 8); inst.Bytes[3] = (byte)var; } return(true); }
public void Write(JavaWriter wtr) { wtr.Where.Push($"writing class '{Name}'"); if (Name == null) { throw wtr.Where.Exception("missing class name"); } wtr.Write16((ushort)Flags); wtr.Write16(wtr.ConstClass(Name)); wtr.Write16(wtr.ConstClass(Super)); if (Interfaces == null) { wtr.Write16(0); } else { wtr.Write16(Interfaces.Count); for (int i = 0; i < Interfaces.Count; i++) { wtr.Write16(wtr.ConstClass(Interfaces[i])); } } if (Fields == null) { wtr.Write16(0); } else { wtr.Write16(Fields.Count); for (int i = 0; i < Fields.Count; i++) { Fields[i].Write(wtr); } } if (Methods == null) { wtr.Write16(0); } else { wtr.Write16(Methods.Count); for (int i = 0; i < Methods.Count; i++) { Methods[i].Write(wtr); } } var attributes = new JavaAttributeSet(); if (SourceFile != null) { attributes.Put(new JavaAttribute.SourceFile(SourceFile)); } if (Signature != null) { attributes.Put(new JavaAttribute.Signature(Signature)); } WriteInnerClasses(attributes); if (wtr.bootstrapMethods != null) { attributes.Put(wtr.bootstrapMethods); } attributes.Write(wtr); wtr.Where.Pop(); }
bool FillInstruction_Const(JavaWriter wtr, Instruction inst, byte op) { int length = 3; int count = 0; if (op >= 0x12 && op <= 0x14) { FillInstruction_ConstLoad(wtr, inst); return(true); } int constantIndex = -1; if (op >= 0xB2 && op <= 0xB5) { // getstatic/putstatic/getfield/putfield if (inst.Data is JavaFieldRef vField) { constantIndex = wtr.ConstField(inst.Class, vField); } } else if (op >= 0xB6 && op <= 0xB8) { // invokevirtual/invokespecial/invokestatic if (inst.Data is JavaMethodRef vMethod) { constantIndex = wtr.ConstMethod(inst.Class, vMethod); } } else if (op == 0xB9) { // invokeinterface if (inst.Data is JavaMethodRef vMethod) { constantIndex = wtr.ConstInterfaceMethod(inst.Class, vMethod); length = 5; count = 1; // 'this' argument int numArgs = vMethod.Parameters.Count; for (int i = 0; i < numArgs; i++) { count += vMethod.Parameters[i].Type.Category; } } } else if (op == 0xBA) { // invokedynamic if (inst.Data is JavaCallSite vCallSite) { constantIndex = wtr.ConstInvokeDynamic(vCallSite); length = 5; } } else if (op >= 0xBB) { // new/anewarray/checkcast/instanceof/multianewarray constantIndex = wtr.ConstClass(inst.Class); if (op == 0xC5) { length++; count = (int)inst.Data; } } if (constantIndex == -1) { return(false); } inst.Bytes = new byte[length]; inst.Bytes[0] = op; inst.Bytes[1] = (byte)(constantIndex >> 8); inst.Bytes[2] = (byte)constantIndex; if (op == 0xB9 || op == 0xC5) { inst.Bytes[3] = (byte)count; } return(true); }
public abstract void Write(JavaWriter wrt);
public override void Write(JavaWriter wtr) { wtr.Write8(tag); wtr.Write32((uint)value); }
public override void Write(JavaWriter wtr) { wtr.Write8(tag); wtr.Write16(bootstrapMethodIndex); wtr.Write16(nameAndTypeIndex); }
public override void Write(JavaWriter wtr) { wtr.Write8(tag); wtr.Write16(descriptorIndex); }
public override void Write(JavaWriter wtr) { wtr.Write8(tag); wtr.WriteString(str); }