[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:
Martin Kustermann
2018-05-15 15:17:36 +00:00
committed by commit-bot@chromium.org
parent 12c65eaeb4
commit 9d9ce8d69a
2 changed files with 32 additions and 40 deletions
+13 -40
View File
@@ -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));
}