Skip to content

Commit 8af17ed

Browse files
fishythefishcommit-bot@chromium.org
authored andcommitted
[dart2js] Collect named type variables from recipe generator.
Change-Id: Ie056f605f710f7942973c1a8cd219d94c28e74b0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112480 Commit-Queue: Mayank Patke <[email protected]> Reviewed-by: Stephen Adams <[email protected]>
1 parent ffefa12 commit 8af17ed

File tree

14 files changed

+131
-36
lines changed

14 files changed

+131
-36
lines changed

pkg/compiler/lib/src/deferred_load.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ abstract class DeferredLoadTask extends CompilerTask {
356356
break;
357357
case TypeUseKind.RTI_VALUE:
358358
case TypeUseKind.TYPE_ARGUMENT:
359+
case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
359360
failedAt(element, "Unexpected type use: $typeUse.");
360361
break;
361362
}

pkg/compiler/lib/src/enqueue.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,21 @@ class ResolutionEnqueuer extends EnqueuerImpl {
422422
case TypeUseKind.TYPE_ARGUMENT:
423423
failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
424424
break;
425+
case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
426+
assert(type is TypeVariableType);
427+
_registerNamedTypeVariableNewRti(type);
428+
break;
425429
}
426430
}
427431

428432
void _registerIsCheck(DartType type) {
429433
_worldBuilder.registerIsCheck(type);
430434
}
431435

