static void EmitUnboxAny(TypeMapEntry tme)
 {
     Emit(tme.instrs);
     Emit("box " + tme.ilty);
     Emit("unbox.any " + tme.ilty);
     EmitPrint(tme);
 }
    static string EmitLocal(TypeMapEntry tme, string prefix)
    {
        string varname = "'" + prefix + "_" + tme.ty + "'";

        Emit(".locals(" + tme.ilty + " " + varname + ")");
        return(varname);
    }
    static void EmitInitObj(TypeMapEntry tme)
    {
        string dest = EmitLocal(tme);

        Emit("ldloca " + dest);
        Emit("initobj " + tme.ilty);
        Emit("ldloc " + dest);
        EmitPrint(tme);
    }
    static void EmitStObj(TypeMapEntry tme)
    {
        string varname = EmitLocal(tme);

        Emit("ldloca " + varname);
        Emit(tme.instrs);
        Emit("stobj " + tme.ilty);
        Emit("ldloc " + varname);
        EmitPrint(tme);
    }
Esempio n. 5
0
        public void TypeMapConstructorTest()
        {
            FileType     ft      = new FileType("binary");
            TypeMapEntry mapping = new TypeMapEntry(ft, "//depot/main/...");
            FormSpec     spec    = null;
            TypeMap      target  = new TypeMap(mapping, spec);

            Assert.IsNotNull(target);
            Assert.AreEqual(target.Mapping.FileType.BaseType, BaseFileType.Binary);
            Assert.AreEqual(target.Mapping.Path, "//depot/main/...");
        }
    static void EmitCpObj(TypeMapEntry tme)
    {
        string src  = EmitLocal(tme, "S");
        string dest = EmitLocal(tme, "D");

        Emit(tme.instrs);
        Emit("stloc " + src);
        Emit("ldloca " + dest);
        Emit("ldloca " + src);
        Emit("cpobj " + tme.ilty);
        Emit("ldloc " + dest);
        EmitPrint(tme);
    }
Esempio n. 7
0
        public void MappingTest()
        {
            FileType     ft       = new FileType("binary");
            FileType     ft1      = new FileType("apple");
            FileType     ft2      = new FileType("text");
            TypeMapEntry mapping  = new TypeMapEntry(ft, "//depot/main/...");
            TypeMapEntry mapping1 = new TypeMapEntry(ft1, "//depot/dev/...");
            TypeMapEntry mapping2 = new TypeMapEntry(ft2, "//depot/rel/...");
            TypeMap      target   = new TypeMap();

            target.Add(mapping);
            target.Add(mapping1);
            target.Add(mapping2);
            Assert.IsNotNull(target);
            Assert.AreEqual(target.Count, 3);
            Assert.AreEqual(target[1].Path, "//depot/dev/...");
        }
    static void EmitUnboxAnyFail(TypeMapEntry tme)
    {
        string l1 = GenLabel();
        string l2 = GenLabel();

        EmitOpenBrace(".try");
        Emit("newobj instance void [mscorlib]System.Object::.ctor()");
        Emit("unbox.any " + tme.ilty);
        Emit("pop");
        Emit("leave " + l1);
        EmitCloseBrace();
        EmitOpenBrace("catch [mscorlib]System.InvalidCastException");
        Emit("pop");
        EmitPrintString("downcast failed\\n");
        Emit("leave " + l2);
        EmitCloseBrace();
        Emit(l1 + ":");
        EmitPrintString("downcast succeeded\\n");
        Emit(l2 + ":");
    }
    static void EmitStElemAny(TypeMapEntry tme)
    {
        Emit("ldc.i4 10 newarr " + tme.ilty);
        Emit("dup");
        Emit("ldc.i4 0");
        Emit(tme.instrs);
        Emit("stelem.any " + tme.ilty);

        Emit("ldc.i4 0");
        if (tme.isref)
        {
            Emit("ldelem.ref");
        }
        else
        {
            Emit("ldelem.any " + tme.ilty);
            Emit("box " + tme.ilty);
        }

        EmitWriteLine();
    }
    static void EmitLdElemAny(TypeMapEntry tme)
    {
        Emit("ldc.i4 10 newarr " + tme.ilty);
        Emit("dup");
        Emit("ldc.i4 0");
        if (tme.isref)
        {
            Emit(tme.instrs);
            Emit("stelem.ref");
        }
        else
        {
            Emit("ldelema " + tme.ilty);
            Emit(tme.instrs);
            Emit("stobj " + tme.ilty);
        }

        Emit("ldc.i4 0");
        Emit("ldelem.any " + tme.ilty);
        EmitPrint(tme);
    }
 static void EmitBoxAny(TypeMapEntry tme)
 {
     Emit(tme.instrs);
     Emit("box " + tme.ilty);
     EmitWriteLine();
 }
 static void EmitPrint(TypeMapEntry tme)
 {
     Emit("box " + tme.ilty);
     EmitWriteLine();
 }
