LCOV - code coverage report
Current view: top level - src/wasm - wasm-module.h (source / functions) Hit Total Coverage
Test: app.info Lines: 37 38 97.4 %
Date: 2017-10-20 Functions: 5 5 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_MODULE_H_
       6             : #define V8_WASM_MODULE_H_
       7             : 
       8             : #include <memory>
       9             : 
      10             : #include "src/debug/debug-interface.h"
      11             : #include "src/globals.h"
      12             : #include "src/handles.h"
      13             : #include "src/managed.h"
      14             : #include "src/parsing/preparse-data.h"
      15             : 
      16             : #include "src/wasm/decoder.h"
      17             : #include "src/wasm/signature-map.h"
      18             : #include "src/wasm/wasm-opcodes.h"
      19             : 
      20             : namespace v8 {
      21             : namespace internal {
      22             : 
      23             : class WasmCompiledModule;
      24             : class WasmDebugInfo;
      25             : class WasmModuleObject;
      26             : class WasmInstanceObject;
      27             : class WasmTableObject;
      28             : class WasmMemoryObject;
      29             : 
      30             : namespace compiler {
      31             : class CallDescriptor;
      32             : }
      33             : 
      34             : namespace wasm {
      35             : class ErrorThrower;
      36             : 
      37             : enum WasmExternalKind {
      38             :   kExternalFunction = 0,
      39             :   kExternalTable = 1,
      40             :   kExternalMemory = 2,
      41             :   kExternalGlobal = 3
      42             : };
      43             : 
      44             : // Static representation of a wasm function.
      45             : struct WasmFunction {
      46             :   FunctionSig* sig;      // signature of the function.
      47             :   uint32_t func_index;   // index into the function table.
      48             :   uint32_t sig_index;    // index into the signature table.
      49             :   WireBytesRef name;     // function name, if any.
      50             :   WireBytesRef code;     // code of this function.
      51             :   bool imported;
      52             :   bool exported;
      53             : };
      54             : 
      55             : // Static representation of a wasm global variable.
      56             : struct WasmGlobal {
      57             :   ValueType type;        // type of the global.
      58             :   bool mutability;       // {true} if mutable.
      59             :   WasmInitExpr init;     // the initialization expression of the global.
      60             :   uint32_t offset;       // offset into global memory.
      61             :   bool imported;         // true if imported.
      62             :   bool exported;         // true if exported.
      63             : };
      64             : 
      65             : // Note: An exception signature only uses the params portion of a
      66             : // function signature.
      67             : typedef FunctionSig WasmExceptionSig;
      68             : 
      69             : struct WasmException {
      70             :   explicit WasmException(const WasmExceptionSig* sig = &empty_sig_)
      71         150 :       : sig(sig) {}
      72         143 :   FunctionSig* ToFunctionSig() const { return const_cast<FunctionSig*>(sig); }
      73             : 
      74             :   const WasmExceptionSig* sig;  // type signature of the exception.
      75             : 
      76             :   // Used to hold data on runtime exceptions.
      77             :   static constexpr const char* kRuntimeIdStr = "WasmExceptionRuntimeId";
      78             :   static constexpr const char* kRuntimeValuesStr = "WasmExceptionValues";
      79             : 
      80             :  private:
      81             :   static const WasmExceptionSig empty_sig_;
      82             : };
      83             : 
      84             : // Static representation of a wasm data segment.
      85             : struct WasmDataSegment {
      86             :   WasmInitExpr dest_addr;  // destination memory address of the data.
      87             :   WireBytesRef source;     // start offset in the module bytes.
      88             : };
      89             : 
      90             : // Static representation of a wasm indirect call table.
      91             : struct WasmIndirectFunctionTable {
      92           0 :   MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmIndirectFunctionTable);
      93             : 
      94             :   uint32_t initial_size = 0;      // initial table size.
      95             :   uint32_t maximum_size = 0;      // maximum table size.
      96             :   bool has_maximum_size = false;  // true if there is a maximum size.
      97             :   // TODO(titzer): Move this to WasmInstance. Needed by interpreter only.
      98             :   std::vector<int32_t> values;  // function table, -1 indicating invalid.
      99             :   bool imported = false;        // true if imported.
     100             :   bool exported = false;        // true if exported.
     101             : };
     102             : 
     103             : // Static representation of how to initialize a table.
     104             : struct WasmTableInit {
     105          80 :   MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(WasmTableInit);
     106             : 
     107             :   WasmTableInit(uint32_t table_index, WasmInitExpr offset)
     108        1163 :       : table_index(table_index), offset(offset) {}
     109             : 
     110             :   uint32_t table_index;
     111             :   WasmInitExpr offset;
     112             :   std::vector<uint32_t> entries;
     113             : };
     114             : 
     115             : // Static representation of a wasm import.
     116             : struct WasmImport {
     117             :   WireBytesRef module_name;  // module name.
     118             :   WireBytesRef field_name;   // import name.
     119             :   WasmExternalKind kind;     // kind of the import.
     120             :   uint32_t index;            // index into the respective space.
     121             : };
     122             : 
     123             : // Static representation of a wasm export.
     124             : struct WasmExport {
     125             :   WireBytesRef name;      // exported name.
     126             :   WasmExternalKind kind;  // kind of the export.
     127             :   uint32_t index;         // index into the respective space.
     128             : };
     129             : 
     130             : enum ModuleOrigin : uint8_t { kWasmOrigin, kAsmJsOrigin };
     131             : 
     132             : struct ModuleWireBytes;
     133             : 
     134             : // Static representation of a module.
     135     1383368 : struct V8_EXPORT_PRIVATE WasmModule {
     136             :   MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(WasmModule);
     137             : 
     138             :   static const uint32_t kPageSize = 0x10000;    // Page size, 64kb.
     139             :   static const uint32_t kMinMemPages = 1;       // Minimum memory size = 64kb
     140             : 
     141             :   static constexpr int kInvalidExceptionTag = -1;
     142             : 
     143             :   std::unique_ptr<Zone> signature_zone;
     144             :   uint32_t initial_pages = 0;      // initial size of the memory in 64k pages
     145             :   uint32_t maximum_pages = 0;      // maximum size of the memory in 64k pages
     146             :   bool has_shared_memory = false;  // true if memory is a SharedArrayBuffer
     147             :   bool has_maximum_pages = false;  // true if there is a maximum memory size
     148             :   bool has_memory = false;         // true if the memory was defined or imported
     149             :   bool mem_export = false;         // true if the memory is exported
     150             :   int start_function_index = -1;   // start function, >= 0 if any
     151             : 
     152             :   std::vector<WasmGlobal> globals;
     153             :   uint32_t globals_size = 0;
     154             :   uint32_t num_imported_functions = 0;
     155             :   uint32_t num_declared_functions = 0;
     156             :   uint32_t num_exported_functions = 0;
     157             :   WireBytesRef name = {0, 0};
     158             :   // TODO(wasm): Add url here, for spec'ed location information.
     159             :   std::vector<FunctionSig*> signatures;  // by signature index
     160             :   std::vector<uint32_t> signature_ids;   // by signature index
     161             :   std::vector<WasmFunction> functions;
     162             :   std::vector<WasmDataSegment> data_segments;
     163             :   std::vector<WasmIndirectFunctionTable> function_tables;
     164             :   std::vector<WasmImport> import_table;
     165             :   std::vector<WasmExport> export_table;
     166             :   std::vector<WasmException> exceptions;
     167             :   std::vector<WasmTableInit> table_inits;
     168             :   SignatureMap signature_map;  // canonicalizing map for signature indexes.
     169             : 
     170      112506 :   WasmModule() : WasmModule(nullptr) {}
     171             :   WasmModule(std::unique_ptr<Zone> owned);
     172             : 
     173             :   ModuleOrigin origin() const { return origin_; }
     174      309108 :   void set_origin(ModuleOrigin new_value) { origin_ = new_value; }
     175          40 :   bool is_wasm() const { return origin_ == kWasmOrigin; }
     176      196471 :   bool is_asm_js() const { return origin_ == kAsmJsOrigin; }
     177             : 
     178             :  private:
     179             :   // TODO(kschimpf) - Encapsulate more fields.
     180             :   ModuleOrigin origin_ = kWasmOrigin;  // origin of the module
     181             : };
     182             : 
     183             : typedef Managed<WasmModule> WasmModuleWrapper;
     184             : 
     185             : // Interface to the storage (wire bytes) of a wasm module.
     186             : // It is illegal for anyone receiving a ModuleWireBytes to store pointers based
     187             : // on module_bytes, as this storage is only guaranteed to be alive as long as
     188             : // this struct is alive.
     189             : struct V8_EXPORT_PRIVATE ModuleWireBytes {
     190             :   ModuleWireBytes(Vector<const byte> module_bytes)
     191       18727 :       : module_bytes_(module_bytes) {}
     192             :   ModuleWireBytes(const byte* start, const byte* end)
     193      622485 :       : module_bytes_(start, static_cast<int>(end - start)) {
     194             :     DCHECK_GE(kMaxInt, end - start);
     195             :   }
     196             : 
     197             :   // Get a string stored in the module bytes representing a name.
     198       43887 :   WasmName GetName(WireBytesRef ref) const {
     199       43887 :     if (ref.is_empty()) return {"<?>", 3};  // no name.
     200       18284 :     CHECK(BoundsCheck(ref.offset(), ref.length()));
     201             :     return Vector<const char>::cast(
     202       18284 :         module_bytes_.SubVector(ref.offset(), ref.end_offset()));
     203             :   }
     204             : 
     205             :   // Get a string stored in the module bytes representing a function name.
     206             :   WasmName GetName(const WasmFunction* function) const {
     207       43887 :     return GetName(function->name);
     208             :   }
     209             : 
     210             :   // Get a string stored in the module bytes representing a name.
     211      300997 :   WasmName GetNameOrNull(WireBytesRef ref) const {
     212      300997 :     if (!ref.is_set()) return {nullptr, 0};  // no name.
     213        4528 :     CHECK(BoundsCheck(ref.offset(), ref.length()));
     214             :     return Vector<const char>::cast(
     215        4528 :         module_bytes_.SubVector(ref.offset(), ref.end_offset()));
     216             :   }
     217             : 
     218             :   // Get a string stored in the module bytes representing a function name.
     219             :   WasmName GetNameOrNull(const WasmFunction* function) const {
     220      300997 :     return GetNameOrNull(function->name);
     221             :   }
     222             : 
     223             :   // Checks the given offset range is contained within the module bytes.
     224             :   bool BoundsCheck(uint32_t offset, uint32_t length) const {
     225       22812 :     uint32_t size = static_cast<uint32_t>(module_bytes_.length());
     226       22812 :     return offset <= size && length <= size - offset;
     227             :   }
     228             : 
     229             :   Vector<const byte> GetFunctionBytes(const WasmFunction* function) const {
     230             :     return module_bytes_.SubVector(function->code.offset(),
     231          89 :                                    function->code.end_offset());
     232             :   }
     233             : 
     234         200 :   Vector<const byte> module_bytes() const { return module_bytes_; }
     235      778425 :   const byte* start() const { return module_bytes_.start(); }
     236             :   const byte* end() const { return module_bytes_.end(); }
     237     1528417 :   size_t length() const { return module_bytes_.length(); }
     238             : 
     239             :  private:
     240             :   Vector<const byte> module_bytes_;
     241             : };
     242             : 
     243             : // A helper for printing out the names of functions.
     244             : struct WasmFunctionName {
     245             :   WasmFunctionName(const WasmFunction* function, WasmName name)
     246      157373 :       : function_(function), name_(name) {}
     247             : 
     248             :   const WasmFunction* function_;
     249             :   WasmName name_;
     250             : };
     251             : 
     252             : std::ostream& operator<<(std::ostream& os, const WasmFunctionName& name);
     253             : 
     254             : // Get the debug info associated with the given wasm object.
     255             : // If no debug info exists yet, it is created automatically.
     256             : Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm);
     257             : 
     258             : V8_EXPORT_PRIVATE MaybeHandle<WasmModuleObject> CreateModuleObjectFromBytes(
     259             :     Isolate* isolate, const byte* start, const byte* end, ErrorThrower* thrower,
     260             :     ModuleOrigin origin, Handle<Script> asm_js_script,
     261             :     Vector<const byte> asm_offset_table);
     262             : 
     263             : V8_EXPORT_PRIVATE bool IsWasmCodegenAllowed(Isolate* isolate,
     264             :                                             Handle<Context> context);
     265             : 
     266             : V8_EXPORT_PRIVATE Handle<JSArray> GetImports(Isolate* isolate,
     267             :                                              Handle<WasmModuleObject> module);
     268             : V8_EXPORT_PRIVATE Handle<JSArray> GetExports(Isolate* isolate,
     269             :                                              Handle<WasmModuleObject> module);
     270             : V8_EXPORT_PRIVATE Handle<JSArray> GetCustomSections(
     271             :     Isolate* isolate, Handle<WasmModuleObject> module, Handle<String> name,
     272             :     ErrorThrower* thrower);
     273             : 
     274             : // Decode local variable names from the names section. Return FixedArray of
     275             : // FixedArray of <undefined|String>. The outer fixed array is indexed by the
     276             : // function index, the inner one by the local index.
     277             : Handle<FixedArray> DecodeLocalNames(Isolate*, Handle<WasmCompiledModule>);
     278             : 
     279             : // If the target is an export wrapper, return the {WasmFunction*} corresponding
     280             : // to the wrapped wasm function; in all other cases, return nullptr.
     281             : // The returned pointer is owned by the wasm instance target belongs to. The
     282             : // result is alive as long as the instance exists.
     283             : // TODO(titzer): move this to WasmExportedFunction.
     284             : WasmFunction* GetWasmFunctionForExport(Isolate* isolate, Handle<Object> target);
     285             : 
     286             : void UpdateDispatchTables(Isolate* isolate, Handle<FixedArray> dispatch_tables,
     287             :                           int index, WasmFunction* function, Handle<Code> code);
     288             : 
     289             : void UnpackAndRegisterProtectedInstructions(Isolate* isolate,
     290             :                                             Handle<FixedArray> code_table);
     291             : 
     292             : const char* ExternalKindName(WasmExternalKind);
     293             : 
     294             : // TruncatedUserString makes it easy to output names up to a certain length, and
     295             : // output a truncation followed by '...' if they exceed a limit.
     296             : // Use like this:
     297             : //   TruncatedUserString<> name (pc, len);
     298             : //   printf("... %.*s ...", name.length(), name.start())
     299             : template <int kMaxLen = 50>
     300             : class TruncatedUserString {
     301             :   static_assert(kMaxLen >= 4, "minimum length is 4 (length of '...' plus one)");
     302             : 
     303             :  public:
     304             :   template <typename T>
     305             :   explicit TruncatedUserString(Vector<T> name)
     306        5841 :       : TruncatedUserString(name.start(), name.length()) {}
     307             : 
     308             :   TruncatedUserString(const byte* start, size_t len)
     309         400 :       : TruncatedUserString(reinterpret_cast<const char*>(start), len) {}
     310             : 
     311        6241 :   TruncatedUserString(const char* start, size_t len)
     312       12482 :       : start_(start), length_(std::min(kMaxLen, static_cast<int>(len))) {
     313        6241 :     if (len > static_cast<size_t>(kMaxLen)) {
     314          10 :       memcpy(buffer_, start, kMaxLen - 3);
     315          10 :       memset(buffer_ + kMaxLen - 3, '.', 3);
     316          10 :       start_ = buffer_;
     317             :     }
     318        6241 :   }
     319             : 
     320             :   const char* start() const { return start_; }
     321             : 
     322             :   int length() const { return length_; }
     323             : 
     324             :  private:
     325             :   const char* start_;
     326             :   int length_;
     327             :   char buffer_[kMaxLen];
     328             : };
     329             : 
     330             : }  // namespace wasm
     331             : }  // namespace internal
     332             : }  // namespace v8
     333             : 
     334             : #endif  // V8_WASM_MODULE_H_

Generated by: LCOV version 1.10