[VM] Ensure constant table is written in depth-first post-order
The addition of recently added [PartialInstantiationConstant] caused an issue during constant table writing, becaused we the table writing code wasn't updated. This change uses visitChildren to guard against such changes in the future. Closes https://github.com/dart-lang/sdk/issues/33095 Change-Id: I3c6b19e1383c6825f11120b2d6255b8b747d0063 Reviewed-on: https://dart-review.googlesource.com/55161 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
12c65eaeb4
commit
9d9ce8d69a
@@ -2019,59 +2019,32 @@ class ConstantIndexer extends RecursiveVisitor {
|
||||
|
||||
ConstantIndexer(this.stringIndexer);
|
||||
|
||||
defaultConstantReference(Constant node) {
|
||||
put(node);
|
||||
}
|
||||
|
||||
int put(Constant constant) {
|
||||
final int value = index[constant];
|
||||
if (value != null) return value;
|
||||
final int oldIndex = index[constant];
|
||||
if (oldIndex != null) return oldIndex;
|
||||
|
||||
// Traverse DAG in post-order to ensure children have their id's assigned
|
||||
// before the parent.
|
||||
return constant.accept(this);
|
||||
}
|
||||
constant.visitChildren(this);
|
||||
|
||||
defaultConstant(Constant node) {
|
||||
final int oldIndex = index[node];
|
||||
if (oldIndex != null) return oldIndex;
|
||||
|
||||
if (node is StringConstant) {
|
||||
stringIndexer.put(node.value);
|
||||
} else if (node is DoubleConstant) {
|
||||
stringIndexer.put('${node.value}');
|
||||
} else if (node is IntConstant) {
|
||||
final int value = node.value;
|
||||
if (constant is StringConstant) {
|
||||
stringIndexer.put(constant.value);
|
||||
} else if (constant is DoubleConstant) {
|
||||
stringIndexer.put('${constant.value}');
|
||||
} else if (constant is IntConstant) {
|
||||
final int value = constant.value;
|
||||
if ((value.abs() >> 30) != 0) {
|
||||
stringIndexer.put('$value');
|
||||
}
|
||||
}
|
||||
|
||||
final int newIndex = entries.length;
|
||||
entries.add(node);
|
||||
return index[node] = newIndex;
|
||||
entries.add(constant);
|
||||
return index[constant] = newIndex;
|
||||
}
|
||||
|
||||
visitMapConstant(MapConstant node) {
|
||||
for (final ConstantMapEntry entry in node.entries) {
|
||||
put(entry.key);
|
||||
put(entry.value);
|
||||
}
|
||||
return defaultConstant(node);
|
||||
}
|
||||
|
||||
visitListConstant(ListConstant node) {
|
||||
for (final Constant entry in node.entries) {
|
||||
put(entry);
|
||||
}
|
||||
return defaultConstant(node);
|
||||
}
|
||||
|
||||
visitInstanceConstant(InstanceConstant node) {
|
||||
for (final Constant entry in node.fieldValues.values) {
|
||||
put(entry);
|
||||
}
|
||||
return defaultConstant(node);
|
||||
defaultConstantReference(Constant node) {
|
||||
put(node);
|
||||
}
|
||||
|
||||
int operator [](Constant node) => index[node];
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// 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.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
typedef String IntFunctionType(int _);
|
||||
|
||||
class Box {
|
||||
final IntFunctionType fun;
|
||||
const Box(this.fun);
|
||||
}
|
||||
|
||||
String genericFunction<T>(T v) => '$v';
|
||||
|
||||
void main() {
|
||||
const list = const [const Box(genericFunction)];
|
||||
Expect.equals('42', list.first.fun(42));
|
||||
}
|
||||
Reference in New Issue
Block a user