LCOV - code coverage report
Current view: top level - src/wasm - wasm-module.h (source / functions) Hit Total Coverage
Test: app.info Lines: 30 30 100.0 %
Date: 2019-01-20 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // Copyright 2015 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             : #ifndef V8_WASM_WASM_MODULE_H_
       6             : #define V8_WASM_WASM_MODULE_H_
       7             : 
       8             : #include <memory>
       9             : 
      10             : #include "src/globals.h"
      11             : #include "src/handles.h"
      12             : #include "src/vector.h"
      13             : #include "src/wasm/signature-map.h"
      14             : #include "src/wasm/wasm-constants.h"
      15             : #include "src/wasm/wasm-opcodes.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : 
      20             : class WasmDebugInfo;
      21             : class WasmModuleObject;
      22             : 
      23             : namespace wasm {
      24             : 
      25             : using WasmName = Vector<const char>;
      26             : 
      27             : class ErrorThrower;
      28             : 
      29             : // Reference to a string in the wire bytes.
      30             : class WireBytesRef {
      31             :  public:
      32             :   WireBytesRef() : WireBytesRef(0, 0) {}
      33             :   WireBytesRef(uint32_t offset, uint32_t length)
      34     5778716 :       : offset_(offset), length_(length) {
      35             :     DCHECK_IMPLIES(offset_ == 0, length_ == 0);
      36             :     DCHECK_LE(offset_, offset_ + length_);  // no uint32_t overflow.
      37             :   }
      38             : 
      39          90 :   uint32_t offset() const { return offset_; }
      40             :   uint32_t length() const { return length_; }
      41     1919906 :   uint32_t end_offset() const { return offset_ + length_; }
      42             :   bool is_empty() const { return length_ == 0; }
      43             :   bool is_set() const { return offset_ != 0; }
      44             : 
      45             :  private:
      46             :   uint32_t offset_;
      47             :   uint32_t length_;
      48             : };
      49             : 
      50             : // Static representation of a wasm function.
      51             : struct WasmFunction {
      52             :   FunctionSig* sig;      // signature of the function.
      53             :   uint32_t func_index;   // index into the function table.
      54             :   uint32_t sig_index;    // index into the signature table.
      55             :   WireBytesRef code;     // code of this function.
      56             :   bool imported;
      57             :   bool exported;
      58             : };
      59             : 
      60             : // Static representation of a wasm global variable.
      61             : struct WasmGlobal {
      62             :   ValueType type;     // type of the global.
      63             :   bool mutability;    // {true} if mutable.
      64             :   WasmInitExpr init;  // the initialization expression of the global.
      65             :   union {
      66             :     uint32_t index;   // index of imported mutable global.
      67             :     uint32_t offset;  // offset into global memory (if not imported & mutable).
      68             :   };
      69             :   bool imported;  // true if imported.
      70             :   bool exported;  // true if exported.
      71             : };
      72             : 
      73             : // Note: An exception signature only uses the params portion of a
      74             : // function signature.
      75             : typedef FunctionSig WasmExceptionSig;
      76             : 
      77             : // Static representation of a wasm exception type.
      78             : struct WasmException {
      79         582 :   explicit WasmException(const WasmExceptionSig* sig) : sig(sig) {}
      80         685 :   FunctionSig* ToFunctionSig() const { return const_cast<FunctionSig*>(sig); }
      81             : 
      82             :   const WasmExceptionSig* sig;  // type signature of the exception.
      83             : };
      84             : 
      85             : // Static representation of a wasm data segment.
      86             : struct WasmDataSegment {
      87             :   // Construct an active segment.
      88             :   explicit WasmDataSegment(WasmInitExpr dest_addr)
      89        3808 :       : dest_addr(dest_addr), active(true) {}
      90             : 
      91             :   // Construct a passive segment, which has no dest_addr.
      92          64 :   WasmDataSegment() : active(false) {}
      93             : 
      94             :   WasmInitExpr dest_addr;  // destination memory address of the data.
      95             :   WireBytesRef source;     // start offset in the module bytes.
      96             :   bool active = true;      // true if copied automatically during instantiation.
      97             : };
      98             : 
      99             : // Static representation of a wasm indirect call table.
     100             : struct WasmTable {
     101          26 :   MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmTable);
     102             :   ValueType type = kWasmStmt;     // table type.
     103             :   uint32_t initial_size = 0;      // initial table size.
     104             :   uint32_t maximum_size = 0;      // maximum table size.
     105             :   bool has_maximum_size = false;  // true if there is a maximum size.
     106             :   // TODO(titzer): Move this to WasmInstance. Needed by interpreter only.
     107             :   std::vector<int32_t> values;  // function table, -1 indicating invalid.
     108             :   bool imported = false;        // true if imported.
     109             :   bool exported = false;        // true if exported.
     110             : };
     111             : 
     112             : // Static representation of wasm element segment (table initializer).
     113             : struct WasmElemSegment {
     114        1676 :   MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(WasmElemSegment);
     115             : 
     116             :   // Construct an active segment.
     117             :   WasmElemSegment(uint32_t table_index, WasmInitExpr offset)
     118        5104 :       : table_index(table_index), offset(offset), active(true) {}
     119             : 
     120             :   // Construct a passive segment, which has no table index or offset.
     121          72 :   WasmElemSegment() : table_index(0), active(false) {}
     122             : 
     123             :   uint32_t table_index;
     124             :   WasmInitExpr offset;
     125             :   std::vector<uint32_t> entries;
     126             :   bool active;  // true if copied automatically during instantiation.
     127             : };
     128             : 
     129             : // Static representation of a wasm import.
     130             : struct WasmImport {
     131             :   WireBytesRef module_name;  // module name.
     132             :   WireBytesRef field_name;   // import name.
     133             :   ImportExportKindCode kind;  // kind of the import.
     134             :   uint32_t index;            // index into the respective space.
     135             : };
     136             : 
     137             : // Static representation of a wasm export.
     138             : struct WasmExport {
     139             :   WireBytesRef name;      // exported name.
     140             :   ImportExportKindCode kind;  // kind of the export.
     141             :   uint32_t index;         // index into the respective space.
     142             : };
     143             : 
     144             : enum ModuleOrigin : uint8_t { kWasmOrigin, kAsmJsOrigin };
     145             : 
     146             : #define SELECT_WASM_COUNTER(counters, origin, prefix, suffix)     \
     147             :   ((origin) == kWasmOrigin ? (counters)->prefix##_wasm_##suffix() \
     148             :                            : (counters)->prefix##_asm_##suffix())
     149             : 
     150             : struct ModuleWireBytes;
     151             : 
     152             : // Static representation of a module.
     153     6736784 : struct V8_EXPORT_PRIVATE WasmModule {
     154             :   MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(WasmModule);
     155             : 
     156             :   std::unique_ptr<Zone> signature_zone;
     157             :   uint32_t initial_pages = 0;      // initial size of the memory in 64k pages
     158             :   uint32_t maximum_pages = 0;      // maximum size of the memory in 64k pages
     159             :   bool has_shared_memory = false;  // true if memory is a SharedArrayBuffer
     160             :   bool has_maximum_pages = false;  // true if there is a maximum memory size
     161             :   bool has_memory = false;         // true if the memory was defined or imported
     162             :   bool mem_export = false;         // true if the memory is exported
     163             :   int start_function_index = -1;   // start function, >= 0 if any
     164             : 
     165             :   std::vector<WasmGlobal> globals;
     166             :   // Size of the buffer required for all globals that are not imported and
     167             :   // mutable.
     168             :   uint32_t untagged_globals_buffer_size = 0;
     169             :   uint32_t tagged_globals_buffer_size = 0;
     170             :   uint32_t num_imported_mutable_globals = 0;
     171             :   uint32_t num_imported_functions = 0;
     172             :   uint32_t num_declared_functions = 0;  // excluding imported
     173             :   uint32_t num_exported_functions = 0;
     174             :   uint32_t num_declared_data_segments = 0;  // From the DataCount section.
     175             :   WireBytesRef name = {0, 0};
     176             :   std::vector<FunctionSig*> signatures;  // by signature index
     177             :   std::vector<uint32_t> signature_ids;   // by signature index
     178             :   std::vector<WasmFunction> functions;
     179             :   std::vector<WasmDataSegment> data_segments;
     180             :   std::vector<WasmTable> tables;
     181             :   std::vector<WasmImport> import_table;
     182             :   std::vector<WasmExport> export_table;
     183             :   std::vector<WasmException> exceptions;
     184             :   std::vector<WasmElemSegment> elem_segments;
     185             :   SignatureMap signature_map;  // canonicalizing map for signature indexes.
     186             : 
     187             :   ModuleOrigin origin = kWasmOrigin;  // origin of the module
     188             :   mutable std::unique_ptr<std::unordered_map<uint32_t, WireBytesRef>>
     189             :       function_names;
     190             :   std::string source_map_url;
     191             : 
     192             :   explicit WasmModule(std::unique_ptr<Zone> signature_zone = nullptr);
     193             : 
     194             :   WireBytesRef LookupFunctionName(const ModuleWireBytes& wire_bytes,
     195             :                                   uint32_t function_index) const;
     196             :   void AddFunctionNameForTesting(int function_index, WireBytesRef name);
     197             : };
     198             : 
     199             : size_t EstimateStoredSize(const WasmModule* module);
     200             : 
     201             : // Interface to the storage (wire bytes) of a wasm module.
     202             : // It is illegal for anyone receiving a ModuleWireBytes to store pointers based
     203             : // on module_bytes, as this storage is only guaranteed to be alive as long as
     204             : // this struct is alive.
     205             : struct V8_EXPORT_PRIVATE ModuleWireBytes {
     206             :   explicit ModuleWireBytes(Vector<const byte> module_bytes)
     207       26011 :       : module_bytes_(module_bytes) {}
     208             :   ModuleWireBytes(const byte* start, const byte* end)
     209      469462 :       : module_bytes_(start, static_cast<int>(end - start)) {
     210             :     DCHECK_GE(kMaxInt, end - start);
     211             :   }
     212             : 
     213             :   // Get a string stored in the module bytes representing a name.
     214             :   WasmName GetNameOrNull(WireBytesRef ref) const;
     215             : 
     216             :   // Get a string stored in the module bytes representing a function name.
     217             :   WasmName GetNameOrNull(const WasmFunction* function,
     218             :                          const WasmModule* module) const;
     219             : 
     220             :   // Checks the given offset range is contained within the module bytes.
     221             :   bool BoundsCheck(uint32_t offset, uint32_t length) const {
     222         398 :     uint32_t size = static_cast<uint32_t>(module_bytes_.length());
     223         398 :     return offset <= size && length <= size - offset;
     224             :   }
     225             : 
     226             :   Vector<const byte> GetFunctionBytes(const WasmFunction* function) const {
     227             :     return module_bytes_.SubVector(function->code.offset(),
     228         199 :                                    function->code.end_offset());
     229             :   }
     230             : 
     231      160368 :   Vector<const byte> module_bytes() const { return module_bytes_; }
     232      298248 :   const byte* start() const { return module_bytes_.start(); }
     233             :   const byte* end() const { return module_bytes_.end(); }
     234      314073 :   size_t length() const { return module_bytes_.length(); }
     235             : 
     236             :  private:
     237             :   Vector<const byte> module_bytes_;
     238             : };
     239             : 
     240             : // A helper for printing out the names of functions.
     241             : struct WasmFunctionName {
     242             :   WasmFunctionName(const WasmFunction* function, WasmName name)
     243      151734 :       : function_(function), name_(name) {}
     244             : 
     245             :   const WasmFunction* function_;
     246             :   const WasmName name_;
     247             : };
     248             : 
     249             : std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name);
     250             : 
     251             : // Get the debug info associated with the given wasm object.
     252             : // If no debug info exists yet, it is created automatically.
     253             : Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm);
     254             : 
     255             : V8_EXPORT_PRIVATE MaybeHandle<WasmModuleObject> CreateModuleObjectFromBytes(
     256             :     Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower,
     257             :     ModuleOrigin origin, Handle<Script> asm_js_script,
     258             :     Vector<const byte> asm_offset_table);
     259             : 
     260             : V8_EXPORT_PRIVATE bool IsWasmCodegenAllowed(Isolate* isolate,
     261             :                                             Handle<Context> context);
     262             : 
     263             : V8_EXPORT_PRIVATE Handle<JSArray> GetImports(Isolate* isolate,
     264             :                                              Handle<WasmModuleObject> module);
     265             : V8_EXPORT_PRIVATE Handle<JSArray> GetExports(Isolate* isolate,
     266             :                                              Handle<WasmModuleObject> module);
     267             : V8_EXPORT_PRIVATE Handle<JSArray> GetCustomSections(
     268             :     Isolate* isolate, Handle<WasmModuleObject> module, Handle<String> name,
     269             :     ErrorThrower* thrower);
     270             : 
     271             : // Decode local variable names from the names section. Return FixedArray of
     272             : // FixedArray of <undefined|String>. The outer fixed array is indexed by the
     273             : // function index, the inner one by the local index.
     274             : Handle<FixedArray> DecodeLocalNames(Isolate*, Handle<WasmModuleObject>);
     275             : 
     276             : // TruncatedUserString makes it easy to output names up to a certain length, and
     277             : // output a truncation followed by '...' if they exceed a limit.
     278             : // Use like this:
     279             : //   TruncatedUserString<> name (pc, len);
     280             : //   printf("... %.*s ...", name.length(), name.start())
     281             : template <int kMaxLen = 50>
     282             : class TruncatedUserString {
     283             :   static_assert(kMaxLen >= 4, "minimum length is 4 (length of '...' plus one)");
     284             : 
     285             :  public:
     286             :   template <typename T>
     287             :   explicit TruncatedUserString(Vector<T> name)
     288           9 :       : TruncatedUserString(name.start(), name.length()) {}
     289             : 
     290             :   TruncatedUserString(const byte* start, size_t len)
     291         369 :       : TruncatedUserString(reinterpret_cast<const char*>(start), len) {}
     292             : 
     293         378 :   TruncatedUserString(const char* start, size_t len)
     294         756 :       : start_(start), length_(std::min(kMaxLen, static_cast<int>(len))) {
     295         378 :     if (len > static_cast<size_t>(kMaxLen)) {
     296           9 :       memcpy(buffer_, start, kMaxLen - 3);
     297           9 :       memset(buffer_ + kMaxLen - 3, '.', 3);
     298           9 :       start_ = buffer_;
     299             :     }
     300         378 :   }
     301             : 
     302             :   const char* start() const { return start_; }
     303             : 
     304             :   int length() const { return length_; }
     305             : 
     306             :  private:
     307             :   const char* start_;
     308             :   const int length_;
     309             :   char buffer_[kMaxLen];
     310             : };
     311             : 
     312             : }  // namespace wasm
     313             : }  // namespace internal
     314             : }  // namespace v8
     315             : 
     316             : #endif  // V8_WASM_WASM_MODULE_H_

Generated by: LCOV version 1.10