public TypeGenerator(PEemitter emitter, ClassFactory factory) { this.emitter = emitter; this.factory = factory; tpBldCache = new Hashtable(); typeCache = new Hashtable(); // populate basic types typeCache["byte"] = typeof(byte); typeCache["char"] = typeof(char); typeCache["double"] = typeof(double); typeCache["float"] = typeof(float); typeCache["int"] = typeof(int); typeCache["long"] = typeof(long); typeCache["short"] = typeof(short); typeCache["bool"] = typeof(bool); typeCache["void"] = typeof(void); }
public static void Main(string[] args) { try { CaffeOptions opt = CaffeOptions.Instance; opt.ProcessArgs(); if (opt.Verbose) { Debug.Listeners.Add(new TextWriterTraceListener(Console.Out)); Debug.AutoFlush = true; } if (opt.RemainingArguments.Length == 0) { opt.DoUsage(); throw new ApplicationException("Jar files to be processed not specified"); } string assemblyName = opt.Output; if (assemblyName == null) { assemblyName = opt.RemainingArguments[0]; FileInfo info = new FileInfo(assemblyName); if (!info.Exists) { throw new ApplicationException("File does not exist: " + assemblyName); } int index = assemblyName.LastIndexOf(".jar"); if (index < 0) { index = assemblyName.LastIndexOf(".zip"); } if (index > 0) { assemblyName = assemblyName.Substring(0, index); } assemblyName += ".dll"; Console.WriteLine("Output assembly: {0}" + " (Use /out switch to specify assembly name)", assemblyName); } // 1st pass: load class files in each Jar into a hashtable Hashtable classFiles = new Hashtable(); foreach (string file in opt.RemainingArguments) { // try/catch purposely to allow processing to continue try { JarFile j = new JarFile(file); foreach (DictionaryEntry entry in j.Classes) { // WARNING: silently overwrites existing class classFiles[entry.Key] = entry.Value; } } catch (ApplicationException e) { Console.WriteLine("Error while processing {0}: {1}", file, e.Message); } } // 2nd pass: load classes from class files and assembly references ClassFactory factory = new ClassFactory(classFiles, opt.References); foreach (ClassFile cf in classFiles.Values) { factory.LoadClass(cf.Name); } // 3rd pass: dereference inner types factory.ResolveInnerClasses(); // Actual generation PEemitter emitter = new PEemitter(); TypeGenerator bld = new TypeGenerator( emitter, factory); emitter.BeginModule(assemblyName); // 1st pass: generate all type builders // (in order to avoid cyclic references) foreach (string classFile in classFiles.Keys) { bld.AddType(factory.LoadClass(classFile)); } Console.WriteLine("Generating types"); // 2nd pass: generate type implementation foreach (string classFile in classFiles.Keys) { Class c = factory.LoadClass(classFile); bld.Generate(c); } Console.WriteLine("Baking types"); // 3rd pass: "******" types (inner order matters) bld.EndTypes(); // 4th save assembly emitter.EndModule(); } catch (Exception e) { Console.WriteLine(e); Console.WriteLine("Error: {0}", e.Message); System.Environment.Exit(1); } }
static Descriptor ProcessDescriptor(string value, ClassFactory factory) { Descriptor descriptor = new Descriptor(); string t = GetTypeForDescriptor(value); if (ARRAY_TYPE.Equals(t)) { descriptor.Component = ProcessDescriptor(value.Substring(1), factory); descriptor.IsArrayType = true; } else if (OBJECT_TYPE.Equals(t)) { string des = GetTypeForObjectType(value); descriptor.Class = factory.LoadClass(des); descriptor.IsObjectType = true; } else { descriptor.Class = factory.LoadClass(t); descriptor.IsBasicType = true; } return descriptor; }
void ProcessMethodDescriptorString(Method m, string value, ClassFactory factory) { string args = value.Substring(1, value.IndexOf(')') - 1); int index = 0; while (index < args.Length) { string arg = args.Substring(index); Descriptor d = ProcessDescriptor (arg, factory); if (d.IsBasicType) { index++; } else if (d.IsObjectType) { index += d.Class.InternalName.Length + 2; // Ljava/util/List; } else { index++; // [ Descriptor componentType = d; while ((componentType = componentType.Component).IsArrayType) { index++; // [ } if (componentType.IsBasicType) { index++; // [B } else { index += componentType.Class.InternalName.Length + 2; // Ljava/util/List; } } m.AddArgument(d); } m.Return = ProcessDescriptor(value.Substring(value.IndexOf(')') + 1), factory); }
public void BuildClass(Class c, ClassFactory factory) { // accessFlags c.AccessFlags = (Class.AccessFlag) accessFlags; // thisClass c.InternalName = GetClassName(thisClass); // superClass c.AddBaseType(factory.LoadClass(GetClassName(superClass))); // interfaces foreach (ushort iface in interfaces) { c.AddBaseType(factory.LoadClass(GetClassName(iface))); } // fields foreach (FieldInfo info in fields) { Field f = new Field(c); f.AccessFlags = (Field.AccessFlag) info.AccessFlags; f.Name = GetUtf8(info.NameIndex); f.Signature = GetUtf8(info.DescriptorIndex); f.Descriptor = ProcessDescriptor(f.Signature, factory); c.AddField(f); } // methods foreach (MethodInfo info in methods) { Method m = new Method(c); m.AccessFlags = (Method.AccessFlag) info.AccessFlags; m.Name = GetUtf8(info.NameIndex); m.Signature = GetUtf8(info.DescriptorIndex); ProcessMethodDescriptorString(m, m.Signature, factory); c.AddMethod(m); } }