/// <exception cref="System.IO.IOException"/> public override void InitContent(DataInputFullStream data, ConstantPool pool) { int len = data.ReadUnsignedShort(); if (len > 0) { entries = new List <StructInnerClassesAttribute.Entry>(len); for (int i = 0; i < len; i++) { int innerNameIdx = data.ReadUnsignedShort(); int outerNameIdx = data.ReadUnsignedShort(); int simpleNameIdx = data.ReadUnsignedShort(); int accessFlags = data.ReadUnsignedShort(); string innerName = pool.GetPrimitiveConstant(innerNameIdx).GetString(); string outerName = outerNameIdx != 0 ? pool.GetPrimitiveConstant(outerNameIdx).GetString () : null; string simpleName = simpleNameIdx != 0 ? pool.GetPrimitiveConstant(simpleNameIdx) .GetString() : null; entries.Add(new StructInnerClassesAttribute.Entry(outerNameIdx, simpleNameIdx, accessFlags , innerName, outerName, simpleName)); } } else { entries = new System.Collections.Generic.List <StructInnerClassesAttribute.Entry>(); } }
/// <exception cref="IOException"/> public static AnnotationExprent ParseAnnotation(DataInputStream data, ConstantPool pool) { string className = pool.GetPrimitiveConstant(data.ReadUnsignedShort()).GetString( ); List <string> names; List <Exprent> values; int len = data.ReadUnsignedShort(); if (len > 0) { names = new List <string>(len); values = new List <Exprent>(len); for (int i = 0; i < len; i++) { names.Add(pool.GetPrimitiveConstant(data.ReadUnsignedShort()).GetString()); values.Add(ParseAnnotationElement(data, pool)); } } else { names = new System.Collections.Generic.List <string>(); values = new System.Collections.Generic.List <Exprent>(); } return(new AnnotationExprent(new VarType(className).value, names, values)); }
/// <exception cref="System.IO.IOException"/> public override void InitContent(DataInputFullStream data, ConstantPool pool) { int classIndex = data.ReadUnsignedShort(); int methodIndex = data.ReadUnsignedShort(); className = pool.GetPrimitiveConstant(classIndex).GetString(); if (methodIndex != 0) { LinkConstant lk = pool.GetLinkConstant(methodIndex); methodName = lk.elementname; methodDescriptor = lk.descriptor; } }
/// <exception cref="System.IO.IOException"/> protected internal virtual Dictionary <string, StructGeneralAttribute> ReadAttributes (DataInputFullStream @in, ConstantPool pool) { int length = @in.ReadUnsignedShort(); Dictionary <string, StructGeneralAttribute> attributes = new Dictionary <string, StructGeneralAttribute >(length); for (int i = 0; i < length; i++) { int nameIndex = @in.ReadUnsignedShort(); string name = pool.GetPrimitiveConstant(nameIndex).GetString(); StructGeneralAttribute attribute = ReadAttribute(@in, pool, name); if (attribute != null) { if (StructGeneralAttribute.Attribute_Local_Variable_Table.GetName().Equals(name) && attributes.ContainsKey(name)) { // merge all variable tables StructLocalVariableTableAttribute table = (StructLocalVariableTableAttribute)attributes .GetOrNull(name); table.Add((StructLocalVariableTableAttribute)attribute); } else if (StructGeneralAttribute.Attribute_Local_Variable_Type_Table.GetName().Equals (name) && attributes.ContainsKey(name)) { // merge all variable tables StructLocalVariableTypeTableAttribute table = (StructLocalVariableTypeTableAttribute )attributes.GetOrNull(name); table.Add((StructLocalVariableTypeTableAttribute)attribute); } else { Sharpen.Collections.Put(attributes, attribute.GetName(), attribute); } } } return(attributes); }
/* * u1 parameters_count; * { u2 name_index; * u2 access_flags; * } parameters[parameters_count]; */ /// <exception cref="System.IO.IOException"/> public override void InitContent(DataInputFullStream data, ConstantPool pool) { int len = data.ReadUnsignedByte(); List <StructMethodParametersAttribute.Entry> entries; if (len > 0) { entries = new List <StructMethodParametersAttribute.Entry>(len); for (int i = 0; i < len; i++) { int nameIndex = data.ReadUnsignedShort(); string name = nameIndex != 0 ? pool.GetPrimitiveConstant(nameIndex).GetString() : null; int access_flags = data.ReadUnsignedShort(); entries.Add(new StructMethodParametersAttribute.Entry(name, access_flags)); } } else { entries = new System.Collections.Generic.List <StructMethodParametersAttribute.Entry >(); } myEntries = (entries); }
/// <exception cref="System.IO.IOException"/> private InstructionSequence ParseBytecode(DataInputFullStream @in, int length, ConstantPool pool) { VBStyleCollection <Instruction, int> instructions = new VBStyleCollection <Instruction , int>(); int bytecode_version = classStruct.GetBytecodeVersion(); for (int i = 0; i < length;) { int offset = i; int opcode = @in.ReadUnsignedByte(); int group = Group_General; bool wide = (opcode == opc_wide); if (wide) { i++; opcode = @in.ReadUnsignedByte(); } List <int> operands = new List <int>(); if (opcode >= opc_iconst_m1 && opcode <= opc_iconst_5) { operands.Add(opr_iconst[opcode - opc_iconst_m1]); opcode = opc_bipush; } else if (opcode >= opc_iload_0 && opcode <= opc_aload_3) { operands.Add(opr_loadstore[opcode - opc_iload_0]); opcode = opcs_load[(opcode - opc_iload_0) / 4]; } else if (opcode >= opc_istore_0 && opcode <= opc_astore_3) { operands.Add(opr_loadstore[opcode - opc_istore_0]); opcode = opcs_store[(opcode - opc_istore_0) / 4]; } else { switch (opcode) { case opc_bipush: { operands.Add((int)@in.ReadByte()); i++; break; } case opc_ldc: case opc_newarray: { operands.Add(@in.ReadUnsignedByte()); i++; break; } case opc_sipush: case opc_ifeq: case opc_ifne: case opc_iflt: case opc_ifge: case opc_ifgt: case opc_ifle: case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmplt: case opc_if_icmpge: case opc_if_icmpgt: case opc_if_icmple: case opc_if_acmpeq: case opc_if_acmpne: case opc_goto: case opc_jsr: case opc_ifnull: case opc_ifnonnull: { if (opcode != opc_sipush) { group = Group_Jump; } operands.Add((int)@in.ReadShort()); i += 2; break; } case opc_ldc_w: case opc_ldc2_w: case opc_getstatic: case opc_putstatic: case opc_getfield: case opc_putfield: case opc_invokevirtual: case opc_invokespecial: case opc_invokestatic: case opc_new: case opc_anewarray: case opc_checkcast: case opc_instanceof: { operands.Add(@in.ReadUnsignedShort()); i += 2; if (opcode >= opc_getstatic && opcode <= opc_putfield) { group = Group_Fieldaccess; } else if (opcode >= opc_invokevirtual && opcode <= opc_invokestatic) { group = Group_Invocation; } break; } case opc_invokedynamic: { if (classStruct.IsVersionGE_1_7()) { // instruction unused in Java 6 and before operands.Add(@in.ReadUnsignedShort()); @in.Discard(2); group = Group_Invocation; i += 4; } break; } case opc_iload: case opc_lload: case opc_fload: case opc_dload: case opc_aload: case opc_istore: case opc_lstore: case opc_fstore: case opc_dstore: case opc_astore: case opc_ret: { if (wide) { operands.Add(@in.ReadUnsignedShort()); i += 2; } else { operands.Add(@in.ReadUnsignedByte()); i++; } if (opcode == opc_ret) { group = Group_Return; } break; } case opc_iinc: { if (wide) { operands.Add(@in.ReadUnsignedShort()); operands.Add((int)@in.ReadShort()); i += 4; } else { operands.Add(@in.ReadUnsignedByte()); operands.Add((int)@in.ReadByte()); i += 2; } break; } case opc_goto_w: case opc_jsr_w: { opcode = opcode == opc_jsr_w ? opc_jsr : opc_goto; operands.Add(@in.ReadInt()); group = Group_Jump; i += 4; break; } case opc_invokeinterface: { operands.Add(@in.ReadUnsignedShort()); operands.Add(@in.ReadUnsignedByte()); @in.Discard(1); group = Group_Invocation; i += 4; break; } case opc_multianewarray: { operands.Add(@in.ReadUnsignedShort()); operands.Add(@in.ReadUnsignedByte()); i += 3; break; } case opc_tableswitch: { @in.Discard((4 - (i + 1) % 4) % 4); i += ((4 - (i + 1) % 4) % 4); // padding operands.Add(@in.ReadInt()); i += 4; int low = @in.ReadInt(); operands.Add(low); i += 4; int high = @in.ReadInt(); operands.Add(high); i += 4; for (int j = 0; j < high - low + 1; j++) { operands.Add(@in.ReadInt()); i += 4; } group = Group_Switch; break; } case opc_lookupswitch: { @in.Discard((4 - (i + 1) % 4) % 4); i += ((4 - (i + 1) % 4) % 4); // padding operands.Add(@in.ReadInt()); i += 4; int npairs = @in.ReadInt(); operands.Add(npairs); i += 4; for (int j = 0; j < npairs; j++) { operands.Add(@in.ReadInt()); i += 4; operands.Add(@in.ReadInt()); i += 4; } group = Group_Switch; break; } case opc_ireturn: case opc_lreturn: case opc_freturn: case opc_dreturn: case opc_areturn: case opc_return: case opc_athrow: { group = Group_Return; break; } } } int[] ops = null; if (!(operands.Count == 0)) { ops = new int[operands.Count]; for (int j = 0; j < operands.Count; j++) { ops[j] = operands[j]; } } Instruction instr = Instruction.Create(opcode, wide, group, bytecode_version, ops ); instructions.AddWithKey(instr, offset); i++; } // initialize exception table List <ExceptionHandler> lstHandlers = new List <ExceptionHandler>(); int exception_count = @in.ReadUnsignedShort(); for (int i = 0; i < exception_count; i++) { ExceptionHandler handler = new ExceptionHandler(); handler.from = @in.ReadUnsignedShort(); handler.to = @in.ReadUnsignedShort(); handler.handler = @in.ReadUnsignedShort(); int excclass = @in.ReadUnsignedShort(); if (excclass != 0) { handler.exceptionClass = pool.GetPrimitiveConstant(excclass).GetString(); } lstHandlers.Add(handler); } InstructionSequence seq = new FullInstructionSequence(instructions, new ExceptionTable (lstHandlers)); // initialize instructions int i_1 = seq.Length() - 1; seq.SetPointer(i_1); while (i_1 >= 0) { Instruction instr = seq.GetInstr(i_1--); if (instr.group != Group_General) { instr.InitInstruction(seq); } seq.AddToPointer(-1); } return(seq); }
private static bool IsAnonymous(StructClass cl, StructClass enclosingCl) { // checking super class and interfaces int[] interfaces = cl.GetInterfaces(); if (interfaces.Length > 0) { bool hasNonTrivialSuperClass = cl.superClass != null && !VarType.Vartype_Object.Equals (new VarType(cl.superClass.GetString(), true)); if (hasNonTrivialSuperClass || interfaces.Length > 1) { // can't have multiple 'sources' string message = "Inconsistent anonymous class definition: '" + cl.qualifiedName + "'. Multiple interfaces and/or super class defined."; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn ); return(false); } } else if (cl.superClass == null) { // neither interface nor super class defined string message = "Inconsistent anonymous class definition: '" + cl.qualifiedName + "'. Neither interface nor super class defined."; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn ); return(false); } // FIXME: check constructors // FIXME: check enclosing class/method ConstantPool pool = enclosingCl.GetPool(); int refCounter = 0; bool refNotNew = false; StructEnclosingMethodAttribute attribute = cl.GetAttribute(StructGeneralAttribute .Attribute_Enclosing_Method); string enclosingMethod = attribute != null?attribute.GetMethodName() : null; // checking references in the enclosing class foreach (StructMethod mt in enclosingCl.GetMethods()) { if (enclosingMethod != null && !enclosingMethod.Equals(mt.GetName())) { continue; } try { mt.ExpandData(); InstructionSequence seq = mt.GetInstructionSequence(); if (seq != null) { int len = seq.Length(); for (int i = 0; i < len; i++) { Instruction instr = seq.GetInstr(i); switch (instr.opcode) { case opc_checkcast: case opc_instanceof: { if (cl.qualifiedName.Equals(pool.GetPrimitiveConstant(instr.Operand(0)).GetString ())) { refCounter++; refNotNew = true; } break; } case opc_new: case opc_anewarray: case opc_multianewarray: { if (cl.qualifiedName.Equals(pool.GetPrimitiveConstant(instr.Operand(0)).GetString ())) { refCounter++; } break; } case opc_getstatic: case opc_putstatic: { if (cl.qualifiedName.Equals(pool.GetLinkConstant(instr.Operand(0)).classname)) { refCounter++; refNotNew = true; } break; } } } } mt.ReleaseResources(); } catch (IOException) { string message = "Could not read method while checking anonymous class definition: '" + enclosingCl.qualifiedName + "', '" + InterpreterUtil.MakeUniqueKey(mt.GetName (), mt.GetDescriptor()) + "'"; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn ); return(false); } if (refCounter > 1 || refNotNew) { string message = "Inconsistent references to the class '" + cl.qualifiedName + "' which is supposed to be anonymous"; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn ); return(false); } } return(true); }
/* * u2 local_variable_table_length; * local_variable { * u2 start_pc; * u2 length; * u2 name_index; * u2 descriptor_index; * u2 index; * } */ /// <exception cref="System.IO.IOException"/> public override void InitContent(DataInputFullStream data, ConstantPool pool) { int len = data.ReadUnsignedShort(); if (len > 0) { localVariables = new List <StructLocalVariableTableAttribute.LocalVariable>(len); for (int i = 0; i < len; i++) { int start_pc = data.ReadUnsignedShort(); int length = data.ReadUnsignedShort(); int nameIndex = data.ReadUnsignedShort(); int descriptorIndex = data.ReadUnsignedShort(); int varIndex = data.ReadUnsignedShort(); localVariables.Add(new StructLocalVariableTableAttribute.LocalVariable(start_pc, length, pool.GetPrimitiveConstant(nameIndex).GetString(), pool.GetPrimitiveConstant (descriptorIndex).GetString(), varIndex)); } } else { localVariables = new System.Collections.Generic.List <StructLocalVariableTableAttribute.LocalVariable >(); } }
public virtual string GetExcClassname(int index, ConstantPool pool) { return(pool.GetPrimitiveConstant(throwsExceptions[index]).GetString()); }
/// <exception cref="System.IO.IOException"/> public StructClass(DataInputFullStream @in, bool own, LazyLoader loader) { /* * class_file { * u4 magic; * u2 minor_version; * u2 major_version; * u2 constant_pool_count; * cp_info constant_pool[constant_pool_count-1]; * u2 access_flags; * u2 this_class; * u2 super_class; * u2 interfaces_count; * u2 interfaces[interfaces_count]; * u2 fields_count; * field_info fields[fields_count]; * u2 methods_count; * method_info methods[methods_count]; * u2 attributes_count; * attribute_info attributes[attributes_count]; * } */ this.own = own; this.loader = loader; @in.Discard(4); minorVersion = @in.ReadUnsignedShort(); majorVersion = @in.ReadUnsignedShort(); pool = new ConstantPool(@in); accessFlags = @in.ReadUnsignedShort(); int thisClassIdx = @in.ReadUnsignedShort(); int superClassIdx = @in.ReadUnsignedShort(); qualifiedName = pool.GetPrimitiveConstant(thisClassIdx).GetString(); superClass = pool.GetPrimitiveConstant(superClassIdx); // interfaces int length = @in.ReadUnsignedShort(); interfaces = new int[length]; interfaceNames = new string[length]; for (int i = 0; i < length; i++) { interfaces[i] = @in.ReadUnsignedShort(); interfaceNames[i] = pool.GetPrimitiveConstant(interfaces[i]).GetString(); } // fields length = @in.ReadUnsignedShort(); fields = new VBStyleCollection <StructField, string>(length); for (int i = 0; i < length; i++) { StructField field = new StructField(@in, this); fields.AddWithKey(field, InterpreterUtil.MakeUniqueKey(field.GetName(), field.GetDescriptor ())); } // methods length = @in.ReadUnsignedShort(); methods = new VBStyleCollection <StructMethod, string>(length); for (int i = 0; i < length; i++) { StructMethod method = new StructMethod(@in, this); methods.AddWithKey(method, InterpreterUtil.MakeUniqueKey(method.GetName(), method .GetDescriptor())); } // attributes attributes = ReadAttributes(@in, pool); ReleaseResources(); }
/// <exception cref="IOException"/> public static Exprent ParseAnnotationElement(DataInputStream data, ConstantPool pool ) { int tag = data.ReadUnsignedByte(); switch (tag) { case 'e': { // enum constant string className = pool.GetPrimitiveConstant(data.ReadUnsignedShort()).GetString( ); string constName = pool.GetPrimitiveConstant(data.ReadUnsignedShort()).GetString( ); FieldDescriptor descr = FieldDescriptor.ParseDescriptor(className); return(new FieldExprent(constName, descr.type.value, true, null, descr, null)); } case 'c': { // class string descriptor = pool.GetPrimitiveConstant(data.ReadUnsignedShort()).GetString (); VarType type = FieldDescriptor.ParseDescriptor(descriptor).type; string value; switch (type.type) { case ICodeConstants.Type_Object: { value = type.value; break; } case ICodeConstants.Type_Byte: { value = typeof(byte).FullName; break; } case ICodeConstants.Type_Char: { value = typeof(char).FullName; break; } case ICodeConstants.Type_Double: { value = typeof(double).FullName; break; } case ICodeConstants.Type_Float: { value = typeof(float).FullName; break; } case ICodeConstants.Type_Int: { value = typeof(int).FullName; break; } case ICodeConstants.Type_Long: { value = typeof(long).FullName; break; } case ICodeConstants.Type_Short: { value = typeof(short).FullName; break; } case ICodeConstants.Type_Boolean: { value = typeof(bool).FullName; break; } case ICodeConstants.Type_Void: { value = typeof(void).FullName; break; } default: { throw new Exception("invalid class type: " + type.type); } } return(new ConstExprent(VarType.Vartype_Class, value, null)); } case '[': { // array List <Exprent> elements = new System.Collections.Generic.List <Exprent>(); int len = data.ReadUnsignedShort(); if (len > 0) { elements = new List <Exprent>(len); for (int i = 0; i < len; i++) { elements.Add(ParseAnnotationElement(data, pool)); } } VarType newType; if ((elements.Count == 0)) { newType = new VarType(ICodeConstants.Type_Object, 1, "java/lang/Object"); } else { VarType elementType = elements[0].GetExprType(); newType = new VarType(elementType.type, 1, elementType.value); } NewExprent newExpr = new NewExprent(newType, new System.Collections.Generic.List < Exprent>(), null); newExpr.SetDirectArrayInit(true); newExpr.SetLstArrayElements(elements); return(newExpr); } case '@': { // annotation return(ParseAnnotation(data, pool)); } default: { PrimitiveConstant cn = pool.GetPrimitiveConstant(data.ReadUnsignedShort()); switch (tag) { case 'B': { return(new ConstExprent(VarType.Vartype_Byte, cn.value, null)); } case 'C': { return(new ConstExprent(VarType.Vartype_Char, cn.value, null)); } case 'D': { return(new ConstExprent(VarType.Vartype_Double, cn.value, null)); } case 'F': { return(new ConstExprent(VarType.Vartype_Float, cn.value, null)); } case 'I': { return(new ConstExprent(VarType.Vartype_Int, cn.value, null)); } case 'J': { return(new ConstExprent(VarType.Vartype_Long, cn.value, null)); } case 'S': { return(new ConstExprent(VarType.Vartype_Short, cn.value, null)); } case 'Z': { return(new ConstExprent(VarType.Vartype_Boolean, cn.value, null)); } case 's': { return(new ConstExprent(VarType.Vartype_String, cn.value, null)); } default: { throw new Exception("invalid element type!"); } } break; } } }
/// <exception cref="System.IO.IOException"/> public override void InitContent(DataInputFullStream data, ConstantPool pool) { int index = data.ReadUnsignedShort(); signature = pool.GetPrimitiveConstant(index).GetString(); }