From 8b3e9a84e7db2fa4a5f5ee5dffadc118bb823a16 Mon Sep 17 00:00:00 2001 From: Nate Biggs Date: Thu, 21 Jul 2022 03:59:25 +0000 Subject: [PATCH] Add test for unordered indexing in serialization. This test catches an issue previously uncaught by tests where offsets for indices were written incorrectly and could therefore lead to errors when deserializingelements in deferred mode. Change-Id: I14bf80bbe4fa47c12e543679803c7be38582a0e5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252300 Commit-Queue: Nate Biggs Reviewed-by: Sigmund Cherem --- .../serialization/data/unordered_indices.dart | 19 ++++++++ .../serialization/serialization_test.dart | 4 +- .../serialization_test_helper.dart | 47 ++++++++++++++++--- 3 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 pkg/compiler/test/serialization/data/unordered_indices.dart diff --git a/pkg/compiler/test/serialization/data/unordered_indices.dart b/pkg/compiler/test/serialization/data/unordered_indices.dart new file mode 100644 index 00000000000..09c3234066c --- /dev/null +++ b/pkg/compiler/test/serialization/data/unordered_indices.dart @@ -0,0 +1,19 @@ +// @dart=2.7 +// @doCodegen + +// Introduce a named parameter with a given string name. +typedef Bar = String Function({String someString}); + +class Foo { + Bar _bar; + Foo(this._bar); +} + +void main() { + // Create a String constant that matches the name of the above named param. + print("someString"); + + // Include an expression whose static type involves the named param above. But + // importantly do not create an instance of the type. + final x = Foo(null)._bar; +} diff --git a/pkg/compiler/test/serialization/serialization_test.dart b/pkg/compiler/test/serialization/serialization_test.dart index 3b052f52e17..3ce55129dd3 100644 --- a/pkg/compiler/test/serialization/serialization_test.dart +++ b/pkg/compiler/test/serialization/serialization_test.dart @@ -64,6 +64,7 @@ Future checkTests(Directory dataDir, Uri.parse('memory:$commonTestPath/dart2js_native/main.dart'); String mainCode = await new File.fromUri(entity.uri).readAsString(); Map memorySourceFiles = {entryPoint.path: mainCode}; + final doCodegen = mainCode.contains('@doCodegen'); if (libDirectory != null) { print('Supporting libraries:'); @@ -84,7 +85,8 @@ Future checkTests(Directory dataDir, entryPoint: entryPoint, memorySourceFiles: memorySourceFiles, options: testOptions, - strategy: strategy); + strategy: strategy, + doCodegen: doCodegen); } Expect.isFalse(hasFailures, 'Errors found.'); Expect.isTrue(testCount > 0, "No files were tested."); diff --git a/pkg/compiler/test/serialization/serialization_test_helper.dart b/pkg/compiler/test/serialization/serialization_test_helper.dart index aa3474c2e63..ace4373ab19 100644 --- a/pkg/compiler/test/serialization/serialization_test_helper.dart +++ b/pkg/compiler/test/serialization/serialization_test_helper.dart @@ -107,7 +107,8 @@ runTest( Uri librariesSpecificationUri, List options, SerializationStrategy strategy: const BytesInMemorySerializationStrategy(), - bool useDataKinds: false}) async { + bool useDataKinds: false, + bool doCodegen: false}) async { var commonOptions = options + ['--out=out.js']; OutputCollector collector = new OutputCollector(); CompilationResult result = await runCompiler( @@ -157,10 +158,11 @@ runTest( Directory dir = await Directory.systemTemp.createTemp('serialization_test_helper'); - var dillFileUri = dir.uri.resolve('out.dill'); - var closedWorldFileUri = dir.uri.resolve('world.data'); - var dillBytes = collector3a.binaryOutputMap[dillUri].list; - var closedWorldBytes = collector3a.binaryOutputMap[closedWorldUri].list; + final dillFileUri = dir.uri.resolve('out.dill'); + final closedWorldFileUri = dir.uri.resolve('world.data'); + final globalDataUri = Uri.parse('global.data'); + final dillBytes = collector3a.binaryOutputMap[dillUri].list; + final closedWorldBytes = collector3a.binaryOutputMap[closedWorldUri].list; File(dillFileUri.path).writeAsBytesSync(dillBytes); File(closedWorldFileUri.path).writeAsBytesSync(closedWorldBytes); OutputCollector collector3b = new OutputCollector(); @@ -173,7 +175,7 @@ runTest( [ '${Flags.inputDill}=$dillFileUri', '${Flags.readClosedWorld}=$closedWorldFileUri', - '${Flags.writeData}=global.data' + '${Flags.writeData}=$globalDataUri' ], outputProvider: collector3b, beforeRun: (Compiler compiler) { @@ -182,12 +184,45 @@ runTest( }); Expect.isTrue(result3b.isSuccess); + final globalDataFileUri = dir.uri.resolve('global.data'); + + // We must write the global data bytes before calling + // `finishCompileAndCompare` below as that clears the collector. + if (doCodegen) { + Expect.isTrue(collector3b.binaryOutputMap.containsKey(globalDataUri)); + + final globalDataBytes = collector3b.binaryOutputMap[globalDataUri].list; + File(globalDataFileUri.path).writeAsBytesSync(globalDataBytes); + } + await finishCompileAndCompare( expectedOutput, collector2, result2.compiler, strategy, stoppedAfterClosedWorld: true); await finishCompileAndCompare( expectedOutput, collector3b, result3b.compiler, strategy, stoppedAfterTypeInference: true); + + if (doCodegen) { + OutputCollector collector4 = new OutputCollector(); + CompilationResult result4 = await runCompiler( + entryPoint: entryPoint, + memorySourceFiles: memorySourceFiles, + packageConfig: packageConfig, + librariesSpecificationUri: librariesSpecificationUri, + options: commonOptions + + [ + '${Flags.inputDill}=$dillFileUri', + '${Flags.readClosedWorld}=$closedWorldFileUri', + '${Flags.readData}=$globalDataFileUri', + '--out=out.js' + ], + outputProvider: collector4, + beforeRun: (Compiler compiler) { + compiler.forceSerializationForTesting = true; + }); + Expect.isTrue(result4.isSuccess); + } + await dir.delete(recursive: true); }