436+
void _registerNamedTypeVariableNewRti(TypeVariableType type) {
437+
_worldBuilder.registerNamedTypeVariableNewRti(type);
438+
}
439+
432440
void _registerClosurizedMember(MemberEntity element) {
433441
assert(element.isInstanceMember);
434442
applyImpact(listener.registerClosurizedMember(element),

pkg/compiler/lib/src/js_backend/enqueuer.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ class CodegenEnqueuer extends EnqueuerImpl {
226226
break;
227227
case TypeUseKind.CONST_INSTANTIATION:
228228
failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
229+
break;
230+
case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
231+
assert(type is TypeVariableType);
232+
_registerNamedTypeVariableNewRti(type);
229233
}
230234
}
231235

@@ -243,6 +247,10 @@ class CodegenEnqueuer extends EnqueuerImpl {
243247
_worldBuilder.registerIsCheck(type);
244248
}
245249

250+
void _registerNamedTypeVariableNewRti(TypeVariableType type) {
251+
_worldBuilder.registerNamedTypeVariableNewRti(type);
252+
}
253+
246254
void _registerClosurizedMember(FunctionEntity element) {
247255
assert(element.isInstanceMember);
248256
applyImpact(listener.registerClosurizedMember(element));

pkg/compiler/lib/src/js_backend/impact_transformer.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
204204
break;
205205
case TypeUseKind.RTI_VALUE:
206206
case TypeUseKind.TYPE_ARGUMENT:
207+
case TypeUseKind.NAMED_TYPE_VARIABLE_NEW_RTI:
207208
failedAt(CURRENT_ELEMENT_SPANNABLE, "Unexpected type use: $typeUse.");
208209
break;
209210
}

pkg/compiler/lib/src/js_backend/runtime_types_new.dart

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,17 @@ import 'native_data.dart';
2121
import 'runtime_types_codegen.dart' show RuntimeTypesSubstitutions;
2222
import 'runtime_types_resolution.dart' show RuntimeTypesNeed;
2323

24+
class RecipeEncoding {
25+
final jsAst.Literal recipe;
26+
final Set<TypeVariableType> typeVariables;
27+
28+
const RecipeEncoding(this.recipe, this.typeVariables);
29+
}
30+
2431
abstract class RecipeEncoder {
25-
/// Returns a [jsAst.Literal] representing the given [recipe] to be
32+
/// Returns a [RecipeEncoding] representing the given [recipe] to be
2633
/// evaluated against a type environment with shape [structure].
27-
jsAst.Literal encodeRecipe(ModularEmitter emitter,
34+
RecipeEncoding encodeRecipe(ModularEmitter emitter,
2835
TypeEnvironmentStructure environmentStructure, TypeRecipe recipe);
2936

3037
jsAst.Literal encodeGroundRecipe(ModularEmitter emitter, TypeRecipe recipe);
@@ -67,22 +74,23 @@ class RecipeEncoderImpl implements RecipeEncoder {
6774
this._elementEnvironment, this.commonElements, this._rtiNeed);
6875

6976
@override
70-
jsAst.Literal encodeRecipe(ModularEmitter emitter,
77+
RecipeEncoding encodeRecipe(ModularEmitter emitter,
7178
TypeEnvironmentStructure environmentStructure, TypeRecipe recipe) {
7279
return _RecipeGenerator(this, emitter, environmentStructure, recipe).run();
7380
}
7481

7582
@override
7683
jsAst.Literal encodeGroundRecipe(ModularEmitter emitter, TypeRecipe recipe) {
77-
return _RecipeGenerator(this, emitter, null, recipe).run();
84+
return _RecipeGenerator(this, emitter, null, recipe).run().recipe;
7885
}
7986

8087
@override
8188
jsAst.Literal encodeRecipeWithVariablesReplaceByAny(
8289
ModularEmitter emitter, DartType dartType) {
8390
return _RecipeGenerator(this, emitter, null, TypeExpressionRecipe(dartType),
8491
hackTypeVariablesToAny: true)
85-
.run();
92+
.run()
93+
.recipe;
8694
}
8795

8896
@override
@@ -94,7 +102,8 @@ class RecipeEncoderImpl implements RecipeEncoder {
94102
FullTypeEnvironmentStructure(classType: declaringType),
95103
TypeExpressionRecipe(supertypeArgument),
96104
indexTypeVariablesOnDeclaringClass: true)
97-
.run();
105+
.run()
106+
.recipe;
98107
}
99108

100109
@override
@@ -125,6 +134,7 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
125134
final bool hackTypeVariablesToAny;
126135

127136
final List<FunctionTypeVariable> functionTypeVariables = [];
137+
final Set<TypeVariableType> typeVariables = {};
128138

129139
// Accumulated recipe.
130140
final List<jsAst.Literal> _fragments = [];
@@ -139,15 +149,19 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
139149
NativeBasicData get _nativeData => _encoder._nativeData;
140150
RuntimeTypesSubstitutions get _rtiSubstitutions => _encoder._rtiSubstitutions;
141151

142-
jsAst.Literal run() {
152+
RecipeEncoding _finishEncoding(jsAst.Literal literal) =>
153+
RecipeEncoding(literal, typeVariables);
154+
155+
RecipeEncoding run() {
143156
_start(_recipe);
144157
assert(functionTypeVariables.isEmpty);
145158
if (_fragments.isEmpty) {
146-
return js.string(String.fromCharCodes(_codes));
159+
return _finishEncoding(js.string(String.fromCharCodes(_codes)));
147160
}
148161
_flushCodes();
149162
jsAst.LiteralString quote = jsAst.LiteralString('"');
150-
return jsAst.StringConcatenation([quote, ..._fragments, quote]);
163+
return _finishEncoding(
164+
jsAst.StringConcatenation([quote, ..._fragments, quote]));
151165
}
152166

153167
void _start(TypeRecipe recipe) {
@@ -261,6 +275,7 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
261275
}
262276
jsAst.Name name = _emitter.typeVariableAccessNewRti(type.element);
263277
_emitName(name);
278+
typeVariables.add(type);
264279
return;
265280
}
266281
// TODO(sra): Handle missing cases. This just emits some readable junk. The
@@ -449,9 +464,10 @@ class _RecipeGenerator implements DartTypeVisitor<void, void> {
449464
class _RulesetEntry {
450465
final InterfaceType _targetType;
451466
List<InterfaceType> _supertypes;
452-
Map<TypeVariableType, DartType> _typeVariables = {};
467+
Map<TypeVariableType, DartType> _typeVariables;
453468

454-
_RulesetEntry(this._targetType, Iterable<InterfaceType> supertypes)
469+
_RulesetEntry(
470+
this._targetType, Iterable<InterfaceType> supertypes, this._typeVariables)
455471
: _supertypes = supertypes.toList();
456472

457473
bool get isEmpty => _supertypes.isEmpty && _typeVariables.isEmpty;
@@ -463,8 +479,9 @@ class Ruleset {
463479
Ruleset(this._entries);
464480
Ruleset.empty() : this([]);
465481

466-
void add(InterfaceType targetType, Iterable<InterfaceType> supertypes) =>
467-
_entries.add(_RulesetEntry(targetType, supertypes));
482+
void add(InterfaceType targetType, Iterable<InterfaceType> supertypes,
483+
Map<TypeVariableType, DartType> typeVariables) =>
484+
_entries.add(_RulesetEntry(targetType, supertypes, typeVariables));
468485
}
469486

470487
class RulesetEncoder {
@@ -487,23 +504,9 @@ class RulesetEncoder {
487504

488505
bool _isObject(InterfaceType type) => identical(type.element, _objectClass);
489506

490-
void _preprocessSupertype(_RulesetEntry entry, InterfaceType supertype) {
491-
InterfaceType thisSupertype = _dartTypes.getThisType(supertype.element);
492-
List<DartType> typeVariables = thisSupertype.typeArguments;
493-
List<DartType> supertypeArguments = supertype.typeArguments;
494-
int length = typeVariables.length;
495-
assert(supertypeArguments.length == length);
496-
for (int i = 0; i < length; i++) {
497-
entry._typeVariables[typeVariables[i]] = supertypeArguments[i];
498-
}
499-
}
500-
501507
void _preprocessEntry(_RulesetEntry entry) {
502-
entry._supertypes.removeWhere(_isObject);
503-
entry._supertypes.forEach(
504-
(InterfaceType supertype) => _preprocessSupertype(entry, supertype));
505-
entry._supertypes.removeWhere(
506-
(InterfaceType supertype) => identical(entry._targetType, supertype));
508+
entry._supertypes.removeWhere((InterfaceType supertype) =>
509+
_isObject(supertype) || identical(entry._targetType, supertype));
507510
}
508511

509512
void _preprocessRuleset(Ruleset ruleset) {

pkg/compiler/lib/src/js_emitter/model.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ library dart2js.new_js_emitter.model;
77
import '../constants/values.dart' show ConstantValue;
88
import '../deferred_load.dart' show OutputUnit;
99
import '../elements/entities.dart';
10+
import '../elements/types.dart';
1011
import '../js/js.dart' as js show Expression, Name, Statement, TokenFinalizer;
1112
import '../js/js_debug.dart' as js show nodeToString;
1213
import '../js_backend/runtime_types_codegen.dart';
@@ -233,6 +234,7 @@ class StaticField {
233234
}
234235
}
235236

237+
// TODO(fishythefish, sra): Split type information into separate model object.
236238
class Class implements FieldContainer {
237239
/// The element should only be used during the transition to the new model.
238240
/// Uses indicate missing information in the model.
@@ -246,6 +248,7 @@ class Class implements FieldContainer {
246248
final List<Field> fields;
247249
final List<StubMethod> isChecks;
248250
final ClassChecks classChecksNewRti;
251+
final Set<TypeVariableType> namedTypeVariablesNewRti = {};
249252
final List<StubMethod> checkedSetters;
250253

251254
/// Stub methods for this class that are call stubs for getters.

pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ import '../../js_backend/namer.dart' show Namer, StringBackedName;
2828
import '../../js_backend/native_data.dart';
2929
import '../../js_backend/runtime_types.dart'
3030
show RuntimeTypesChecks, RuntimeTypesEncoder;
31-
import '../../js_backend/runtime_types_new.dart' show RecipeEncoder;
31+
import '../../js_backend/runtime_types_new.dart'
32+
show RecipeEncoder, RecipeEncoding;
3233
import '../../js_backend/runtime_types_resolution.dart' show RuntimeTypesNeed;
3334
import '../../js_model/elements.dart' show JGeneratorBody, JSignatureMethod;
3435
import '../../js_model/type_recipe.dart'
3536
show FullTypeEnvironmentStructure, TypeExpressionRecipe;
3637
import '../../native/enqueue.dart' show NativeCodegenEnqueuer;
3738
import '../../options.dart';
39+
import '../../universe/class_hierarchy.dart';
3840
import '../../universe/codegen_world_builder.dart';
3941
import '../../universe/selector.dart' show Selector;
4042
import '../../universe/world_builder.dart' show SelectorConstraints;
@@ -102,6 +104,10 @@ class ProgramBuilder {
102104
/// True if the program should store function types in the metadata.
103105
bool _storeFunctionTypesInMetadata = false;
104106

107+
final Set<TypeVariableType> _lateNamedTypeVariablesNewRti = {};
108+
109+
ClassHierarchy get _classHierarchy => _closedWorld.classHierarchy;
110+
105111
ProgramBuilder(
106112
this._options,
107113
this._reporter,
@@ -241,6 +247,10 @@ class ProgramBuilder {
241247

242248
_markEagerClasses();
243249

250+
if (_options.experimentNewRti) {
251+
associateNamedTypeVariablesNewRti();
252+
}
253+
244254
List<Holder> holders = _registry.holders.toList(growable: false);
245255

246256
bool needsNativeSupport =
@@ -838,6 +848,18 @@ class ProgramBuilder {
838848
return result;
839849
}
840850

851+
void associateNamedTypeVariablesNewRti() {
852+
for (TypeVariableType typeVariable in _codegenWorld.namedTypeVariablesNewRti
853+
.union(_lateNamedTypeVariablesNewRti)) {
854+
for (ClassEntity entity
855+
in _classHierarchy.subtypesOf(typeVariable.element.typeDeclaration)) {
856+
Class cls = _classes[entity];
857+
if (cls == null) continue;
858+
cls.namedTypeVariablesNewRti.add(typeVariable);
859+
}
860+
}
861+
}
862+
841863
bool _methodNeedsStubs(FunctionEntity method) {
842864
if (method is JGeneratorBody) return false;
843865
if (method is ConstructorBodyEntity) return false;
@@ -962,13 +984,13 @@ class ProgramBuilder {
962984
FunctionType type, OutputUnit outputUnit) {
963985
if (type.containsTypeVariables) {
964986
if (_options.experimentNewRti) {
965-
// TODO(sra): The recipe might reference class type variables. Collect
966-
// these for the type metadata.
967-
return _rtiRecipeEncoder.encodeRecipe(
987+
RecipeEncoding encoding = _rtiRecipeEncoder.encodeRecipe(
968988
_task.emitter,
969989
FullTypeEnvironmentStructure(
970990
classType: _elementEnvironment.getThisType(enclosingClass)),
971991
TypeExpressionRecipe(type));
992+
_lateNamedTypeVariablesNewRti.addAll(encoding.typeVariables);
993+
return encoding.recipe;
972994
} else {
973995
js.Expression thisAccess = js.js(r'this.$receiver');
974996
return _rtiEncoder.getSignatureEncoding(

pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1950,7 +1950,15 @@ class FragmentEmitter {
19501950
InterfaceType targetType = _elementEnvironment.getThisType(cls.element);
19511951
Iterable<InterfaceType> supertypes = cls.classChecksNewRti.checks.map(
19521952
(TypeCheck check) => _dartTypes.asInstanceOf(targetType, check.cls));
1953-
ruleset.add(targetType, supertypes);
1953+
Map<TypeVariableType, DartType> typeVariables = {};
1954+
for (TypeVariableType typeVariable in cls.namedTypeVariablesNewRti) {
1955+
TypeVariableEntity element = typeVariable.element;
1956+
InterfaceType supertype =
1957+
_dartTypes.asInstanceOf(targetType, element.typeDeclaration);
1958+
List<DartType> supertypeArguments = supertype.typeArguments;
1959+
typeVariables[typeVariable] = supertypeArguments[element.index];
1960+
}
1961+
ruleset.add(targetType, supertypes, typeVariables);
19541962
});
19551963

19561964
FunctionEntity method = _closedWorld.commonElements.rtiAddRulesMethod;

pkg/compiler/lib/src/kernel/kernel_world.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class KClosedWorldImpl implements KClosedWorld {
7979
@override
8080
final Set<DartType> isChecks;
8181

82+
@override
83+
final Set<TypeVariableType> namedTypeVariablesNewRti;
84+
8285
final Map<Entity, Set<DartType>> staticTypeArgumentDependencies;
8386

8487
final Map<Selector, Set<DartType>> dynamicTypeArgumentDependencies;
@@ -122,6 +125,7 @@ class KClosedWorldImpl implements KClosedWorld {
122125
this.classHierarchy,
123126
this.annotationsData,
124127
this.isChecks,
128+
this.namedTypeVariablesNewRti,
125129
this.staticTypeArgumentDependencies,
126130
this.dynamicTypeArgumentDependencies,
127131
this.typeVariableTypeLiterals,

pkg/compiler/lib/src/ssa/codegen.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ import '../js_backend/native_data.dart';
2727
import '../js_backend/namer.dart' show ModularNamer;
2828
import '../js_backend/runtime_types.dart';
2929
import '../js_backend/runtime_types_codegen.dart';
30-
import '../js_backend/runtime_types_new.dart' show RecipeEncoder;
30+
import '../js_backend/runtime_types_new.dart'
31+
show RecipeEncoder, RecipeEncoding;
3132
import '../js_emitter/code_emitter_task.dart' show ModularEmitter;
3233
import '../js_model/elements.dart' show JGeneratorBody;
3334
import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
@@ -3423,8 +3424,15 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
34233424
// Call `env._eval("recipe")`.
34243425
use(node.inputs[0]);
34253426
js.Expression environment = pop();
3426-
js.Expression recipe = _rtiRecipeEncoder.encodeRecipe(
3427+
RecipeEncoding encoding = _rtiRecipeEncoder.encodeRecipe(
34273428
_emitter, node.envStructure, node.typeExpression);
3429+
js.Expression recipe = encoding.recipe;
3430+
3431+
for (TypeVariableType typeVariable in encoding.typeVariables) {
3432+
// TODO(fishythefish): Constraint the type variable to only be emitted on
3433+
// (subtypes of) the environment type.
3434+
_registry.registerTypeUse(TypeUse.namedTypeVariableNewRti(typeVariable));
3435+
}
34283436

34293437
MemberEntity method = _commonElements.rtiEvalMethod;
34303438
Selector selector = Selector.fromElement(method);

0 commit comments

Comments
 (0)