void UpdateWhenChanged(string path, string type, MemoryStream ms, Action <Stream> generator) { if (InstantRunEnabled) { ms.SetLength(0); generator(ms); MonoAndroidHelper.CopyIfStreamChanged(ms, path); } string dataFilePath = $"{path}.inc"; using (var stream = new NativeAssemblyDataStream()) { generator(stream); stream.EndOfFile(); MonoAndroidHelper.CopyIfStreamChanged(stream, dataFilePath); var generatedFiles = new List <ITaskItem> (); string mappingFieldName = $"{type}_typemap"; string dataFileName = Path.GetFileName(dataFilePath); NativeAssemblerTargetProvider asmTargetProvider; var utf8Encoding = new UTF8Encoding(false); foreach (string abi in SupportedAbis) { ms.SetLength(0); switch (abi.Trim()) { case "armeabi-v7a": asmTargetProvider = new ARMNativeAssemblerTargetProvider(is64Bit: false); 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 asmgen = new TypeMappingNativeAssemblyGenerator(asmTargetProvider, stream, dataFileName, stream.MapByteCount, mappingFieldName); string asmFileName = $"{path}.{abi.Trim ()}.s"; using (var sw = new StreamWriter(ms, utf8Encoding, bufferSize: 8192, leaveOpen: true)) { asmgen.Write(sw, dataFileName); MonoAndroidHelper.CopyIfStreamChanged(ms, asmFileName); } } } }
void WriteMappingHeader(StreamWriter output, NativeAssemblyDataStream dataStream, string mappingFieldName) { output.WriteLine(); WriteCommentLine(output, "Mapping header"); WriteSection(output, $".data.{mappingFieldName}", hasStrings: false, writable: true); WriteSymbol(output, $"{mappingFieldName}_header", alignBits: 2, fieldAlignBytes: 4, isGlobal: true, alwaysWriteSize: true, structureWriter: () => { WriteCommentLine(output, "version"); WriteData(output, dataStream.MapVersion); WriteCommentLine(output, "entry-count"); WriteData(output, dataStream.MapEntryCount); WriteCommentLine(output, "entry-length"); WriteData(output, dataStream.MapEntryLength); WriteCommentLine(output, "value-offset"); WriteData(output, dataStream.MapValueOffset); return(16); }); output.WriteLine(); }
public TypeMappingNativeAssemblyGenerator(NativeAssemblerTargetProvider targetProvider, NativeAssemblyDataStream dataStream, string dataFileName, uint dataSize, string mappingFieldName) : base(targetProvider) { if (dataStream == null) { throw new ArgumentNullException(nameof(dataStream)); } if (String.IsNullOrEmpty(dataFileName)) { throw new ArgumentException("must not be null or empty", nameof(dataFileName)); } if (String.IsNullOrEmpty(mappingFieldName)) { throw new ArgumentException("must not be null or empty", nameof(mappingFieldName)); } this.dataStream = dataStream; this.dataFileName = dataFileName; this.dataSize = dataSize; this.mappingFieldName = mappingFieldName; }