Esempio n. 13
0
static void EmitUnboxAny(TypeMapEntry tme)
{
  Emit(tme.instrs);
  Emit("box " + tme.ilty);
  Emit("unbox.any " + tme.ilty);
  EmitPrint(tme);
}
    static int Main(string[] args)
    {
        string testname;
        string typename;

        TypeMapEntry[] types = typemap;
        TestMapEntry[] tests = testmap;

        filename = "test.il";

        foreach (string a in args)
        {
            int len = a.Length;
            if (len >= 2 && (a[0] == '/' || a[0] == '-'))
            {
                switch (Char.ToUpper(a[1]))
                {
                case 'I':
                    testname = a.Substring(3);
                    if (testname != "*")
                    {
                        tests = new TestMapEntry[1];
                        try { tests[0] = LookupTest(testname); }
                        catch (NotFound) { Console.WriteLine("No such test: " + testname); return(1); }
                    }
                    break;

                case 'T':
                    typename = a.Substring(3);
                    if (typename != "*")
                    {
                        types = new TypeMapEntry[1];
                        try { types[0] = LookupType(typename); }
                        catch (NotFound) { Console.WriteLine("No such type: " + typename); return(1); }
                    }
                    break;

                case 'F':
                    filename = a.Substring(3);
                    break;

                case 'X':
                    System.AppDomain.CurrentDomain.ExecuteAssembly("ilasm");
                    break;

                case '?':
                    Usage();
                    return(0);
                }
            }
        }

        FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);

        outstream = new StreamWriter(fs);

        Console.Write("Generating IL to " + filename + "...");
        EmitHeader();

        foreach (TestMapEntry test in tests)
        {
            EmitPrintString("********************************* " + test.description + " *************************\\n");
            foreach (TypeMapEntry type in types)
            {
                EmitPrintString("  on type " + type.ty + ": ");
                test.emitter(type);
            }
        }


        EmitFooter();
        outstream.Close();
        Console.Write("done.\n");
        return(0);
    }
