|
Scala example source code file (PEModule.java)
The Scala PEModule.java source code/* * System.Reflection-like API for access to .NET assemblies (DLL & EXE) */ package ch.epfl.lamp.compiler.msil; import ch.epfl.lamp.compiler.msil.PEFile; import ch.epfl.lamp.compiler.msil.PEFile.Sig; import ch.epfl.lamp.compiler.msil.util.Signature; import ch.epfl.lamp.compiler.msil.util.Table; import ch.epfl.lamp.compiler.msil.util.Table.*; import java.nio.ByteBuffer; /** Represents a module corresponding to a PE/COFF file * * @author Nikolay Mihaylov * @version 1.0 */ final class PEModule extends Module { //########################################################################## protected final PEFile pefile; private final int definingRow; private Type[] typeRefs = null; protected PEModule(PEFile pefile, int definingRow, String scopeName, Assembly assem) { super(pefile.getName(), pefile.getAbsolutePath(), scopeName, assem); this.pefile = pefile; this.definingRow = definingRow; pefile.initModule(this); pefile.TypeDef.load(); // load into memory //loadTypes(); //pefile.FieldDef.load(); //pefile.MethodDef.load(); loadGlobals(); } //########################################################################## public Type GetType(String typeName) { initTypes(); Object o = typesMap.get(typeName); if (o == null) { //System.out.println("PEModule.GetType(): Unable to find type " // + typeName + " int module " + this); return null; } return o instanceof Type ? (Type)o : getTypeDef(((Integer)o).intValue()); } /** Load information about the types defined in this module. */ protected void loadTypes() { typeRefs = new Type[pefile.TypeRef.rows]; final int nbTypes = pefile.TypeDef.rows; for (int row = 2; row <= nbTypes; row++) { String name = pefile.TypeDef(row).getFullName(); typesMap.put(name, new Integer(row)); } this.types = new Type[nbTypes - 1]; for (int row = 2; row <= nbTypes; row++) { getTypeDef(row); } } /** Return the type defined at the given row in the TypeDef table. */ Type getTypeDef(int row) { if (this.types[row - 2] != null) return this.types[row - 2]; TypeDef type = pefile.TypeDef(row); int attrs = type.Flags; String name = type.getFullName(); Type declType = null; if (TypeAttributes.isNested(attrs)) { for (int i = 1; i <= pefile.NestedClass.rows; i++) { pefile.NestedClass.readRow(i); if (pefile.NestedClass.NestedClass == row) declType = getTypeDef (pefile.NestedClass.EnclosingClass); } } Type t = new PEType (this, attrs, name, declType, Type.AuxAttr.None, pefile, row); types[row - 2] = t; addType(t); int[] tvarIdxes = pefile.GenericParam.getTVarIdxes(row); // if(tvarIdxes.length > 0) { System.out.println("Type: " + t); } for(int i = 0; i < tvarIdxes.length; i++) { GenericParamAndConstraints tvarAndConstraints = getTypeConstraints(tvarIdxes[i]); // add tvarAndConstraints as i-th TVar in t t.addTVar(tvarAndConstraints); } return t; } public GenericParamAndConstraints getTypeConstraints(int genParamIdx) { int tvarNumber = pefile.GenericParam(genParamIdx).Number; // tvarName can be null String tvarName = pefile.GenericParam.getName(); boolean isInvariant = pefile.GenericParam.isInvariant(); boolean isCovariant = pefile.GenericParam.isCovariant(); boolean isContravariant = pefile.GenericParam.isContravariant(); boolean isReferenceType = pefile.GenericParam.isReferenceType(); boolean isValueType = pefile.GenericParam.isValueType(); boolean hasDefaultConstructor = pefile.GenericParam.hasDefaultConstructor(); // grab constraints int[] TypeDefOrRefIdxes = pefile.GenericParamConstraint.getTypeDefOrRefIdxes(genParamIdx); Type[] tCtrs = new Type[TypeDefOrRefIdxes.length]; for(int i = 0; i < TypeDefOrRefIdxes.length; i++) { Type tConstraint = getTypeDefOrRef(TypeDefOrRefIdxes[i]); tCtrs[i] = tConstraint; // System.out.println("\t\tConstraint: " + tConstraint); } GenericParamAndConstraints res = new GenericParamAndConstraints(tvarNumber, tvarName, tCtrs, isInvariant, isCovariant, isContravariant, isReferenceType, isValueType, hasDefaultConstructor); return res; } /** * Load the desription of the module-global fields and methods */ protected void loadGlobals() { //TODO: } protected void loadCustomAttributes(Type attributeType) { initAttributes(this, 1, Table.ModuleDef.ID, attributeType); } /** Return the type referenced by the given row in the TypeRef table. */ Type getTypeRef(int row) { return getTypeRef(row, null); } /** Return the type referenced by the given row in the TypeRef table * only if it resides in the given assembly. * <i>Used by initCustomAttributes to avoid unnecessary loading * of referenced assemblies.</i> */ Type getTypeRef(int row, Assembly inAssembly) { Type type = typeRefs[row - 1]; if (type != null) return type; Table.TypeRef tr = pefile.TypeRef; tr.readRow(row); int tableId = Table.getTableId(Table._ResolutionScope, tr.ResolutionScope); int refRow = tr.ResolutionScope >> Table.NoBits[Table._ResolutionScope]; final String typeName = tr.getFullName(); pefile.getTable(tableId).readRow(refRow); switch (tableId) { case AssemblyRef.ID: String name = pefile.AssemblyRef.getName(); if (inAssembly != null && !inAssembly.GetName().Name.equals(name)) return null; Assembly assem = getAssembly(name); type = assem.GetType(typeName); if (type == null) { // HACK: the IKVM.OpenJDK.Core assembly is compiled against mscorlib.dll v2.0 // The MSIL library cannot parse the v2.0 mscorlib because of generics, so we // use the v1.0 // However, the java.io.FileDescriptor.FlushFileBuffers method uses a type // Microsoft.Win32.SafeHandles.SafeFileHandle, which only exists in mscorlib // v2.0 // For now, jsut return Object (fine as long as we don't use that method). Assembly asmb = getAssembly("mscorlib"); type = asmb.GetType("System.Object"); //throw new RuntimeException("Failed to locate type " + //typeName + " in assembly " + assem); } break; case ModuleDef.ID: assert refRow == 1; type = this.GetType(typeName); //assert type != null; break; case TypeRef.ID: Type nestingType = getTypeRef(refRow); String nestedName = typeName; type = nestingType.GetNestedType(nestedName); break; case ModuleRef.ID: type = getAssembly(pefile.ModuleRef.getName()).GetType(typeName); default: throw new RuntimeException(refRow + "@" + pefile.getTable(tableId).getTableName()/* PEFile.byte2hex(tableId)*/); } if (typeRefs[row - 1] != null) System.out.println("TypeRef[" + PEFile.short2hex(row) + "] " + "changing type " + typeRefs[row - 1] + " for type " + type); typeRefs[row - 1] = type; assert type != null : "Couldn't find type " + typeName; return type; } private Assembly getAssembly(String name) { Assembly assem = Assembly.getAssembly(name); if (assem != null) return assem; java.io.File dir = pefile.getParentFile(); assem = Assembly.LoadFrom(dir, name); if (assem != null) return assem; try { dir = pefile.getUnderlyingFile().getCanonicalFile().getParentFile(); } catch (java.io.IOException e) { throw new RuntimeException(e); } assem = Assembly.LoadFrom(dir, name); if (assem != null) return assem; throw new RuntimeException("Cannot find assembly: " + name); } /** Return the type corresponding to TypeDefOrRef coded index. * @param index - TypeDefOrRef coded index according to 23.2.6. */ public Type getTypeDefOrRef(int index) { int tableId = Table.getTableId(Table._TypeDefOrRef, index); int row = index >> Table.NoBits[Table._TypeDefOrRef]; Type type = null; switch (tableId) { case Table.TypeDef.ID: type = getTypeDef(row); break; case Table.TypeRef.ID: return getTypeRef(row); case Table.TypeSpec.ID: Table.TypeSpec ts = pefile.TypeSpec; ts.readRow(row); int posInBlobStream = ts.Signature; byte[] blobArrWithLengthStripped = pefile.Blob.getBlob(posInBlobStream); byte[] compressedUInt = compressUInt(blobArrWithLengthStripped.length); byte[] byteArr = new byte[blobArrWithLengthStripped.length + compressedUInt.length]; System.arraycopy(compressedUInt, 0, byteArr, 0, compressedUInt.length); System.arraycopy(blobArrWithLengthStripped, 0, byteArr, compressedUInt.length, blobArrWithLengthStripped.length); ByteBuffer buf = ByteBuffer.wrap(byteArr); Sig sig = pefile.new Sig(buf); int desc = sig.readByte(); switch (desc) { // GENERICINST (CLASS | VALUETYPE) TypeDefOrRefEncodred GenArgCount Type* case Signature.ELEMENT_TYPE_GENERICINST: // i.e. 0x15 int b = sig.readByte(); // i.e. (0x12 | 0x11) /* TODO don't ignore b as done above */ Type instantiatedType = getTypeDefOrRef(sig.decodeInt()); // TypeDefOrRefEncoded int numberOfTypeArgs = sig.decodeInt(); // GenArgCount Type[] typeArgs = new Type[numberOfTypeArgs]; for (int iarg = 0; iarg < numberOfTypeArgs; iarg++) { typeArgs[iarg] = sig.decodeType(); // Type* } type = new ConstructedType(instantiatedType, typeArgs); break; /* Miguel says: Actually the following grammar rule production is not among those for a TypeSpecBlob but I've found it in assemblies compiled from C# 3.0. See also duplicate code in PEFile.java */ case Signature.ELEMENT_TYPE_VAR: int typeArgAsZeroBased = sig.decodeInt(); type = new Type.TMVarUsage(typeArgAsZeroBased, true); break; /* Miguel says: Actually the following grammar rule production is not among those for a TypeSpecBlob but I've found it in assemblies compiled from C# 3.0. See also duplicate code in PEFile.java */ case Signature.ELEMENT_TYPE_MVAR: typeArgAsZeroBased = sig.decodeInt(); type = new Type.TMVarUsage(typeArgAsZeroBased, false); break; case Signature.ELEMENT_TYPE_SZARRAY: // Single-dim array with 0 lower bound. sig.skipCustomMods(); type = Type.mkArray(sig.decodeType(), 1); break; case Signature.ELEMENT_TYPE_ARRAY: // <type> Other Scala examples (source code examples)Here is a short list of links related to this Scala PEModule.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.