| // 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. | |
| library vm.bytecode.source_positions; | |
| import 'bytecode_serialization.dart' show BufferedWriter, BufferedReader; | |
| /// Maintains mapping between bytecode instructions and source positions. | |
| class SourcePositions { | |
| final Map<int, int> mapping = <int, int>{}; // PC -> fileOffset | |
| int _lastPc = 0; | |
| int _lastOffset = 0; | |
| SourcePositions(); | |
| void add(int pc, int fileOffset) { | |
| assert(pc > _lastPc); | |
| assert(fileOffset >= 0); | |
| if (fileOffset != _lastOffset) { | |
| mapping[pc] = fileOffset; | |
| _lastPc = pc; | |
| _lastOffset = fileOffset; | |
| } | |
| } | |
| void write(BufferedWriter writer) { | |
| writer.writePackedUInt30(mapping.length); | |
| final encodePC = new PackedUInt30DeltaEncoder(); | |
| final encodeOffset = new SLEB128DeltaEncoder(); | |
| mapping.forEach((int pc, int fileOffset) { | |
| encodePC.write(writer, pc); | |
| encodeOffset.write(writer, fileOffset); | |
| }); | |
| } | |
| SourcePositions.read(BufferedReader reader) { | |
| final int length = reader.readPackedUInt30(); | |
| final decodePC = new PackedUInt30DeltaDecoder(); | |
| final decodeOffset = new SLEB128DeltaDecoder(); | |
| for (int i = 0; i < length; ++i) { | |
| int pc = decodePC.read(reader); | |
| int fileOffset = decodeOffset.read(reader); | |
| add(pc, fileOffset); | |
| } | |
| } | |
| @override | |
| String toString() => mapping.toString(); | |
| Map<int, String> getBytecodeAnnotations() { | |
| return mapping.map((int pc, int fileOffset) => | |
| new MapEntry(pc, 'source position $fileOffset')); | |
| } | |
| } | |
| class PackedUInt30DeltaEncoder { | |
| int _last = 0; | |
| void write(BufferedWriter write, int value) { | |
| write.writePackedUInt30(value - _last); | |
| _last = value; | |
| } | |
| } | |
| class PackedUInt30DeltaDecoder { | |
| int _last = 0; | |
| int read(BufferedReader reader) { | |
| int value = reader.readPackedUInt30() + _last; | |
| _last = value; | |
| return value; | |
| } | |
| } | |
| class SLEB128DeltaEncoder { | |
| int _last = 0; | |
| void write(BufferedWriter writer, int value) { | |
| writer.writeSLEB128(value - _last); | |
| _last = value; | |
| } | |
| } | |
| class SLEB128DeltaDecoder { | |
| int _last = 0; | |
| int read(BufferedReader reader) { | |
| int value = reader.readSLEB128() + _last; | |
| _last = value; | |
| return value; | |
| } | |
| } |