Esempio n. 15
0
static int Main(string[] args)
{
  string testname;
  string typename;
  TypeMapEntry[] types = typemap;
  TestMapEntry[] tests = testmap;

  filename = "test.il";

  foreach (string a in args)
  {
    int len = a.Length;
    if (len >= 2 && (a[0] == '/' || a[0] == '-')) 
    {
      switch (Char.ToUpper(a[1])) 
      {
	case 'I':
          testname = a.Substring(3);
          if (testname != "*")          
          {
            tests = new TestMapEntry[1];
            try { tests[0] = LookupTest(testname); } 
            catch (NotFound) { Console.WriteLine("No such test: " + testname); return 1; }
          }
          break;
        case 'T':
          typename = a.Substring(3);
          if (typename != "*")
          {
            types = new TypeMapEntry[1];
            try { types[0] = LookupType(typename); }
            catch (NotFound) { Console.WriteLine("No such type: " + typename); return 1; }
          }
          break;
        case 'F':
          filename = a.Substring(3);
          break;
        case 'X':
          System.AppDomain.CurrentDomain.ExecuteAssembly("ilasm");
          break;
        case '?':
          Usage();
          return 0;
      }
    }
  }

  FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None);
  outstream = new StreamWriter(fs);

  Console.Write("Generating IL to " + filename + "...");
  EmitHeader();

  foreach (TestMapEntry test in tests)  
  {
    EmitPrintString("********************************* " + test.description + " *************************\\n");
    foreach (TypeMapEntry type in types)
    {
      EmitPrintString("  on type " + type.ty + ": ");
      test.emitter(type);
    }
  }


  EmitFooter();
  outstream.Close();
  Console.Write("done.\n");
  return 0;
}
Esempio n. 16
0
static void EmitInitObj(TypeMapEntry tme)
{
  string dest = EmitLocal(tme);
  Emit("ldloca " + dest);
  Emit("initobj " + tme.ilty);
  Emit("ldloc " + dest);
  EmitPrint(tme);
}
Esempio n. 17
0
static void EmitCpObj(TypeMapEntry tme)
{
  string src = EmitLocal(tme, "S");
  string dest = EmitLocal(tme, "D");
  Emit(tme.instrs);
  Emit("stloc " + src);
  Emit("ldloca " + dest);
  Emit("ldloca " + src);
  Emit("cpobj " + tme.ilty);
  Emit("ldloc " + dest);
  EmitPrint(tme);
}
Esempio n. 18
0
static void EmitStObj(TypeMapEntry tme)
{
  string varname = EmitLocal(tme);
  Emit("ldloca " + varname);
  Emit(tme.instrs);
  Emit("stobj " + tme.ilty);
  Emit("ldloc " + varname);
  EmitPrint(tme);
}
Esempio n. 19
0
static void EmitUnboxAnyFail(TypeMapEntry tme)
{
  string l1 = GenLabel();
  string l2 = GenLabel();

  EmitOpenBrace(".try");
  Emit("newobj instance void [mscorlib]System.Object::.ctor()");
  Emit("unbox.any " + tme.ilty);
  Emit("pop");
  Emit("leave " + l1);
  EmitCloseBrace();
  EmitOpenBrace("catch [mscorlib]System.InvalidCastException");
  Emit("pop");
  EmitPrintString("downcast failed\\n");
  Emit("leave " + l2);
  EmitCloseBrace();
  Emit(l1 + ":");
  EmitPrintString("downcast succeeded\\n");
  Emit(l2 + ":");
}
Esempio n. 20
0
static void EmitNewObj(TypeMapEntry tme)
{
  Emit(tme.instrs);
  Emit("newobj instance void class W<" + tme.ilty + ">::.ctor(!0)");
  EmitWriteLine();
}
Esempio n. 21
0
static void EmitLdElemAny(TypeMapEntry tme)
{
  Emit("ldc.i4 10 newarr " + tme.ilty);  
  Emit("dup");
  Emit("ldc.i4 0");
  if (tme.isref)
  {  
    Emit(tme.instrs);
    Emit("stelem.ref");
  }
  else
  {
    Emit("ldelema " + tme.ilty);
    Emit(tme.instrs);
    Emit("stobj " + tme.ilty);
  }    

  Emit("ldc.i4 0");
  Emit("ldelem.any " + tme.ilty);
  EmitPrint(tme);
}
 static void EmitNewObj(TypeMapEntry tme)
 {
     Emit(tme.instrs);
     Emit("newobj instance void class W<" + tme.ilty + ">::.ctor(!0)");
     EmitWriteLine();
 }
Esempio n. 23
0
static string EmitLocal(TypeMapEntry tme)
{
  return EmitLocal(tme, "V");
}
Esempio n. 24
0
static void EmitPrint(TypeMapEntry tme)
{
  Emit("box " + tme.ilty);
  EmitWriteLine();
}
Esempio n. 25
0
static void EmitStElemAny(TypeMapEntry tme)
{
  Emit("ldc.i4 10 newarr " + tme.ilty);  
  Emit("dup");
  Emit("ldc.i4 0");
  Emit(tme.instrs);
  Emit("stelem.any " + tme.ilty);
  
  Emit("ldc.i4 0");
  if (tme.isref)
  {  
    Emit("ldelem.ref");
  }
  else
  {
    Emit("ldelem.any " + tme.ilty);
    Emit("box " + tme.ilty);
  }    

  EmitWriteLine();
}
 static string EmitLocal(TypeMapEntry tme)
 {
     return(EmitLocal(tme, "V"));
 }
