34fb48bb8a
Migrates libraries dependent only on already migrated libraries. Change-Id: I0e85ee8dbc2afce031b92e0009e71c206a55af28 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179502 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
121 lines
4.5 KiB
Dart
121 lines
4.5 KiB
Dart
// Copyright (c) 2017, 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.
|
|
|
|
// @dart = 2.9
|
|
|
|
library vm.constants_native_effects;
|
|
|
|
import '../ast.dart';
|
|
import '../target/targets.dart';
|
|
import '../core_types.dart';
|
|
|
|
class VmConstantsBackend extends ConstantsBackend {
|
|
final Class immutableMapClass;
|
|
final Class unmodifiableSetClass;
|
|
final Field unmodifiableSetMap;
|
|
|
|
VmConstantsBackend._(this.immutableMapClass, this.unmodifiableSetMap,
|
|
this.unmodifiableSetClass);
|
|
|
|
/// If [defines] is not `null` it will be used for handling
|
|
/// `const {bool,...}.fromEnvironment()` otherwise the current VM's values
|
|
/// will be used.
|
|
factory VmConstantsBackend(CoreTypes coreTypes) {
|
|
final Library coreLibrary = coreTypes.coreLibrary;
|
|
final Class immutableMapClass = coreLibrary.classes
|
|
.firstWhere((Class klass) => klass.name == '_ImmutableMap');
|
|
assert(immutableMapClass != null);
|
|
Field unmodifiableSetMap = coreTypes.index
|
|
.getMember('dart:collection', '_UnmodifiableSet', '_map');
|
|
|
|
return new VmConstantsBackend._(immutableMapClass, unmodifiableSetMap,
|
|
unmodifiableSetMap.enclosingClass);
|
|
}
|
|
|
|
@override
|
|
Constant lowerMapConstant(MapConstant constant) {
|
|
// The _ImmutableMap class is implemented via one field pointing to a list
|
|
// of key/value pairs -- see runtime/lib/immutable_map.dart!
|
|
final List<Constant> kvListPairs =
|
|
new List<Constant>.filled(2 * constant.entries.length, null);
|
|
for (int i = 0; i < constant.entries.length; i++) {
|
|
final ConstantMapEntry entry = constant.entries[i];
|
|
kvListPairs[2 * i] = entry.key;
|
|
kvListPairs[2 * i + 1] = entry.value;
|
|
}
|
|
// This is a bit fishy, since we merge the key and the value type by
|
|
// putting both into the same list.
|
|
final ListConstant kvListConstant =
|
|
new ListConstant(const DynamicType(), kvListPairs);
|
|
assert(immutableMapClass.fields.length == 1);
|
|
final Field kvPairListField = immutableMapClass.fields[0];
|
|
return new InstanceConstant(immutableMapClass.reference, <DartType>[
|
|
constant.keyType,
|
|
constant.valueType,
|
|
], <Reference, Constant>{
|
|
// We use getterReference as we refer to the field itself.
|
|
kvPairListField.getterReference: kvListConstant,
|
|
});
|
|
}
|
|
|
|
@override
|
|
bool isLoweredMapConstant(Constant constant) {
|
|
return constant is InstanceConstant &&
|
|
constant.classNode == immutableMapClass;
|
|
}
|
|
|
|
@override
|
|
void forEachLoweredMapConstantEntry(
|
|
Constant constant, void Function(Constant key, Constant value) f) {
|
|
assert(isLoweredMapConstant(constant));
|
|
final InstanceConstant instance = constant;
|
|
assert(immutableMapClass.fields.length == 1);
|
|
final Field kvPairListField = immutableMapClass.fields[0];
|
|
final ListConstant kvListConstant =
|
|
instance.fieldValues[kvPairListField.getterReference];
|
|
assert(kvListConstant.entries.length % 2 == 0);
|
|
for (int index = 0; index < kvListConstant.entries.length; index += 2) {
|
|
f(kvListConstant.entries[index], kvListConstant.entries[index + 1]);
|
|
}
|
|
}
|
|
|
|
@override
|
|
Constant lowerSetConstant(SetConstant constant) {
|
|
final DartType elementType = constant.typeArgument;
|
|
final List<Constant> entries = constant.entries;
|
|
final List<ConstantMapEntry> mapEntries =
|
|
new List<ConstantMapEntry>.filled(entries.length, null);
|
|
for (int i = 0; i < entries.length; ++i) {
|
|
mapEntries[i] = new ConstantMapEntry(entries[i], new NullConstant());
|
|
}
|
|
Constant map = lowerMapConstant(
|
|
new MapConstant(elementType, const NullType(), mapEntries));
|
|
return new InstanceConstant(unmodifiableSetClass.reference, [elementType],
|
|
<Reference, Constant>{unmodifiableSetMap.getterReference: map});
|
|
}
|
|
|
|
@override
|
|
bool isLoweredSetConstant(Constant constant) {
|
|
if (constant is InstanceConstant &&
|
|
constant.classNode == unmodifiableSetClass) {
|
|
InstanceConstant instance = constant;
|
|
return isLoweredMapConstant(
|
|
instance.fieldValues[unmodifiableSetMap.getterReference]);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@override
|
|
void forEachLoweredSetConstantElement(
|
|
Constant constant, void Function(Constant element) f) {
|
|
assert(isLoweredSetConstant(constant));
|
|
final InstanceConstant instance = constant;
|
|
final Constant mapConstant =
|
|
instance.fieldValues[unmodifiableSetMap.getterReference];
|
|
forEachLoweredMapConstantEntry(mapConstant, (Constant key, Constant value) {
|
|
f(key);
|
|
});
|
|
}
|
|
}
|