Share non-generic signatures through init.types
Change-Id: Ie132bbe805780022c91e5578c8dc4636c3c4cc8b
Reviewed-on: https://dart-review.googlesource.com/56671
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 1c4eac2..884aadb 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -1118,6 +1118,9 @@
FunctionEntity get instantiatedGenericFunctionType =>
_findHelperFunction('instantiatedGenericFunctionType');
+ FunctionEntity get extractFunctionTypeObjectFromInternal =>
+ _findHelperFunction('extractFunctionTypeObjectFromInternal');
+
// From dart:_internal
ClassEntity _symbolImplementationClass;
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 71bec0c..90bc21f 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -774,6 +774,7 @@
_commonElements.instantiate2,
_commonElements.instantiate3,
_commonElements.instantiatedGenericFunctionType,
+ _commonElements.extractFunctionTypeObjectFromInternal,
], instantiatedClasses: [
_commonElements.instantiation1Class,
_commonElements.instantiation2Class,
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 461bd279..bb430e2 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -155,6 +155,7 @@
_customElementsAnalysis.registerTypeConstant(representedType.element);
}
} else if (constant is InstantiationConstantValue) {
+ // TODO(johnniwinther): Register these using `BackendImpact`.
impactBuilder.registerTypeUse(new TypeUse.instantiation(
_elementEnvironment
.getThisType(_commonElements.instantiation1Class)));
@@ -167,6 +168,9 @@
impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
_commonElements.instantiatedGenericFunctionType,
CallStructure.TWO_ARGS));
+ impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
+ _commonElements.extractFunctionTypeObjectFromInternal,
+ CallStructure.ONE_ARG));
}
}
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 2364c42..1281eb9 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -1571,6 +1571,26 @@
typeVariableTestsForTesting = typeVariableTests;
}
+ /*print(typeVariableTests.dump());
+ print('------------------------------------------------------------------');
+ print('classesNeedingTypeArguments:');
+ classesNeedingTypeArguments.forEach((e) => print(' $e'));
+ print('------------------------------------------------------------------');
+ print('methodsNeedingSignature:');
+ methodsNeedingSignature.forEach((e) => print(' $e'));
+ print('------------------------------------------------------------------');
+ print('methodsNeedingTypeArguments:');
+ methodsNeedingTypeArguments.forEach((e) => print(' $e'));
+ print('------------------------------------------------------------------');
+ print('localFunctionsNeedingSignature:');
+ localFunctionsNeedingSignature.forEach((e) => print(' $e'));
+ print('------------------------------------------------------------------');
+ print('localFunctionsNeedingTypeArguments:');
+ localFunctionsNeedingTypeArguments.forEach((e) => print(' $e'));
+ print('------------------------------------------------------------------');
+ print('selectorsNeedingTypeArguments:');
+ selectorsNeedingTypeArguments.forEach((e) => print(' $e'));*/
+
return _createRuntimeTypesNeed(
_elementEnvironment,
closedWorld.backendUsage,
diff --git a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
index 865fc15..477ced0 100644
--- a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
@@ -104,18 +104,19 @@
/// ```
/// $signature:: function() {
/// return H.instantiatedGenericFunctionType(
- /// this._genericClosure.$signature(),
+ /// H.extractFunctionTypeObjectFromInternal(this._genericClosure),
/// this.$ti);
/// }
/// ```
ParameterStubMethod _generateSignatureStub(FieldEntity functionField) {
jsAst.Name operatorSignature = _namer.asName(_namer.operatorSignature);
- jsAst.Fun function = js('function() { return #(this.#.#(), this.#); }', [
+ jsAst.Fun function = js('function() { return #(#(this.#), this.#); }', [
_emitter.staticFunctionAccess(
_commonElements.instantiatedGenericFunctionType),
+ _emitter.staticFunctionAccess(
+ _commonElements.extractFunctionTypeObjectFromInternal),
_namer.fieldPropertyName(functionField),
- operatorSignature,
_namer.rtiFieldJsName,
]);
// TODO(sra): Generate source information for stub that has no member.
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index 3615c8c..e76a39d 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -101,6 +101,7 @@
final RuntimeTypesEncoder _rtiEncoder;
final JsInteropAnalysis _jsInteropAnalysis;
final bool _strongMode;
+ final _TypeContainedInOutputUnitVisitor _outputUnitVisitor;
RuntimeTypeGenerator(
this._commonElements,
@@ -111,7 +112,9 @@
this._rtiChecks,
this._rtiEncoder,
this._jsInteropAnalysis,
- this._strongMode);
+ this._strongMode)
+ : _outputUnitVisitor = new _TypeContainedInOutputUnitVisitor(
+ _commonElements, _outputUnitData);
/**
* Generate "is tests" for [cls] itself, and the "is tests" for the
@@ -145,19 +148,28 @@
// signatures. We either need them for mirrors or because [type] is
// potentially a subtype of a checked function. Currently we eagerly
// generate a function type index or signature for all callable classes.
- if (storeFunctionTypeInMetadata && !type.containsTypeVariables) {
- // TODO(johnniwinther,efortuna): Should we use the scheme for Dart 2?
- // TODO(sigmund): use output unit of `method` (Issue #31032)
- OutputUnit outputUnit = _outputUnitData.mainOutputUnit;
- result.functionTypeIndex =
- emitterTask.metadataCollector.reifyType(type, outputUnit);
+ jsAst.Expression functionTypeIndex;
+ if (!type.containsTypeVariables) {
+ // TODO(sigmund): use output unit of [method] when the classes mentioned
+ // in [type] aren't in the main output unit. (Issue #31032)
+ OutputUnit mainOutputUnit = _outputUnitData.mainOutputUnit;
+ if (_outputUnitVisitor.isTypeContainedIn(type, mainOutputUnit)) {
+ functionTypeIndex =
+ emitterTask.metadataCollector.reifyType(type, mainOutputUnit);
+ }
+ }
+ if (storeFunctionTypeInMetadata && functionTypeIndex != null) {
+ result.functionTypeIndex = functionTypeIndex;
} else {
jsAst.Expression encoding =
generatedCode[classFunctionType.signatureFunction];
- if (classFunctionType.signatureFunction != null) {
- // Use precomputed signature function if live.
- } else {
- assert(!_strongMode);
+ if (_strongMode) {
+ if (classFunctionType.signatureFunction == null) {
+ // The signature function isn't live.
+ return;
+ }
+ encoding = functionTypeIndex ?? encoding;
+ } else if (encoding == null) {
// Generate the signature on the fly. This is only supported for
// Dart 1.
@@ -240,3 +252,84 @@
}
}
}
+
+/// Visitor that checks whether a type is contained within one output unit.
+class _TypeContainedInOutputUnitVisitor
+ implements DartTypeVisitor<bool, OutputUnit> {
+ final CommonElements _commonElements;
+ final OutputUnitData _outputUnitData;
+
+ _TypeContainedInOutputUnitVisitor(this._commonElements, this._outputUnitData);
+
+ /// Returns `true` if all classes mentioned in [type] are in [outputUnit].
+ bool isTypeContainedIn(DartType type, OutputUnit outputUnit) =>
+ visit(type, outputUnit);
+
+ @override
+ bool visit(DartType type, OutputUnit argument) => type.accept(this, argument);
+
+ bool visitList(List<DartType> types, OutputUnit argument) {
+ for (DartType type in types) {
+ if (!visit(type, argument)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @override
+ bool visitFutureOrType(FutureOrType type, OutputUnit argument) {
+ if (_outputUnitData.outputUnitForClass(_commonElements.functionClass) !=
+ argument) {
+ return false;
+ }
+ return visit(type.typeArgument, argument);
+ }
+
+ @override
+ bool visitDynamicType(DynamicType type, OutputUnit argument) => true;
+
+ @override
+ bool visitTypedefType(TypedefType type, OutputUnit argument) {
+ return visit(type.unaliased, argument);
+ }
+
+ @override
+ bool visitInterfaceType(InterfaceType type, OutputUnit argument) {
+ if (_outputUnitData.outputUnitForClass(type.element) != argument) {
+ return false;
+ }
+ return visitList(type.typeArguments, argument);
+ }
+
+ @override
+ bool visitFunctionType(FunctionType type, OutputUnit argument) {
+ bool result = visit(type.returnType, argument) &&
+ visitList(type.parameterTypes, argument) &&
+ visitList(type.optionalParameterTypes, argument) &&
+ visitList(type.namedParameterTypes, argument);
+ if (!result) return false;
+ for (FunctionTypeVariable typeVariable in type.typeVariables) {
+ if (!visit(typeVariable.bound, argument)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @override
+ bool visitFunctionTypeVariable(
+ FunctionTypeVariable type, OutputUnit argument) {
+ return true;
+ }
+
+ @override
+ bool visitTypeVariableType(TypeVariableType type, OutputUnit argument) {
+ return false;
+ }
+
+ @override
+ bool visitVoidType(VoidType type, OutputUnit argument) {
+ return true;
+ }
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index af67c0e..4896e9d 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -3447,10 +3447,20 @@
extractFunctionTypeObjectFrom(o) {
var interceptor = getInterceptor(o);
+ return extractFunctionTypeObjectFromInternal(interceptor);
+}
+
+extractFunctionTypeObjectFromInternal(o) {
var signatureName = JS_GET_NAME(JsGetName.SIGNATURE_NAME);
- return JS('bool', '# in #', signatureName, interceptor)
- ? JS('', '#[#]()', interceptor, signatureName)
- : null;
+ if (JS('bool', '# in #', signatureName, o)) {
+ var signature = JS('', '#[#]', o, signatureName);
+ if (JS('bool', 'typeof # == "number"', signature)) {
+ return getType(signature);
+ } else {
+ return JS('', '#[#]()', o, signatureName);
+ }
+ }
+ return null;
}
functionTypeTest(value, functionTypeRti) {
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
index d6be639..09f2df3 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -859,10 +859,8 @@
if (isDartFunctionType(t)) {
// Functions are treated specially and have their type information stored
// directly in the instance.
- var targetSignatureFunction =
- getField(o, '${JS_GET_NAME(JsGetName.SIGNATURE_NAME)}');
- if (targetSignatureFunction == null) return false;
- type = invokeOn(targetSignatureFunction, o, null);
+ type = extractFunctionTypeObjectFromInternal(o);
+ if (type == null) return false;
return isFunctionSubtype(type, t);
}
return isSubtype(type, t);
diff --git a/tests/compiler/dart2js_extra/deferred_function_types1_test.dart b/tests/compiler/dart2js_extra/deferred_function_types1_test.dart
new file mode 100644
index 0000000..91c9075
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types1_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+ await lib1.loadLibrary();
+ Expect.isTrue(lib1.method1() is int Function(int));
+ Expect.isFalse(lib1.method1() is String Function(String));
+ await lib2.loadLibrary();
+ Expect.isFalse(lib2.method2() is int Function(int));
+ Expect.isTrue(lib2.method2() is String Function(String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types2_test.dart b/tests/compiler/dart2js_extra/deferred_function_types2_test.dart
new file mode 100644
index 0000000..4336421
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types2_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+ await lib2.loadLibrary();
+ Expect.isFalse(lib2.method2() is int Function(int));
+ Expect.isTrue(lib2.method2() is String Function(String));
+ await lib1.loadLibrary();
+ Expect.isTrue(lib1.method1() is int Function(int));
+ Expect.isFalse(lib1.method1() is String Function(String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types3_test.dart b/tests/compiler/dart2js_extra/deferred_function_types3_test.dart
new file mode 100644
index 0000000..98a6de8
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types3_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+ await lib1.loadLibrary();
+ Expect.isTrue(lib1.method3() is Object Function(Null));
+ Expect.isFalse(lib1.method3() is Object Function(Null, Null));
+ await lib2.loadLibrary();
+ Expect.isFalse(lib2.method4() is Object Function(Null));
+ Expect.isTrue(lib2.method4() is Object Function(Null, Null));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types4_test.dart b/tests/compiler/dart2js_extra/deferred_function_types4_test.dart
new file mode 100644
index 0000000..fc78d96
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types4_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+ await lib2.loadLibrary();
+ Expect.isFalse(lib2.method4() is Object Function(Null));
+ Expect.isTrue(lib2.method4() is Object Function(Null, Null));
+ await lib1.loadLibrary();
+ Expect.isTrue(lib1.method3() is Object Function(Null));
+ Expect.isFalse(lib1.method3() is Object Function(Null, Null));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types5_test.dart b/tests/compiler/dart2js_extra/deferred_function_types5_test.dart
new file mode 100644
index 0000000..998d678
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types5_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+ await lib1.loadLibrary();
+ Expect.isTrue(lib1.test3(lib1.method3()));
+ Expect.isFalse(lib1.method3() is Object Function(String));
+ await lib2.loadLibrary();
+ Expect.isFalse(lib2.method4() is Object Function(String, String));
+ Expect.isTrue(lib2.test4(lib2.method4()));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types6_test.dart b/tests/compiler/dart2js_extra/deferred_function_types6_test.dart
new file mode 100644
index 0000000..2423b52
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types6_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+ await lib2.loadLibrary();
+ Expect.isFalse(lib2.method4() is Object Function(String, String));
+ Expect.isTrue(lib2.test4(lib2.method4()));
+ await lib1.loadLibrary();
+ Expect.isTrue(lib1.test3(lib1.method3()));
+ Expect.isFalse(lib1.method3() is Object Function(String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types7_test.dart b/tests/compiler/dart2js_extra/deferred_function_types7_test.dart
new file mode 100644
index 0000000..c3e8de0
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types7_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+ await lib1.loadLibrary();
+ Expect.isTrue(lib1.method1() is int Function(int));
+ Expect.isFalse(lib1.method1() is String Function(String));
+ Expect.isTrue(lib1.method5 is Object Function(Null, String, int));
+ Expect.isFalse(lib1.method5 is Object Function(Null, int, String));
+ await lib2.loadLibrary();
+ Expect.isFalse(lib2.method2() is int Function(int));
+ Expect.isTrue(lib2.method2() is String Function(String));
+ Expect.isFalse(lib2.method6 is Object Function(Null, String, int));
+ Expect.isTrue(lib2.method6 is Object Function(Null, int, String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types8_test.dart b/tests/compiler/dart2js_extra/deferred_function_types8_test.dart
new file mode 100644
index 0000000..eaa89ca
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types8_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+ await lib2.loadLibrary();
+ Expect.isFalse(lib2.method2() is int Function(int));
+ Expect.isTrue(lib2.method2() is String Function(String));
+ Expect.isFalse(lib2.method6 is Object Function(Null, String, int));
+ Expect.isTrue(lib2.method6 is Object Function(Null, int, String));
+ await lib1.loadLibrary();
+ Expect.isTrue(lib1.method1() is int Function(int));
+ Expect.isFalse(lib1.method1() is String Function(String));
+ Expect.isTrue(lib1.method5 is Object Function(Null, String, int));
+ Expect.isFalse(lib1.method5 is Object Function(Null, int, String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types_lib1.dart b/tests/compiler/dart2js_extra/deferred_function_types_lib1.dart
new file mode 100644
index 0000000..4bacb61
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types_lib1.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+method1() {
+ return (int i) => i;
+}
+
+class Class1 {}
+
+method3() {
+ return (Class1 c) => c;
+}
+
+test3(o) => o is Class1 Function(Class1);
+
+method5(Class1 c, String s, int i) {}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types_lib2.dart b/tests/compiler/dart2js_extra/deferred_function_types_lib2.dart
new file mode 100644
index 0000000..a8abb54
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types_lib2.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+method2() {
+ return (String s) => s;
+}
+
+class Class2 {}
+
+method4() {
+ return (Class2 c1, Class2 c2) => c1;
+}
+
+test4(o) => o is Class2 Function(Class2, Class2);
+
+method6(Class2 c, int i, String s) {}
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 740c6c6..71ce2bf 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -196,10 +196,6 @@
map_test: Crash # tests/corelib_2/map_test.dart:903:7: Internal problem: Unhandled Null in installDefaultConstructor.
symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
-[ $compiler == dart2js && $fast_startup ]
-apply3_test: RuntimeError
-dynamic_nosuchmethod_test: RuntimeError
-
[ $compiler == dart2js && $fast_startup && $fasta && $strong ]
cast_test: RuntimeError
error_stack_trace1_test: RuntimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 953e7a2..830d006 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -486,7 +486,6 @@
stacktrace_rethrow_error_test/withtraceparameter: RuntimeError # Issue 12698
stacktrace_rethrow_nonerror_test: RuntimeError # Issue 12698
stacktrace_test: RuntimeError # Issue 12698
-super_call4_test: Crash # NoSuchMethodError: The getter 'thisLocal' was called on null.
switch_bad_case_test/01: MissingCompileTimeError
switch_bad_case_test/02: MissingCompileTimeError
switch_case_test/00: MissingCompileTimeError
@@ -808,7 +807,6 @@
string_split_test: CompileTimeError
string_supertype_checked_test: CompileTimeError
super_bound_closure_test/none: CompileTimeError
-super_call4_test: Crash # NoSuchMethodError: The getter 'thisLocal' was called on null.
super_no_such_method1_test: CompileTimeError
super_no_such_method2_test: CompileTimeError
super_no_such_method3_test: CompileTimeError