blob: 849cc730c341aacbcba44cb30142ea236803c062 [file] [log] [blame]
/*
* Copyright 2017 WebAssembly Community Group participants
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WABT_SOURCE_MAPS_H
#define WABT_SOURCE_MAPS_H
#include <cstdint>
#include <cstring>
#include <map>
#include <string>
#include <vector>
struct SourceMap {
static constexpr const int32_t kSourceMapVersion = 3;
// Representation of mappings
struct Segment {
// Field 1
uint32_t generated_col = 0; // Start column in generated code. Remove?
uint32_t generated_col_delta = 0; // Delta from previous generated col
bool has_source = false; // If true, fields 2-4 will be valid.
// Field 2
size_t source = 0; // Index into sources list
// Field 3
uint32_t source_line = 0; // Start line in source. Remove?
int32_t source_line_delta = 0; // Delta from previous source line
// Field 4
uint32_t source_col = 0; // Start column in source. Remove?
int32_t source_col_delta = 0; // Delta from previous source column
bool has_name = false; // If true, field 5 will be valid.
// Field 5
size_t name = 0; // Index into names list
Segment() = default;
// Explicit constructor, mostly used for testing.
Segment(std::pair<uint32_t, int32_t> generated_col_p,
std::pair<bool, size_t> source_p,
std::pair<uint32_t, int32_t> source_line_p,
std::pair<uint32_t, int32_t> source_col_p,
std::pair<bool, size_t> name_p) {
std::tie(generated_col, generated_col_delta) = generated_col_p;
std::tie(has_source, source) = source_p;
std::tie(source_line, source_line_delta) = source_line_p;
std::tie(source_col, source_col_delta) = source_col_p;
std::tie(has_name, name) = name_p;
}
};
struct SegmentGroup {
uint32_t generated_line; // Line in the generated file for all segments
std::vector<Segment> segments;
};
// Top level fields
std::string file; // Generated code filename; optional
std::string source_root; // Prepended to entries in sources list; optional
std::vector<std::string> sources; // List of sources use by mappings
std::vector<std::string> sources_content; // Not supported yet.
std::vector<std::string> names; // Not supported yet.
std::vector<SegmentGroup> segment_groups;
SourceMap(std::string file_, std::string source_root_)
: file(file_), source_root(source_root_) {}
void Dump();
bool Validate(bool fatal = false) const;
};
class SourceMapGenerator {
public:
struct SourceLocation {
uint32_t line;
uint32_t col;
};
SourceMapGenerator(std::string file_, std::string source_root_)
: map(file_, source_root_) {}
// Returns true if the mapping is valid, and if so adds to the list.
bool AddMapping(SourceLocation generated, SourceLocation original,
std::string source);
void DumpMappings() { DumpRawMappings(); }
const SourceMap& GetMap() {
CompressMappings();
return map;
};
std::string SerializeMappings();
public:
// TODO: make this private? But need to find a way to use it in tests.
struct SourceMapping {
SourceLocation original;
SourceLocation generated; // Use binary location?
size_t source_idx; // pointer to src?
// We don't use the 'name' field currently.
bool operator<(const SourceMapping& other) const;
bool operator==(const SourceMapping& other) const;
void Dump() const;
};
private:
void CompressMappings();
bool map_prepared = false; // Is the map compressed and ready for export?
SourceMap map;
std::map<std::string, size_t> sources_map;
std::vector<SourceMapping> mappings;
// TODO:
// Parse from file
// Dump to file
// Lookup mapping bidirectionally (future?)
// Future? Support modifiable mappings (e.g. a way to pin source location to
// IR) Add source location without generated mapping (with e.g. an opaque
// handle/token) Apply generated-location to each handle
void DumpRawMappings();
};
#endif // WABT_SOURCE_MAPS_H