1 // Copyright 2019 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #if !V8_ENABLE_WEBASSEMBLY 6 #error This header should only be included if WebAssembly is enabled. 7 #endif // !V8_ENABLE_WEBASSEMBLY 8 9 #ifndef V8_WASM_WASM_MODULE_SOURCEMAP_H_ 10 #define V8_WASM_WASM_MODULE_SOURCEMAP_H_ 11 12 #include <string> 13 #include <vector> 14 15 #include "include/v8-local-handle.h" 16 #include "src/base/macros.h" 17 18 namespace v8 { 19 20 class String; 21 22 namespace internal { 23 namespace wasm { 24 // The class is for decoding and managing source map generated by a WebAssembly 25 // toolchain (e.g. Emscripten). This implementation mostly complies with the 26 // specification (https://sourcemaps.info/spec.html), with the following 27 // accommodations: 28 // 1. "names" field is an empty array in current source maps of Wasm, hence it 29 // is not handled; 30 // 2. The semicolons divides "mappings" field into groups, each of which 31 // represents a line in the generated code. As *.wasm is in binary format, there 32 // is one "line" of generated code, and ";" is treated as illegal symbol in 33 // "mappings". 34 // 3. Though each comma-separated section may contains 1, 4 or 5 fields, we only 35 // consider "mappings" with 4 fields, i.e. start line of generated code, index 36 // into "sources" fields, start line of source code and start column of source 37 // code. 38 class V8_EXPORT_PRIVATE WasmModuleSourceMap { 39 public: 40 WasmModuleSourceMap(v8::Isolate* v8_isolate, 41 v8::Local<v8::String> src_map_str); 42 43 // Member valid_ is true only if the source map complies with specification 44 // and can be correctly decoded. IsValid()45 bool IsValid() const { return valid_; } 46 47 // Given a function located at [start, end) in Wasm Module, this function 48 // checks if this function has its corresponding source code. 49 bool HasSource(size_t start, size_t end) const; 50 51 // Given a function's base address start and an address addr within, this 52 // function checks if the address can be mapped to an offset in this function. 53 // For example, we have the following memory layout for Wasm functions, foo 54 // and bar, and O1, O2, O3 and O4 are the decoded offsets of source map: 55 // 56 // O1 --- O2 ----- O3 ----- O4 57 // --->|<-foo->|<--bar->|<----- 58 // --------------A------------- 59 // 60 // Address A of function bar should be mapped to its nearest lower offset, O2. 61 // However, O2 is an address of function foo, thus, this mapping is treated as 62 // invalid. 63 bool HasValidEntry(size_t start, size_t addr) const; 64 65 // This function is responsible for looking up an offset's corresponding line 66 // number in source file. It should only be called when current function is 67 // checked with IsValid, HasSource and HasValidEntry. 68 size_t GetSourceLine(size_t wasm_offset) const; 69 70 // This function is responsible for looking up an offset's corresponding 71 // source file name. It should only be called when current function is checked 72 // with IsValid, HasSource and HasValidEntry. 73 std::string GetFilename(size_t wasm_offset) const; 74 75 private: 76 std::vector<size_t> offsets; 77 std::vector<std::string> filenames; 78 std::vector<size_t> file_idxs; 79 std::vector<size_t> source_row; 80 // As column number in source file is always 0 in source map generated by 81 // WebAssembly toolchain, we will not store this value. 82 83 bool valid_ = false; 84 85 bool DecodeMapping(const std::string& s); 86 }; 87 } // namespace wasm 88 } // namespace internal 89 } // namespace v8 90 #endif // V8_WASM_WASM_MODULE_SOURCEMAP_H_ 91