Esempio n. 27
0
static void EmitBoxAny(TypeMapEntry tme)
{
  Emit(tme.instrs);
  Emit("box " + tme.ilty);
  EmitWriteLine();
}
        public bool Generate(bool skipJniAddNativeMethodRegistrationAttributeScan, List <TypeDefinition> javaTypes, string outputDirectory, bool generateNativeAssembly, out ApplicationConfigTaskState appConfState)
        {
            if (String.IsNullOrEmpty(outputDirectory))
            {
                throw new ArgumentException("must not be null or empty", nameof(outputDirectory));
            }

            if (!Directory.Exists(outputDirectory))
            {
                Directory.CreateDirectory(outputDirectory);
            }

            int assemblyId              = 0;
            int maxJavaNameLength       = 0;
            int maxModuleFileNameLength = 0;
            var knownAssemblies         = new Dictionary <string, int> (StringComparer.Ordinal);
            var tempModules             = new Dictionary <byte[], ModuleData> ();
            Dictionary <AssemblyDefinition, int> moduleCounter = null;
            var mvidCache = new Dictionary <Guid, byte[]> ();

            appConfState = new ApplicationConfigTaskState {
                JniAddNativeMethodRegistrationAttributePresent = skipJniAddNativeMethodRegistrationAttributeScan
            };

            foreach (TypeDefinition td in javaTypes)
            {
                UpdateApplicationConfig(td, appConfState);

                string assemblyName = td.Module.Assembly.FullName;

                if (!knownAssemblies.ContainsKey(assemblyName))
                {
                    assemblyId++;
                    knownAssemblies.Add(assemblyName, assemblyId);
                }

                // We must NOT use Guid here! The reason is that Guid sort order is different than its corresponding
                // byte array representation and on the runtime we need the latter in order to be able to binary search
                // through the module array.
                byte[] moduleUUID;
                if (!mvidCache.TryGetValue(td.Module.Mvid, out moduleUUID))
                {
                    moduleUUID = td.Module.Mvid.ToByteArray();
                    mvidCache.Add(td.Module.Mvid, moduleUUID);
                }

                ModuleData moduleData;
                if (!tempModules.TryGetValue(moduleUUID, out moduleData))
                {
                    if (moduleCounter == null)
                    {
                        moduleCounter = new Dictionary <AssemblyDefinition, int> ();
                    }

                    moduleData = new ModuleData {
                        Mvid           = td.Module.Mvid,
                        MvidBytes      = moduleUUID,
                        Assembly       = td.Module.Assembly,
                        AssemblyName   = td.Module.Assembly.Name.Name,
                        TypesScratch   = new Dictionary <string, TypeMapEntry> (StringComparer.Ordinal),
                        DuplicateTypes = new Dictionary <uint, TypeMapEntry> (),
                    };
                    tempModules.Add(moduleUUID, moduleData);

                    if (!generateNativeAssembly)
                    {
                        int moduleNum;
                        if (!moduleCounter.TryGetValue(moduleData.Assembly, out moduleNum))
                        {
                            moduleNum = 0;
                            moduleCounter [moduleData.Assembly] = 0;
                        }
                        else
                        {
                            moduleNum++;
                            moduleCounter [moduleData.Assembly] = moduleNum;
                        }

                        string fileName = $"{moduleData.Assembly.Name.Name}.{moduleNum}.typemap";
                        moduleData.OutputFilePath = Path.Combine(outputDirectory, fileName);
                        if (maxModuleFileNameLength < fileName.Length)
                        {
                            maxModuleFileNameLength = fileName.Length;
                        }
                    }
                }

                string javaName = Java.Interop.Tools.TypeNameMappings.JavaNativeTypeManager.ToJniName(td);
                var    entry    = new TypeMapEntry {
                    JavaName          = javaName,
                    JavaNameLength    = outputEncoding.GetByteCount(javaName),
                    ManagedTypeName   = td.FullName,
                    Token             = td.MetadataToken.ToUInt32(),
                    AssemblyNameIndex = knownAssemblies [assemblyName]
                };

                if (generateNativeAssembly)
                {
                    if (entry.JavaNameLength > maxJavaNameLength)
                    {
                        maxJavaNameLength = entry.JavaNameLength;
                    }
                }

                if (moduleData.TypesScratch.ContainsKey(entry.JavaName))
                {
                    // This is disabled because it costs a lot of time (around 150ms per standard XF Integration app
                    // build) and has no value for the end user. The message is left here because it may be useful to us
                    // in our devloop at some point.
                    //logger ($"Warning: duplicate Java type name '{entry.JavaName}' in assembly '{moduleData.AssemblyName}' (new token: {entry.Token}).");
                    moduleData.DuplicateTypes.Add(entry.Token, entry);
                }
                else
                {
                    moduleData.TypesScratch.Add(entry.JavaName, entry);
                }
            }

            var modules = tempModules.Values.ToArray();

            Array.Sort(modules, new ModuleUUIDArrayComparer());

            var typeMapEntryComparer = new TypeMapEntryArrayComparer();

            foreach (ModuleData module in modules)
            {
                if (module.TypesScratch.Count == 0)
                {
                    module.Types = new TypeMapEntry[0];
                    continue;
                }

                module.Types = module.TypesScratch.Values.ToArray();
                Array.Sort(module.Types, typeMapEntryComparer);
            }

            NativeTypeMappingData data;

            if (!generateNativeAssembly)
            {
                string typeMapIndexPath = Path.Combine(outputDirectory, "typemap.index");
                using (var indexWriter = MemoryStreamPool.Shared.CreateBinaryWriter()) {
                    OutputModules(modules, indexWriter, maxModuleFileNameLength + 1);
                    indexWriter.Flush();
                    MonoAndroidHelper.CopyIfStreamChanged(indexWriter.BaseStream, typeMapIndexPath);
                }
                GeneratedBinaryTypeMaps.Add(typeMapIndexPath);

                data = new NativeTypeMappingData(logger, new ModuleData[0], 0);
            }
            else
            {
                data = new NativeTypeMappingData(logger, modules, maxJavaNameLength + 1);
            }

            NativeAssemblerTargetProvider asmTargetProvider;
            bool sharedBitsWritten = false;
            bool sharedIncludeUsesAbiPrefix;

            foreach (string abi in supportedAbis)
            {
                sharedIncludeUsesAbiPrefix = false;
                switch (abi.Trim())
                {
                case "armeabi-v7a":
                    asmTargetProvider          = new ARMNativeAssemblerTargetProvider(is64Bit: false);
                    sharedIncludeUsesAbiPrefix = true;                             // ARMv7a is "special", it uses different directive prefix
                    // than the others and the "shared" code won't build for it
                    break;

                case "arm64-v8a":
                    asmTargetProvider = new ARMNativeAssemblerTargetProvider(is64Bit: true);
                    break;

                case "x86":
                    asmTargetProvider = new X86NativeAssemblerTargetProvider(is64Bit: false);
                    break;

                case "x86_64":
                    asmTargetProvider = new X86NativeAssemblerTargetProvider(is64Bit: true);
                    break;

                default:
                    throw new InvalidOperationException($"Unknown ABI {abi}");
                }

                var generator = new TypeMappingNativeAssemblyGenerator(asmTargetProvider, data, Path.Combine(outputDirectory, "typemaps"), sharedBitsWritten, sharedIncludeUsesAbiPrefix);

                using (var sw = MemoryStreamPool.Shared.CreateStreamWriter(outputEncoding)) {
                    generator.Write(sw);
                    sw.Flush();
                    MonoAndroidHelper.CopyIfStreamChanged(sw.BaseStream, generator.MainSourceFile);
                    if (!sharedIncludeUsesAbiPrefix)
                    {
                        sharedBitsWritten = true;
                    }
                }
            }
            return(true);
        }
Esempio n. 29
0
static string EmitLocal(TypeMapEntry tme, string prefix)
{
  string varname = "'" + prefix + "_" + tme.ty + "'";
  Emit(".locals(" + tme.ilty + " " + varname + ")");
  return varname;
}