private MethodGenerator(JavaAssemblyBuilder ab, MethodDefinition md, JavaMethodInfo mi, CodeAttribute ca, CpInfo[] cp) { _ab = ab; _md = md; _mi = mi; _ca = ca; _cp = cp; }
public static MethodBody GenerateMethod(MethodDefinition md, JavaMethodInfo mi, CodeAttribute ca, CpInfo[] cp) { var mg = new MethodGenerator(JavaAssemblyBuilder.Instance, md, mi, ca, cp); //Console.WriteLine(md.FullName); //foreach (var entry in ca.ExceptionTable) //{ // Console.WriteLine(" try {{ {0:X4} .. {1:X4} }} catch ({3}) {{ {2:X4} }}", entry.StartPc, entry.EndPc, entry.HandlerPc, entry.CatchType != 0 ? cp[entry.CatchType].Represent() : "*"); //} mg.DivideIntoOps(); if (mg._ops.Any(x => x?.Instr == JavaInstruction.invokedynamic)) { throw new JavaNetException(JavaNetException.ReasonType.ClassLoad, "invokedynamic"); } //foreach (var op in mg._ops) //{ // if (op != null) // Console.WriteLine(op); //} mg.BlockAnalyzer(); //foreach (var block in mg._blocks.Values.OrderBy(x => x.JavaOffset)) //{ // Console.WriteLine(" {0}: [{1} ops]", block, block.JavaOps.Count); // foreach (var op in block.JavaOps) // { // Console.WriteLine(" {0}", op); // } //} mg._body = mg._md.Body; mg.ValueAnalyzer(); //foreach (var block in mg._blocks.Values.OrderBy(x => x.JavaOffset)) //{ // Console.WriteLine(" {0}: [{1} actions]", block, block.Actions.Count); // if (!block.Generated) // { // Console.WriteLine(" [NOT GENERATED]"); // } // foreach (var action in block.Actions) // { // Console.WriteLine(" {0}", action); // } //} var values = mg._blocks.Values.SelectMany(x => x.Actions.SelectMany(a => a.RequiredValues)).Distinct().Count(); mg.LocalAnalyzer(); foreach (var local in mg._locals) { mg._body.Variables.Add(local); } mg.HandlerAnalyzer(); mg.ActionGenerator(); //foreach (var entry in mg._ca.ExceptionTable) //{ // //var (handlerIndex, handlerBlocks) = mg._handlers.First(x => x.Value[0].JavaOffset == entry.HandlerPc); // //body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch) // //{ // // TryStart = mg._blocks[entry.StartPc].FirstNetOp, // // TryEnd = mg._blocks[entry.EndPc].FirstNetOp, // // HandlerStart = handlerBlocks[0].FirstNetOp, // // HandlerEnd = mg._blocks[handlerBlocks.Last().JavaOffset + handlerBlocks.Last().JavaLength].FirstNetOp, // // CatchType = handlerBlocks[0].ExceptionValue.ActualType // //}); // Debug.Assert(mg._blocks[entry.EndPc].JavaOps[0].Instr == JavaInstruction.@goto); //} mg._body.Optimize(); return(mg._body); }