Skip to content

Commit c6f708d

Browse files
rakudramacommit-bot@chromium.org
authored andcommitted
[dart2js] new-rti: Implement type literals
Emit type literals in the constant pool using recipes. Change-Id: Ia5ea024b444596844e94afbe2a34ce33e8557604 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107454 Commit-Queue: Stephen Adams <sra@google.com> Reviewed-by: Mayank Patke <fishythefish@google.com>
1 parent 0256155 commit c6f708d

12 files changed

Lines changed: 135 additions & 30 deletions

File tree

pkg/compiler/lib/src/common_elements.dart

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import 'inferrer/abstract_value_domain.dart';
1616
import 'js_backend/native_data.dart' show NativeBasicData;
1717
import 'js_model/locals.dart';
1818
import 'kernel/dart2js_target.dart';
19+
import 'options.dart';
1920
import 'universe/selector.dart' show Selector;
2021

2122
/// The common elements and types in Dart.
@@ -482,6 +483,7 @@ abstract class CommonElements {
482483

483484
FunctionEntity get findType;
484485
FunctionEntity get instanceType;
486+
FunctionEntity get typeLiteralMaker;
485487
FieldEntity get rtiAsField;
486488
FieldEntity get rtiCheckField;
487489
FieldEntity get rtiIsField;
@@ -614,8 +616,9 @@ abstract class JCommonElements implements CommonElements {
614616
class CommonElementsImpl
615617
implements CommonElements, KCommonElements, JCommonElements {
616618
final ElementEnvironment _env;
619+
final CompilerOptions _options;
617620

618-
CommonElementsImpl(this._env);
621+
CommonElementsImpl(this._env, this._options);
619622

620623
ClassEntity _objectClass;
621624
@override
@@ -1443,7 +1446,9 @@ class CommonElementsImpl
14431446
ClassEntity _typeLiteralClass;
14441447
@override
14451448
ClassEntity get typeLiteralClass =>
1446-
_typeLiteralClass ??= _findHelperClass('TypeImpl');
1449+
_typeLiteralClass ??= _options.experimentNewRti
1450+
? _findRtiClass('_Type')
1451+
: _findHelperClass('TypeImpl');
14471452

14481453
ClassEntity _constMapLiteralClass;
14491454
@override
@@ -1730,8 +1735,9 @@ class CommonElementsImpl
17301735
_findHelperFunction('throwNoSuchMethod');
17311736

17321737
@override
1733-
FunctionEntity get createRuntimeType =>
1734-
_findHelperFunction('createRuntimeType');
1738+
FunctionEntity get createRuntimeType => _options.experimentNewRti
1739+
? _findRtiFunction('_createRuntimeType')
1740+
: _findHelperFunction('createRuntimeType');
17351741

17361742
@override
17371743
FunctionEntity get fallThroughError =>
@@ -1805,6 +1811,8 @@ class CommonElementsImpl
18051811

18061812
// From dart:_rti
18071813

1814+
ClassEntity _findRtiClass(String name) => _findClass(rtiLibrary, name);
1815+
18081816
FunctionEntity _findRtiFunction(String name) =>
18091817
_findLibraryMember(rtiLibrary, name);
18101818

@@ -1817,6 +1825,11 @@ class CommonElementsImpl
18171825
FunctionEntity get instanceType =>
18181826
_instanceType ??= _findRtiFunction('instanceType');
18191827

1828+
FunctionEntity _typeLiteralMaker;
1829+
@override
1830+
FunctionEntity get typeLiteralMaker =>
1831+
_typeLiteralMaker ??= _findRtiFunction('typeLiteral');
1832+
18201833
ClassEntity get _rtiImplClass => _findClass(rtiLibrary, 'Rti');
18211834
FieldEntity _findRtiClassField(String name) =>
18221835
_findClassMember(_rtiImplClass, name);

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,12 @@ class BackendImpacts {
423423
BackendImpact _typeLiteral;
424424

425425
BackendImpact get typeLiteral {
426-
return _typeLiteral ??= new BackendImpact(
427-
instantiatedClasses: [_commonElements.typeLiteralClass],
428-
staticUses: [_commonElements.createRuntimeType]);
426+
return _typeLiteral ??= new BackendImpact(instantiatedClasses: [
427+
_commonElements.typeLiteralClass
428+
], staticUses: [
429+
_commonElements.createRuntimeType,
430+
if (_newRti) _commonElements.typeLiteralMaker,
431+
]);
429432
}
430433

431434
BackendImpact _stackTraceInCatch;

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,10 @@ class CodegenEnqueuerListener extends EnqueuerListener {
182182
helper, helper.parameterStructure.callStructure));
183183
}
184184
if (type.element == _commonElements.typeLiteralClass) {
185-
// If we use a type literal in a constant, the compile time
186-
// constant emitter will generate a call to the createRuntimeType
187-
// helper so we register a use of that.
188-
FunctionEntity helper = _commonElements.createRuntimeType;
189-
impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
190-
helper, helper.parameterStructure.callStructure));
185+
// If we use a type literal in a constant, the compile time constant
186+
// emitter will generate a call to a helper so we register the impact
187+
// that contains that call.
188+
_impacts.typeLiteral.registerImpact(impactBuilder, _elementEnvironment);
191189
}
192190
}
193191
}

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

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ import '../js/js.dart' as jsAst;
1313
import '../js/js.dart' show js;
1414
import '../js_backend/field_analysis.dart';
1515
import '../js_emitter/code_emitter_task.dart';
16+
import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
1617
import '../options.dart';
1718
import 'field_analysis.dart' show JFieldAnalysis;
1819
import 'runtime_types.dart';
20+
import 'runtime_types_new.dart' show RecipeEncoder;
1921

