[dart2wasm] Fix unreachable instance call issue
When a call is unreachable we used to generate sometimes a block with no outputs, but callers expected an output which they may drop. That caused stack discipline mismatch. Instead we should simply emit an unreachable and tell the caller there's no value. Issue https://github.com/dart-lang/sdk/issues/63454 Change-Id: I81be6729fd578e237c4e6483539a9d53a9ed355e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506960 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Slava Egorov <vegorov@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
6c88c6f2ba
commit
5423762c21
@@ -2047,13 +2047,8 @@ abstract class AstCodeGenerator
|
||||
" at ${node.location}",
|
||||
);
|
||||
pushArguments(signature, selector.paramInfo);
|
||||
for (int i = 0; i < signature.inputs.length; ++i) {
|
||||
b.drop();
|
||||
}
|
||||
b.block(const [], signature.outputs);
|
||||
b.unreachable();
|
||||
b.end();
|
||||
return translator.outputOrVoid(signature.outputs);
|
||||
return voidMarker;
|
||||
}
|
||||
if (directCall) {
|
||||
final target = translator.getFunctionEntry(
|
||||
|
||||
@@ -245,10 +245,8 @@ class SelectorInfo {
|
||||
// This happens if the selector doesn't have any targets. Any call site of
|
||||
// such a selector is unreachable. Though such call sites still have to
|
||||
// evaluate receiver and arguments. Doing so requires the signature. So we
|
||||
// create a dummy signature with top types. Receivers specifically should
|
||||
// be non-nullable since we must be invoking a selector on some object.
|
||||
assert(!isReceiver);
|
||||
return isReceiver ? translator.topTypeNonNullable : translator.topType;
|
||||
// create a dummy signature with top types.
|
||||
return translator.topType;
|
||||
}
|
||||
if (!ensureBoxed && types.length == 1 && types.single.isPrimitive) {
|
||||
// Unboxed primitive.
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2026, 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.
|
||||
|
||||
main() {
|
||||
print('main start');
|
||||
final value = Object();
|
||||
final map = <Unused, int>{};
|
||||
for (final entry in map.entries) {
|
||||
print('before');
|
||||
entry.key.foo = value;
|
||||
print('after');
|
||||
}
|
||||
print('main end');
|
||||
}
|
||||
|
||||
class Unused {
|
||||
Object? foo;
|
||||
}
|
||||
Reference in New Issue
Block a user