Version 2.17.0-178.0.dev
Merge commit '6231245e8053ea15120fe8b4fd66cf3966e78eb2' into 'dev'
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index 2795e48..f50a56d 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -27,6 +27,7 @@
const greater = GreaterOperation();
const identity = IdentityOperation();
const ifNull = IfNullOperation();
+const index = _IndexOperation();
const lessEqual = LessEqualOperation();
const less = LessOperation();
const modulo = ModuloOperation();
@@ -990,6 +991,38 @@
}
}
+class _IndexOperation implements BinaryOperation {
+ @override
+ final String name = '[]';
+
+ const _IndexOperation();
+
+ @override
+ ConstantValue fold(ConstantValue left, ConstantValue right) {
+ if (left is ListConstantValue) {
+ if (right is IntConstantValue) {
+ List<ConstantValue> entries = left.entries;
+ if (right.isUInt32()) {
+ int index = right.intValue.toInt();
+ if (index >= 0 && index < entries.length) {
+ return entries[index];
+ }
+ }
+ }
+ }
+ if (left is MapConstantValue) {
+ ConstantValue value = left.lookup(right);
+ if (value != null) return value;
+ return const NullConstantValue();
+ }
+
+ return null;
+ }
+
+ @override
+ apply(left, right) => throw UnsupportedError('punned indexing');
+}
+
class UnfoldedUnaryOperation implements UnaryOperation {
@override
final String name;
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index ab80914..f514f5f 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -275,6 +275,11 @@
const IndexSpecializer();
@override
+ constant_system.BinaryOperation operation() {
+ return constant_system.index;
+ }
+
+ @override
HInstruction tryConvertToBuiltin(
HInvokeDynamic instruction,
HGraph graph,
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index d7433a0..5e178c2 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -1493,15 +1493,15 @@
@override
HInstruction visitIndex(HIndex node) {
- if (node.receiver.isConstantList() && node.index.isConstantInteger()) {
- HConstant instruction = node.receiver;
- ListConstantValue list = instruction.constant;
- List<ConstantValue> entries = list.entries;
- HConstant indexInstruction = node.index;
- IntConstantValue indexConstant = indexInstruction.constant;
- int index = indexConstant.intValue.toInt();
- if (index >= 0 && index < entries.length) {
- return _graph.addConstant(entries[index], _closedWorld);
+ HInstruction receiver = node.receiver;
+ if (receiver is HConstant) {
+ HInstruction index = node.index;
+ if (index is HConstant) {
+ ConstantValue foldedValue =
+ constant_system.index.fold(receiver.constant, index.constant);
+ if (foldedValue != null) {
+ return _graph.addConstant(foldedValue, _closedWorld);
+ }
}
}
return node;
diff --git a/pkg/compiler/test/codegen/data/indexer_constant_folding.dart b/pkg/compiler/test/codegen/data/indexer_constant_folding.dart
new file mode 100644
index 0000000..da77d1e
--- /dev/null
+++ b/pkg/compiler/test/codegen/data/indexer_constant_folding.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2022, 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.
+
+const kList = ['first', 'second'];
+const kMap = {0: 'zero', 1: 'one', 2: "two"};
+
+@pragma('dart2js:noInline')
+/*member: list1:function() {
+ return "second";
+}*/
+list1() {
+ return kList[1]; // Constant folds to `"second"`.
+}
+
+@pragma('dart2js:noInline')
+/*member: list2:function() {
+ return A.ioore(B.List_first_second, 10);
+ return B.List_first_second[10];
+}*/
+list2() {
+ return kList[10]; // Does not constant-fold.
+}
+
+@pragma('dart2js:noInline')
+/*member: map1:function() {
+ return "one";
+}*/
+map1() {
+ return kMap[1]; // Constant folds to `"one"`.
+}
+
+@pragma('dart2js:noInline')
+/*member: map2:function() {
+ return null;
+}*/
+map2() {
+ return kMap[10]; // Constant folds to `null`.
+}
+
+/*member: main:ignore*/
+main() {
+ list1();
+ list2();
+ map1();
+ map2();
+}
diff --git a/tools/VERSION b/tools/VERSION
index 669b922..22204ac 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 177
+PRERELEASE 178
PRERELEASE_PATCH 0
\ No newline at end of file