public virtual VarVersionNode CreateNode(VarVersionPair ver) { VarVersionNode node; nodes.AddWithKey(node = new VarVersionNode(ver.var, ver.version), ver); return(node); }
private VBStyleCollection <BasicBlock, int> CreateBasicBlocks(short[] startblock, InstructionSequence instrseq, Dictionary <int, BasicBlock> mapInstrBlocks) { VBStyleCollection <BasicBlock, int> col = new VBStyleCollection <BasicBlock, int>(); InstructionSequence currseq = null; List <int> lstOffs = null; int len = startblock.Length; short counter = 0; int blockoffset = 0; BasicBlock currentBlock = null; for (int i = 0; i < len; i++) { if (startblock[i] == 1) { currentBlock = new BasicBlock(++counter); currseq = currentBlock.GetSeq(); lstOffs = currentBlock.GetInstrOldOffsets(); col.AddWithKey(currentBlock, currentBlock.id); blockoffset = instrseq.GetOffset(i); } startblock[i] = counter; Sharpen.Collections.Put(mapInstrBlocks, i, currentBlock); currseq.AddInstruction(instrseq.GetInstr(i), instrseq.GetOffset(i) - blockoffset); lstOffs.Add(instrseq.GetOffset(i)); } last_id = counter; return(col); }
private void OrderNodes() { setRoots = graph.GetRoots(); foreach (var node in graph.GetReversePostOrderList()) { colOrderedIDoms.AddWithKey(null, node); } }
/// <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); }
public virtual void CollapseNodesToStatement(Statement stat) { Statement head = stat.GetFirst(); Statement post = stat.GetPost(); VBStyleCollection <Statement, int> setNodes = stat.GetStats(); // post edges if (post != null) { foreach (StatEdge edge in post.GetEdges(Statedge_Direct_All, Direction_Backward)) { if (stat.ContainsStatementStrict(edge.GetSource())) { edge.GetSource().ChangeEdgeType(Direction_Forward, edge, StatEdge.Type_Break); stat.AddLabeledEdge(edge); } } } // regular head edges foreach (StatEdge prededge in head.GetAllPredecessorEdges()) { if (prededge.GetType() != StatEdge.Type_Exception && stat.ContainsStatementStrict (prededge.GetSource())) { prededge.GetSource().ChangeEdgeType(Direction_Forward, prededge, StatEdge.Type_Continue ); stat.AddLabeledEdge(prededge); } head.RemovePredecessor(prededge); prededge.GetSource().ChangeEdgeNode(Direction_Forward, prededge, stat); stat.AddPredecessor(prededge); } if (setNodes.ContainsKey(first.id)) { first = stat; } // exception edges HashSet <Statement> setHandlers = new HashSet <Statement>(head.GetNeighbours(StatEdge .Type_Exception, Direction_Forward)); foreach (Statement node in setNodes) { setHandlers.UnionWith(node.GetNeighbours(StatEdge.Type_Exception, Direction_Forward )); } if (!(setHandlers.Count == 0)) { foreach (StatEdge edge in head.GetEdges(StatEdge.Type_Exception, Direction_Forward )) { Statement handler = edge.GetDestination(); if (setHandlers.Contains(handler)) { if (!setNodes.ContainsKey(handler.id)) { stat.AddSuccessor(new StatEdge(stat, handler, edge.GetExceptions())); } } } foreach (Statement node in setNodes) { foreach (StatEdge edge in node.GetEdges(StatEdge.Type_Exception, Direction_Forward )) { if (setHandlers.Contains(edge.GetDestination())) { node.RemoveSuccessor(edge); } } } } if (post != null && !stat.GetNeighbours(StatEdge.Type_Exception, Direction_Forward ).Contains(post)) { // TODO: second condition redundant? stat.AddSuccessor(new StatEdge(StatEdge.Type_Regular, stat, post)); } // adjust statement collection foreach (Statement st in setNodes) { stats.RemoveWithKey(st.id); } stats.AddWithKey(stat, stat.id); stat.SetAllParent(); stat.SetParent(this); stat.BuildContinueSet(); // monitorenter and monitorexit stat.BuildMonitorFlags(); if (stat.type == Type_Switch) { // special case switch, sorting leaf nodes ((SwitchStatement)stat).SortEdgesAndNodes(); } }
public virtual void Init() { DecompilerContext.SetProperty(DecompilerContext.Current_Class, classStruct); DecompilerContext.SetProperty(DecompilerContext.Current_Class_Wrapper, this); DecompilerContext.GetLogger().StartClass(classStruct.qualifiedName); int maxSec = System.Convert.ToInt32(DecompilerContext.GetProperty(IFernflowerPreferences .Max_Processing_Method).ToString()); bool testMode = DecompilerContext.GetOption(IFernflowerPreferences.Unit_Test_Mode ); foreach (StructMethod mt in classStruct.GetMethods()) { DecompilerContext.GetLogger().StartMethod(mt.GetName() + " " + mt.GetDescriptor() ); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); VarProcessor varProc = new VarProcessor(mt, md); DecompilerContext.StartMethod(varProc); VarNamesCollector vc = varProc.GetVarNamesCollector(); CounterContainer counter = DecompilerContext.GetCounterContainer(); RootStatement root = null; bool isError = false; try { if (mt.ContainsCode()) { if (maxSec == 0 || testMode) { root = MethodProcessorRunnable.CodeToJava(mt, md, varProc); } else { MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, md, varProc, DecompilerContext .GetCurrentContext()); Thread mtThread = new Thread(o => mtProc.Run()) { Name = "Java decompiler" }; long stopAt = Runtime.CurrentTimeMillis() + maxSec * 1000L; mtThread.Start(); while (!mtProc.IsFinished()) { try { lock (mtProc.Lock) { Thread.Sleep(200); } } catch (Exception e) { KillThread(mtThread); throw; } if (Runtime.CurrentTimeMillis() >= stopAt) { string message = "Processing time limit exceeded for method " + mt.GetName() + ", execution interrupted."; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Error ); KillThread(mtThread); isError = true; break; } } if (!isError) { root = mtProc.GetResult(); } } } else { bool thisVar = !mt.HasModifier(ICodeConstants.Acc_Static); int paramCount = 0; if (thisVar) { Sharpen.Collections.Put(varProc.GetThisVars(), new VarVersionPair(0, 0), classStruct .qualifiedName); paramCount = 1; } paramCount += [email protected]; int varIndex = 0; for (int i = 0; i < paramCount; i++) { varProc.SetVarName(new VarVersionPair(varIndex, 0), vc.GetFreeName(varIndex)); if (thisVar) { if (i == 0) { varIndex++; } else { varIndex += md.@params[i - 1].stackSize; } } else { varIndex += md.@params[i].stackSize; } } } } catch (Exception t) { string message = "Method " + mt.GetName() + " " + mt.GetDescriptor() + " couldn't be decompiled."; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn , t); isError = true; } MethodWrapper methodWrapper = new MethodWrapper(root, varProc, mt, counter); methodWrapper.decompiledWithErrors = isError; methods.AddWithKey(methodWrapper, InterpreterUtil.MakeUniqueKey(mt.GetName(), mt. GetDescriptor())); if (!isError) { // rename vars so that no one has the same name as a field VarNamesCollector namesCollector = new VarNamesCollector(); classStruct.GetFields().ForEach((StructField f) => namesCollector.AddName(f.GetName ())); varProc.RefreshVarNames(namesCollector); // if debug information present and should be used if (DecompilerContext.GetOption(IFernflowerPreferences.Use_Debug_Var_Names)) { StructLocalVariableTableAttribute attr = mt.GetLocalVariableAttr(); if (attr != null) { // only param names here varProc.SetDebugVarNames(attr.GetMapParamNames()); // the rest is here methodWrapper.GetOrBuildGraph().IterateExprents((Exprent exprent) => { List <Exprent> lst = exprent.GetAllExprents(true); lst.Add(exprent); lst.Where(e => e.type == Exprent.Exprent_Var).ToList().ForEach((Exprent e) => { VarExprent varExprent = (VarExprent)e; string name = varExprent.GetDebugName(mt); if (name != null) { varProc.SetVarName(varExprent.GetVarVersionPair(), name); } } ); return(0); } ); } } } DecompilerContext.GetLogger().EndMethod(); } DecompilerContext.GetLogger().EndClass(); }
public static VBStyleCollection <List <int>, int> CalcPostDominators(Statement container ) { Dictionary <Statement, FastFixedSetFactory <Statement> .FastFixedSet <Statement> > lists = new Dictionary <Statement, FastFixedSetFactory <Statement> .FastFixedSet <Statement> >(); StrongConnectivityHelper schelper = new StrongConnectivityHelper(container); List <List <Statement> > components = schelper.GetComponents(); List <Statement> lstStats = container.GetPostReversePostOrderList(StrongConnectivityHelper .GetExitReps(components)); FastFixedSetFactory <Statement> factory = new FastFixedSetFactory <Statement>(lstStats ); FastFixedSetFactory <Statement> .FastFixedSet <Statement> setFlagNodes = factory.SpawnEmptySet( ); setFlagNodes.SetAllElements(); FastFixedSetFactory <Statement> .FastFixedSet <Statement> initSet = factory.SpawnEmptySet(); initSet.SetAllElements(); foreach (List <Statement> lst in components) { FastFixedSetFactory <Statement> .FastFixedSet <Statement> tmpSet; if (StrongConnectivityHelper.IsExitComponent(lst)) { tmpSet = factory.SpawnEmptySet(); tmpSet.AddAll(lst); } else { tmpSet = initSet.GetCopy(); } foreach (Statement stat in lst) { Sharpen.Collections.Put(lists, stat, tmpSet); } } do { foreach (Statement stat in lstStats) { if (!setFlagNodes.Contains(stat)) { continue; } setFlagNodes.Remove(stat); FastFixedSetFactory <Statement> .FastFixedSet <Statement> doms = lists.GetOrNull(stat); FastFixedSetFactory <Statement> .FastFixedSet <Statement> domsSuccs = factory.SpawnEmptySet(); List <Statement> lstSuccs = stat.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Forward ); for (int j = 0; j < lstSuccs.Count; j++) { Statement succ = lstSuccs[j]; FastFixedSetFactory <Statement> .FastFixedSet <Statement> succlst = lists.GetOrNull(succ); if (j == 0) { domsSuccs.Union(succlst); } else { domsSuccs.Intersection(succlst); } } if (!domsSuccs.Contains(stat)) { domsSuccs.Add(stat); } if (!InterpreterUtil.EqualObjects(domsSuccs, doms)) { Sharpen.Collections.Put(lists, stat, domsSuccs); List <Statement> lstPreds = stat.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Backward ); foreach (Statement pred in lstPreds) { setFlagNodes.Add(pred); } } } }while (!setFlagNodes.IsEmpty()); VBStyleCollection <List <int>, int> ret = new VBStyleCollection <List <int>, int>(); List <Statement> lstRevPost = container.GetReversePostOrderList(); // sort order crucial! Dictionary <int, int> mapSortOrder = new Dictionary <int, int>(); for (int i = 0; i < lstRevPost.Count; i++) { Sharpen.Collections.Put(mapSortOrder, lstRevPost[i].id, i); } foreach (Statement st in lstStats) { List <int> lstPosts = new List <int>(); foreach (Statement stt in lists.GetOrNull(st)) { lstPosts.Add(stt.id); } lstPosts = lstPosts.OrderBy(c => mapSortOrder[c]).ToList(); if (lstPosts.Count > 1 && lstPosts[0] == st.id) { lstPosts.Add(lstPosts.RemoveAtReturningValue(0)); } ret.AddWithKey(lstPosts, st.id); } return(ret); }
private static Statement FindGeneralStatement(Statement stat, bool forceall, Dictionary <int, HashSet <int> > mapExtPost) { VBStyleCollection <Statement, int> stats = stat.GetStats(); VBStyleCollection <List <int>, int> vbPost; if ((mapExtPost.Count == 0)) { FastExtendedPostdominanceHelper extpost = new FastExtendedPostdominanceHelper(); Sharpen.Collections.PutAll(mapExtPost, extpost.GetExtendedPostdominators(stat)); } if (forceall) { vbPost = new VBStyleCollection <List <int>, int>(); List <Statement> lstAll = stat.GetPostReversePostOrderList(); foreach (Statement st in lstAll) { HashSet <int> set = mapExtPost.GetOrNull(st.id); if (set != null) { vbPost.AddWithKey(new List <int>(set), st.id); } } // FIXME: sort order!! // tail statements HashSet <int> setFirst = mapExtPost.GetOrNull(stat.GetFirst().id); if (setFirst != null) { foreach (int id in setFirst) { List <int> lst = vbPost.GetWithKey(id); if (lst == null) { vbPost.AddWithKey(lst = new List <int>(), id); } lst.Add(id); } } } else { vbPost = CalcPostDominators(stat); } for (int k = 0; k < vbPost.Count; k++) { int headid = vbPost.GetKey(k); List <int> posts = vbPost[k]; if (!mapExtPost.ContainsKey(headid) && !(posts.Count == 1 && posts[0].Equals(headid ))) { continue; } Statement head = stats.GetWithKey(headid); HashSet <int> setExtPosts = mapExtPost.GetOrNull(headid); foreach (int postId in posts) { if (!postId.Equals(headid) && !setExtPosts.Contains(postId)) { continue; } Statement post = stats.GetWithKey(postId); if (post == null) { // possible in case of an inherited postdominance set continue; } bool same = (post == head); HashSet <Statement> setNodes = new HashSet <Statement>(); HashSet <Statement> setPreds = new HashSet <Statement>(); // collect statement nodes HashSet <Statement> setHandlers = new HashSet <Statement>(); setHandlers.Add(head); while (true) { bool hdfound = false; foreach (Statement handler in setHandlers) { if (setNodes.Contains(handler)) { continue; } bool addhd = (setNodes.Count == 0); // first handler == head if (!addhd) { List <Statement> hdsupp = handler.GetNeighbours(StatEdge.Type_Exception, Statement .Direction_Backward); addhd = (setNodes.ContainsAll(hdsupp) && (setNodes.Count > hdsupp.Count || setNodes .Count == 1)); } // strict subset if (addhd) { LinkedList <Statement> lstStack = new LinkedList <Statement>(); lstStack.AddLast(handler); while (!(lstStack.Count == 0)) { Statement st = lstStack.RemoveAtReturningValue(0); if (!(setNodes.Contains(st) || (!same && st == post))) { setNodes.Add(st); if (st != head) { // record predeccessors except for the head Sharpen.Collections.AddAll(setPreds, st.GetNeighbours(StatEdge.Type_Regular, Statement .Direction_Backward)); } // put successors on the stack Sharpen.Collections.AddAll(lstStack, st.GetNeighbours(StatEdge.Type_Regular, Statement .Direction_Forward)); // exception edges Sharpen.Collections.AddAll(setHandlers, st.GetNeighbours(StatEdge.Type_Exception, Statement.Direction_Forward)); } } hdfound = true; setHandlers.Remove(handler); break; } } if (!hdfound) { break; } } // check exception handlers setHandlers.Clear(); foreach (Statement st in setNodes) { Sharpen.Collections.AddAll(setHandlers, st.GetNeighbours(StatEdge.Type_Exception, Statement.Direction_Forward)); } setHandlers.RemoveAll(setNodes); bool excok = true; foreach (Statement handler in setHandlers) { if (!handler.GetNeighbours(StatEdge.Type_Exception, Statement.Direction_Backward) .ContainsAll(setNodes)) { excok = false; break; } } // build statement and return if (excok) { Statement res; setPreds.RemoveAll(setNodes); if (setPreds.Count == 0) { if ((setNodes.Count > 1 || head.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Backward ).Contains(head)) && setNodes.Count < stats.Count) { if (CheckSynchronizedCompleteness(setNodes)) { res = new GeneralStatement(head, setNodes, same ? null : post); stat.CollapseNodesToStatement(res); return(res); } } } } } } return(null); }
private static RootStatement GraphToStatement(ControlFlowGraph graph) { VBStyleCollection <Statement, int> stats = new VBStyleCollection <Statement, int>(); VBStyleCollection <BasicBlock, int> blocks = graph.GetBlocks(); foreach (BasicBlock block in blocks) { stats.AddWithKey(new BasicBlockStatement(block), block.id); } BasicBlock firstblock = graph.GetFirst(); // head statement Statement firstst = stats.GetWithKey(firstblock.id); // dummy exit statement DummyExitStatement dummyexit = new DummyExitStatement(); Statement general; if (stats.Count > 1 || firstblock.IsSuccessor(firstblock)) { // multiple basic blocks or an infinite loop of one block general = new GeneralStatement(firstst, stats, null); } else { // one straightforward basic block RootStatement root = new RootStatement(firstst, dummyexit); firstst.AddSuccessor(new StatEdge(StatEdge.Type_Break, firstst, dummyexit, root)); return(root); } foreach (BasicBlock block in blocks) { Statement stat = stats.GetWithKey(block.id); foreach (BasicBlock succ in block.GetSuccs()) { Statement stsucc = stats.GetWithKey(succ.id); int type; if (stsucc == firstst) { type = StatEdge.Type_Continue; } else if (graph.GetFinallyExits().Contains(block)) { type = StatEdge.Type_Finallyexit; stsucc = dummyexit; } else if (succ.id == graph.GetLast().id) { type = StatEdge.Type_Break; stsucc = dummyexit; } else { type = StatEdge.Type_Regular; } stat.AddSuccessor(new StatEdge(type, stat, (type == StatEdge.Type_Continue) ? general : stsucc, (type == StatEdge.Type_Regular) ? null : general)); } // exceptions edges foreach (BasicBlock succex in block.GetSuccExceptions()) { Statement stsuccex = stats.GetWithKey(succex.id); ExceptionRangeCFG range = graph.GetExceptionRange(succex, block); if (!range.IsCircular()) { stat.AddSuccessor(new StatEdge(stat, stsuccex, range.GetExceptionTypes())); } } } general.BuildContinueSet(); general.BuildMonitorFlags(); return(new RootStatement(general, dummyexit)); }
/// <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(); }
public virtual void AddInstruction(Instruction inst, int offset) { collinstr.AddWithKey(inst, offset); }
private void SplitJsrRange(BasicBlock jsr, BasicBlock ret, HashSet <BasicBlock> common_blocks ) { List <BasicBlock> lstNodes = new List <BasicBlock>(); Dictionary <int, BasicBlock> mapNewNodes = new Dictionary <int, BasicBlock>(); lstNodes.Add(jsr); Sharpen.Collections.Put(mapNewNodes, jsr.id, jsr); while (!(lstNodes.Count == 0)) { BasicBlock node = lstNodes.RemoveAtReturningValue(0); for (int j = 0; j < 2; j++) { List <BasicBlock> lst; if (j == 0) { if (node.GetLastInstruction().opcode == ICodeConstants.opc_ret) { if (node.GetSuccs().Contains(ret)) { continue; } } lst = node.GetSuccs(); } else { if (node == jsr) { continue; } lst = node.GetSuccExceptions(); } for (int i = lst.Count - 1; i >= 0; i--) { BasicBlock child = lst[i]; int childid = child.id; if (mapNewNodes.ContainsKey(childid)) { node.ReplaceSuccessor(child, mapNewNodes.GetOrNull(childid)); } else if (common_blocks.Contains(child)) { // make a copy of the current block BasicBlock copy = child.Clone(); copy.id = ++last_id; // copy all successors if (copy.GetLastInstruction().opcode == ICodeConstants.opc_ret && child.GetSuccs( ).Contains(ret)) { copy.AddSuccessor(ret); child.RemoveSuccessor(ret); } else { for (int k = 0; k < child.GetSuccs().Count; k++) { copy.AddSuccessor(child.GetSuccs()[k]); } } for (int k = 0; k < child.GetSuccExceptions().Count; k++) { copy.AddSuccessorException(child.GetSuccExceptions()[k]); } lstNodes.Add(copy); Sharpen.Collections.Put(mapNewNodes, childid, copy); if (last.GetPreds().Contains(child)) { last.AddPredecessor(copy); } node.ReplaceSuccessor(child, copy); blocks.AddWithKey(copy, copy.id); } else { // stop at the first fixed node //lstNodes.add(child); Sharpen.Collections.Put(mapNewNodes, childid, child); } } } } // note: subroutines won't be copied! SplitJsrExceptionRanges(common_blocks, mapNewNodes); }