79b52401f2
Change-Id: I032d10fd1956b62a9e45ceee9ca2b28c9863d1ce Tested: diagnostic updates only change Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/401560 Commit-Queue: Devon Carew <devoncarew@google.com> Reviewed-by: Nate Bosch <nbosch@google.com>
91 lines
2.8 KiB
Dart
91 lines
2.8 KiB
Dart
// 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 'dart:io';
|
|
|
|
import 'package:dart2js_tools/src/util.dart';
|
|
|
|
/// Script to show a text representation of the inlining data attached to
|
|
/// source-map files.
|
|
///
|
|
/// This expands the push/pop operations and checks simple invariants (e.g. that
|
|
/// the stack is always empty at the beginning of a function).
|
|
void main(List<String> args) {
|
|
if (args.length != 1) {
|
|
print('usage: show_inline_data.dart <js-file>');
|
|
exit(1);
|
|
}
|
|
var uri = Uri.base.resolve(args[0]);
|
|
var provider = CachingFileProvider();
|
|
|
|
var mapping = provider.mappingFor(uri);
|
|
var starts = functionStarts(provider.sourcesFor(uri));
|
|
var file = provider.fileFor(uri);
|
|
var frames = mapping!.frames;
|
|
var offsets = frames.keys.toList()..sort();
|
|
var sb = StringBuffer();
|
|
int depth = 0;
|
|
int? lastFunctionStart;
|
|
for (var offset in offsets) {
|
|
int functionStart = nextFunctionStart(starts, offset, lastFunctionStart);
|
|
if (lastFunctionStart == null || functionStart > lastFunctionStart) {
|
|
sb.write('\n${location(starts[functionStart], file)}: function start\n');
|
|
|
|
if (depth != 0) {
|
|
sb.write(
|
|
"[31m[invalid] function start with non-zero depth: $depth[0m\n",
|
|
);
|
|
}
|
|
lastFunctionStart = functionStart;
|
|
}
|
|
|
|
var offsetPrefix = '${location(offset, file)}:';
|
|
var pad = ' ' * offsetPrefix.length;
|
|
sb.write(offsetPrefix);
|
|
bool first = true;
|
|
for (var frame in frames[offset]!) {
|
|
if (!first) sb.write(pad);
|
|
sb.write(' $frame\n');
|
|
first = false;
|
|
if (frame.isPush) depth++;
|
|
if (frame.isPop) depth--;
|
|
if (frame.isEmpty && depth != 0) {
|
|
sb.write("[31m[invalid] pop-empty with non-zero depth: $depth[0m\n");
|
|
}
|
|
if (!frame.isEmpty && depth == 0) {
|
|
sb.write("[31m[invalid] non-empty pop with zero depth: $depth[0m\n");
|
|
}
|
|
if (depth < 0) {
|
|
sb.write("[31m[invalid] negative depth: $depth[0m\n");
|
|
}
|
|
}
|
|
}
|
|
print('$sb');
|
|
}
|
|
|
|
var _functionDeclarationRegExp = RegExp(r':( )?function\(');
|
|
|
|
List<int> functionStarts(String sources) {
|
|
List<int> result = [];
|
|
int index = sources.indexOf(_functionDeclarationRegExp);
|
|
while (index != -1) {
|
|
result.add(index + 2);
|
|
index = sources.indexOf(_functionDeclarationRegExp, index + 1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int nextFunctionStart(List<int> starts, int offset, int? last) {
|
|
int j = last ?? 0;
|
|
for (; j < starts.length && starts[j] <= offset; j++) {}
|
|
return j - 1;
|
|
}
|
|
|
|
String location(int offset, file) {
|
|
var line = file.getLine(offset) + 1;
|
|
var column = file.getColumn(offset) + 1;
|
|
var location = '$offset ($line:$column)';
|
|
return location + (' ' * (16 - location.length));
|
|
}
|