11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#if !V8_ENABLE_WEBASSEMBLY
61cb0ef41Sopenharmony_ci#error This header should only be included if WebAssembly is enabled.
71cb0ef41Sopenharmony_ci#endif  // !V8_ENABLE_WEBASSEMBLY
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#ifndef V8_WASM_WASM_MODULE_SOURCEMAP_H_
101cb0ef41Sopenharmony_ci#define V8_WASM_WASM_MODULE_SOURCEMAP_H_
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include <string>
131cb0ef41Sopenharmony_ci#include <vector>
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci#include "include/v8-local-handle.h"
161cb0ef41Sopenharmony_ci#include "src/base/macros.h"
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_cinamespace v8 {
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ciclass String;
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_cinamespace internal {
231cb0ef41Sopenharmony_cinamespace wasm {
241cb0ef41Sopenharmony_ci// The class is for decoding and managing source map generated by a WebAssembly
251cb0ef41Sopenharmony_ci// toolchain (e.g. Emscripten). This implementation mostly complies with the
261cb0ef41Sopenharmony_ci// specification (https://sourcemaps.info/spec.html), with the following
271cb0ef41Sopenharmony_ci// accommodations:
281cb0ef41Sopenharmony_ci// 1. "names" field is an empty array in current source maps of Wasm, hence it
291cb0ef41Sopenharmony_ci// is not handled;
301cb0ef41Sopenharmony_ci// 2. The semicolons divides "mappings" field into groups, each of which
311cb0ef41Sopenharmony_ci// represents a line in the generated code. As *.wasm is in binary format, there
321cb0ef41Sopenharmony_ci// is one "line" of generated code, and ";" is treated as illegal symbol in
331cb0ef41Sopenharmony_ci// "mappings".
341cb0ef41Sopenharmony_ci// 3. Though each comma-separated section may contains 1, 4 or 5 fields, we only
351cb0ef41Sopenharmony_ci// consider "mappings" with 4 fields, i.e. start line of generated code, index
361cb0ef41Sopenharmony_ci// into "sources" fields, start line of source code and start column of source
371cb0ef41Sopenharmony_ci// code.
381cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE WasmModuleSourceMap {
391cb0ef41Sopenharmony_ci public:
401cb0ef41Sopenharmony_ci  WasmModuleSourceMap(v8::Isolate* v8_isolate,
411cb0ef41Sopenharmony_ci                      v8::Local<v8::String> src_map_str);
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  // Member valid_ is true only if the source map complies with specification
441cb0ef41Sopenharmony_ci  // and can be correctly decoded.
451cb0ef41Sopenharmony_ci  bool IsValid() const { return valid_; }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  // Given a function located at [start, end) in Wasm Module, this function
481cb0ef41Sopenharmony_ci  // checks if this function has its corresponding source code.
491cb0ef41Sopenharmony_ci  bool HasSource(size_t start, size_t end) const;
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  // Given a function's base address start and an address addr within, this
521cb0ef41Sopenharmony_ci  // function checks if the address can be mapped to an offset in this function.
531cb0ef41Sopenharmony_ci  // For example, we have the following memory layout for Wasm functions, foo
541cb0ef41Sopenharmony_ci  // and bar, and O1, O2, O3 and O4 are the decoded offsets of source map:
551cb0ef41Sopenharmony_ci  //
561cb0ef41Sopenharmony_ci  // O1 --- O2 ----- O3 ----- O4
571cb0ef41Sopenharmony_ci  // --->|<-foo->|<--bar->|<-----
581cb0ef41Sopenharmony_ci  // --------------A-------------
591cb0ef41Sopenharmony_ci  //
601cb0ef41Sopenharmony_ci  // Address A of function bar should be mapped to its nearest lower offset, O2.
611cb0ef41Sopenharmony_ci  // However, O2 is an address of function foo, thus, this mapping is treated as
621cb0ef41Sopenharmony_ci  // invalid.
631cb0ef41Sopenharmony_ci  bool HasValidEntry(size_t start, size_t addr) const;
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci  // This function is responsible for looking up an offset's corresponding line
661cb0ef41Sopenharmony_ci  // number in source file. It should only be called when current function is
671cb0ef41Sopenharmony_ci  // checked with IsValid, HasSource and HasValidEntry.
681cb0ef41Sopenharmony_ci  size_t GetSourceLine(size_t wasm_offset) const;
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  // This function is responsible for looking up an offset's corresponding
711cb0ef41Sopenharmony_ci  // source file name. It should only be called when current function is checked
721cb0ef41Sopenharmony_ci  // with IsValid, HasSource and HasValidEntry.
731cb0ef41Sopenharmony_ci  std::string GetFilename(size_t wasm_offset) const;
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci private:
761cb0ef41Sopenharmony_ci  std::vector<size_t> offsets;
771cb0ef41Sopenharmony_ci  std::vector<std::string> filenames;
781cb0ef41Sopenharmony_ci  std::vector<size_t> file_idxs;
791cb0ef41Sopenharmony_ci  std::vector<size_t> source_row;
801cb0ef41Sopenharmony_ci  // As column number in source file is always 0 in source map generated by
811cb0ef41Sopenharmony_ci  // WebAssembly toolchain, we will not store this value.
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  bool valid_ = false;
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  bool DecodeMapping(const std::string& s);
861cb0ef41Sopenharmony_ci};
871cb0ef41Sopenharmony_ci}  // namespace wasm
881cb0ef41Sopenharmony_ci}  // namespace internal
891cb0ef41Sopenharmony_ci}  // namespace v8
901cb0ef41Sopenharmony_ci#endif  // V8_WASM_WASM_MODULE_SOURCEMAP_H_
91