6903672599
TEST=ci Change-Id: Id12824cf667181122d4d2c4e7af7dc6206d1f85b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384043 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Alexander Markov <alexmarkov@google.com>
111 lines
3.2 KiB
Dart
111 lines
3.2 KiB
Dart
// Copyright (c) 2024, 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 'bytecode_serialization.dart' show BufferedWriter, BufferedReader;
|
|
|
|
class TryBlock {
|
|
static const int flagNeedsStackTrace = 1 << 0;
|
|
static const int flagIsSynthetic = 1 << 1;
|
|
|
|
final int tryIndex;
|
|
final int outerTryIndex;
|
|
final int startPC;
|
|
int endPC = -1;
|
|
int handlerPC = -1;
|
|
int flags = 0;
|
|
List<int> types = <int>[];
|
|
|
|
TryBlock._(this.tryIndex, this.outerTryIndex, this.startPC);
|
|
|
|
bool get needsStackTrace => (flags & flagNeedsStackTrace) != 0;
|
|
|
|
void set needsStackTrace(bool value) {
|
|
flags = (flags & ~flagNeedsStackTrace) | (value ? flagNeedsStackTrace : 0);
|
|
}
|
|
|
|
bool get isSynthetic => (flags & flagIsSynthetic) != 0;
|
|
|
|
void set isSynthetic(bool value) {
|
|
flags = (flags & ~flagIsSynthetic) | (value ? flagIsSynthetic : 0);
|
|
}
|
|
|
|
void write(BufferedWriter writer) {
|
|
writer.writePackedUInt30(outerTryIndex + 1);
|
|
writer.writePackedUInt30(startPC);
|
|
writer.writePackedUInt30(endPC);
|
|
writer.writePackedUInt30(handlerPC);
|
|
writer.writeByte(flags);
|
|
writer.writePackedUInt30(types.length);
|
|
types.forEach(writer.writePackedUInt30);
|
|
}
|
|
|
|
factory TryBlock.read(BufferedReader reader, int tryIndex) {
|
|
final outerTryIndex = reader.readPackedUInt30() - 1;
|
|
final startPC = reader.readPackedUInt30();
|
|
final tryBlock = new TryBlock._(tryIndex, outerTryIndex, startPC);
|
|
|
|
tryBlock.endPC = reader.readPackedUInt30();
|
|
tryBlock.handlerPC = reader.readPackedUInt30();
|
|
tryBlock.flags = reader.readByte();
|
|
tryBlock.types = new List<int>.generate(
|
|
reader.readPackedUInt30(), (_) => reader.readPackedUInt30());
|
|
|
|
return tryBlock;
|
|
}
|
|
|
|
@override
|
|
String toString() => 'try-index $tryIndex, outer $outerTryIndex, '
|
|
'start $startPC, end $endPC, handler $handlerPC, '
|
|
'${needsStackTrace ? 'needs-stack-trace, ' : ''}'
|
|
'${isSynthetic ? 'synthetic, ' : ''}'
|
|
'types ${types.map((t) => 'CP#$t').toList()}';
|
|
}
|
|
|
|
class ExceptionsTable {
|
|
List<TryBlock> blocks = <TryBlock>[];
|
|
|
|
ExceptionsTable();
|
|
|
|
TryBlock enterTryBlock(int startPC) {
|
|
assert(blocks.isEmpty || blocks.last.startPC <= startPC);
|
|
final tryBlock =
|
|
new TryBlock._(blocks.length, _outerTryBlockIndex(startPC), startPC);
|
|
blocks.add(tryBlock);
|
|
return tryBlock;
|
|
}
|
|
|
|
int _outerTryBlockIndex(int startPC) {
|
|
for (int i = blocks.length - 1; i >= 0; --i) {
|
|
final tryBlock = blocks[i];
|
|
if (tryBlock.endPC < 0 || tryBlock.endPC > startPC) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void write(BufferedWriter writer) {
|
|
writer.writePackedUInt30(blocks.length);
|
|
blocks.forEach((b) => b.write(writer));
|
|
}
|
|
|
|
ExceptionsTable.read(BufferedReader reader)
|
|
: blocks = new List<TryBlock>.generate(reader.readPackedUInt30(),
|
|
(int index) => new TryBlock.read(reader, index));
|
|
|
|
@override
|
|
String toString() {
|
|
if (blocks.isEmpty) {
|
|
return '';
|
|
}
|
|
StringBuffer sb = new StringBuffer();
|
|
sb.writeln('ExceptionsTable {');
|
|
for (var tryBlock in blocks) {
|
|
sb.writeln(' $tryBlock');
|
|
}
|
|
sb.writeln('}');
|
|
return sb.toString();
|
|
}
|
|
}
|