2022
typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant);
2123

@@ -205,6 +207,7 @@ class ConstantEmitter extends ModularConstantEmitter {
205207
final JElementEnvironment _elementEnvironment;
206208
final RuntimeTypesNeed _rtiNeed;
207209
final RuntimeTypesEncoder _rtiEncoder;
210+
final RecipeEncoder _rtiRecipeEncoder;
208211
final JFieldAnalysis _fieldAnalysis;
209212
final Emitter _emitter;
210213
final _ConstantReferenceGenerator _constantReferenceGenerator;
@@ -219,6 +222,7 @@ class ConstantEmitter extends ModularConstantEmitter {
219222
this._elementEnvironment,
220223
this._rtiNeed,
221224
this._rtiEncoder,
225+
this._rtiRecipeEncoder,
222226
this._fieldAnalysis,
223227
this._emitter,
224228
this._constantReferenceGenerator,
@@ -354,19 +358,34 @@ class ConstantEmitter extends ModularConstantEmitter {
354358
jsAst.Expression visitType(TypeConstantValue constant, [_]) {
355359
DartType type = constant.representedType.unaliased;
356360

357-
jsAst.Expression unexpected(TypeVariableType _variable) {
358-
TypeVariableType variable = _variable;
359-
throw failedAt(
360-
NO_LOCATION_SPANNABLE,
361-
"Unexpected type variable '${variable}'"
362-
" in constant '${constant.toDartText()}'");
363-
}
361+
if (_options.experimentNewRti) {
362+
assert(!type.containsTypeVariables);
364363

365-
jsAst.Expression rti =
366-
_rtiEncoder.getTypeRepresentation(_emitter, type, unexpected);
364+
jsAst.Expression recipe = _rtiRecipeEncoder.encodeGroundRecipe(
365+
_emitter, TypeExpressionRecipe(type));
367366

368-
return new jsAst.Call(
369-
getHelperProperty(_commonElements.createRuntimeType), [rti]);
367+
// Generate `typeLiteral(recipe)`.
368+
369+
// TODO(sra): `typeLiteral(r)` calls `createRuntimeType(findType(r))`.
370+
// Find a way to share the `findType` call with methods that also use the
371+
// type.
372+
return js('#(#)',
373+
[getHelperProperty(_commonElements.typeLiteralMaker), recipe]);
374+
} else {
375+
jsAst.Expression unexpected(TypeVariableType _variable) {
376+
TypeVariableType variable = _variable;
377+
throw failedAt(
378+
NO_LOCATION_SPANNABLE,
379+
"Unexpected type variable '${variable}'"
380+
" in constant '${constant.toDartText()}'");
381+
}
382+
383+
jsAst.Expression rti =
384+
_rtiEncoder.getTypeRepresentation(_emitter, type, unexpected);
385+
386+
return new jsAst.Call(
387+
getHelperProperty(_commonElements.createRuntimeType), [rti]);
388+
}
370389
}
371390

372391
@override

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class CodeEmitterTask extends CompilerTask {
9090
namer,
9191
closedWorld,
9292
codegen.rtiEncoder,
93+
codegen.rtiRecipeEncoder,
9394
_backendStrategy.sourceInformationStrategy,
9495
this,
9596
_generateSourceMap);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import '../../js/js.dart' as js;
1717
import '../../js_backend/constant_emitter.dart';
1818
import '../../js_backend/namer.dart';
1919
import '../../js_backend/runtime_types.dart';
20+
import '../../js_backend/runtime_types_new.dart' show RecipeEncoder;
2021
import '../../options.dart';
2122
import '../../universe/codegen_world_builder.dart' show CodegenWorld;
2223
import '../../world.dart' show JClosedWorld;
@@ -143,6 +144,7 @@ class EmitterImpl extends ModularEmitterBase implements Emitter {
143144
final DiagnosticReporter _reporter;
144145
final JClosedWorld _closedWorld;
145146
final RuntimeTypesEncoder _rtiEncoder;
147+
final RecipeEncoder _rtiRecipeEncoder;
146148
final CompilerTask _task;
147149
ModelEmitter _emitter;
148150

@@ -157,6 +159,7 @@ class EmitterImpl extends ModularEmitterBase implements Emitter {
157159
Namer namer,
158160
this._closedWorld,
159161
this._rtiEncoder,
162+
this._rtiRecipeEncoder,
160163
SourceInformationStrategy sourceInformationStrategy,
161164
this._task,
162165
bool shouldGenerateSourceMap)
@@ -172,6 +175,7 @@ class EmitterImpl extends ModularEmitterBase implements Emitter {
172175
this,
173176
sourceInformationStrategy,
174177
_rtiEncoder,
178+
_rtiRecipeEncoder,
175179
shouldGenerateSourceMap);
176180
}
177181

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import '../../js_backend/js_backend.dart'
4949
show Namer, ConstantEmitter, StringBackedName;
5050
import '../../js_backend/js_interop_analysis.dart' as jsInteropAnalysis;
5151
import '../../js_backend/runtime_types.dart';
52+
import '../../js_backend/runtime_types_new.dart' show RecipeEncoder;
5253
import '../../options.dart';
5354
import '../../universe/codegen_world_builder.dart' show CodegenWorld;
5455
import '../../world.dart';
@@ -99,6 +100,7 @@ class ModelEmitter {
99100
this._emitter,
100101
this._sourceInformationStrategy,
101102
RuntimeTypesEncoder rtiEncoder,
103+
RecipeEncoder rtiRecipeEncoder,
102104
this._shouldGenerateSourceMap)
103105
: _constantOrdering = new ConstantOrdering(_closedWorld.sorter) {
104106
this._constantEmitter = new ConstantEmitter(
@@ -107,6 +109,7 @@ class ModelEmitter {
107109
_closedWorld.elementEnvironment,
108110
_closedWorld.rtiNeed,
109111
rtiEncoder,
112+
rtiRecipeEncoder,
110113
_closedWorld.fieldAnalysis,
111114
_emitter,
112115
this.generateConstantReference,

pkg/compiler/lib/src/js_model/element_map_impl.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
138138
AnnotationsData annotations)
139139
: this.options = _elementMap.options {
140140
_elementEnvironment = new JsElementEnvironment(this);
141-
_commonElements = new CommonElementsImpl(_elementEnvironment);
141+
_commonElements =
142+
new CommonElementsImpl(_elementEnvironment, _elementMap.options);
142143
_constantEnvironment = new JsConstantEnvironment(this, environment);
143144
_typeConverter = new DartTypeConverter(this);
144145
_types = new KernelDartTypes(this);
@@ -317,7 +318,7 @@ class JsKernelToElementMap implements JsToElementMap, IrToElementMap {
317318
JsKernelToElementMap.readFromDataSource(this.options, this.reporter,
318319
Environment environment, ir.Component component, DataSource source) {
319320
_elementEnvironment = new JsElementEnvironment(this);
320-
_commonElements = new CommonElementsImpl(_elementEnvironment);
321+
_commonElements = new CommonElementsImpl(_elementEnvironment, options);
321322
_constantEnvironment = new JsConstantEnvironment(this, environment);
322323
_typeConverter = new DartTypeConverter(this);
323324
_types = new KernelDartTypes(this);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class KernelToElementMapImpl implements KernelToElementMap, IrToElementMap {
122122
KernelToElementMapImpl(
123123
this.reporter, this._environment, this._frontendStrategy, this.options) {
124124
_elementEnvironment = new KernelElementEnvironment(this);
125-
_commonElements = new CommonElementsImpl(_elementEnvironment);
125+
_commonElements = new CommonElementsImpl(_elementEnvironment, options);
126126
_constantEnvironment = new KernelConstantEnvironment(this, _environment);
127127
_typeConverter = new DartTypeConverter(this);
128128
_types = new KernelDartTypes(this);

sdk/lib/_internal/js_runtime/lib/js_helper.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ import 'dart:_js_names'
5959
unmangleGlobalNameIfPreservedAnyways,
6060
unmangleAllIdentifiersIfPreservedAnyways;
6161

62-
import 'dart:_rti' as newRti show getRuntimeType;
62+
import 'dart:_rti' as newRti show createRuntimeType, getRuntimeType;
6363

6464
part 'annotations.dart';
6565
part 'constant_map.dart';

0 commit comments

Comments
 (0)