LCOV - code coverage report
Current view: top level - src/wasm - wasm-result.h (source / functions) Hit Total Coverage
Test: app.info Lines: 21 21 100.0 %
Date: 2019-04-17 Functions: 7 7 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_RESULT_H_
       6             : #define V8_WASM_WASM_RESULT_H_
       7             : 
       8             : #include <cstdarg>
       9             : #include <memory>
      10             : 
      11             : #include "src/base/compiler-specific.h"
      12             : #include "src/base/macros.h"
      13             : #include "src/base/platform/platform.h"
      14             : 
      15             : #include "src/globals.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : 
      20             : class Isolate;
      21             : template <typename T>
      22             : class Handle;
      23             : 
      24             : namespace wasm {
      25             : 
      26    26866357 : class V8_EXPORT_PRIVATE WasmError {
      27             :  public:
      28    12904241 :   WasmError() = default;
      29             : 
      30             :   WasmError(uint32_t offset, std::string message)
      31      218605 :       : offset_(offset), message_(std::move(message)) {
      32             :     // The error message must not be empty, otherwise {empty()} would be true.
      33             :     DCHECK(!message_.empty());
      34             :   }
      35             : 
      36             :   PRINTF_FORMAT(3, 4)
      37         576 :   WasmError(uint32_t offset, const char* format, ...) : offset_(offset) {
      38             :     va_list args;
      39         576 :     va_start(args, format);
      40        1152 :     message_ = FormatError(format, args);
      41         576 :     va_end(args);
      42             :     // The error message must not be empty, otherwise {empty()} would be true.
      43             :     DCHECK(!message_.empty());
      44         576 :   }
      45             : 
      46             :   bool empty() const { return message_.empty(); }
      47             :   bool has_error() const { return !message_.empty(); }
      48             : 
      49             :   uint32_t offset() const { return offset_; }
      50             :   const std::string& message() const& { return message_; }
      51             :   std::string&& message() && { return std::move(message_); }
      52             : 
      53             :  protected:
      54             :   static std::string FormatError(const char* format, va_list args);
      55             : 
      56             :  private:
      57             :   uint32_t offset_ = 0;
      58             :   std::string message_;
      59             : };
      60             : 
      61             : // Either a result of type T, or a WasmError.
      62             : template <typename T>
      63     7757248 : class Result {
      64             :  public:
      65      145476 :   Result() = default;
      66             : 
      67             :   template <typename S>
      68      752760 :   explicit Result(S&& value) : value_(std::forward<S>(value)) {}
      69             : 
      70             :   template <typename S>
      71        3083 :   Result(Result<S>&& other) V8_NOEXCEPT : value_(std::move(other.value_)),
      72     2255819 :                                           error_(std::move(other.error_)) {}
      73             : 
      74       43049 :   explicit Result(WasmError error) : error_(std::move(error)) {}
      75             : 
      76             :   template <typename S>
      77        2203 :   Result& operator=(Result<S>&& other) V8_NOEXCEPT {
      78      145476 :     value_ = std::move(other.value_);
      79             :     error_ = std::move(other.error_);
      80        2203 :     return *this;
      81             :   }
      82             : 
      83             :   bool ok() const { return error_.empty(); }
      84             :   bool failed() const { return error_.has_error(); }
      85             :   const WasmError& error() const& { return error_; }
      86             :   WasmError&& error() && { return std::move(error_); }
      87             : 
      88             :   // Accessor for the value. Returns const reference if {this} is l-value or
      89             :   // const, and returns r-value reference if {this} is r-value. This allows to
      90             :   // extract non-copyable values like {std::unique_ptr} by using
      91             :   // {std::move(result).value()}.
      92             :   const T& value() const & {
      93             :     DCHECK(ok());
      94             :     return value_;
      95             :   }
      96             :   T&& value() && {
      97             :     DCHECK(ok());
      98             :     return std::move(value_);
      99             :   }
     100             : 
     101             :  private:
     102             :   template <typename S>
     103             :   friend class Result;
     104             : 
     105             :   T value_ = T{};
     106             :   WasmError error_;
     107             : 
     108             :   DISALLOW_COPY_AND_ASSIGN(Result);
     109             : };
     110             : 
     111             : // A helper for generating error messages that bubble up to JS exceptions.
     112             : class V8_EXPORT_PRIVATE ErrorThrower {
     113             :  public:
     114             :   ErrorThrower(Isolate* isolate, const char* context)
     115    52271538 :       : isolate_(isolate), context_(context) {}
     116             :   // Explicitly allow move-construction. Disallow copy (below).
     117             :   ErrorThrower(ErrorThrower&& other) V8_NOEXCEPT;
     118             :   ~ErrorThrower();
     119             : 
     120             :   PRINTF_FORMAT(2, 3) void TypeError(const char* fmt, ...);
     121             :   PRINTF_FORMAT(2, 3) void RangeError(const char* fmt, ...);
     122             :   PRINTF_FORMAT(2, 3) void CompileError(const char* fmt, ...);
     123             :   PRINTF_FORMAT(2, 3) void LinkError(const char* fmt, ...);
     124             :   PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...);
     125             : 
     126             :   void CompileFailed(const WasmError& error) {
     127             :     DCHECK(error.has_error());
     128        9303 :     CompileError("%s @+%u", error.message().c_str(), error.offset());
     129             :   }
     130             : 
     131             :   // Create and return exception object.
     132             :   V8_WARN_UNUSED_RESULT Handle<Object> Reify();
     133             : 
     134             :   // Reset any error which was set on this thrower.
     135             :   void Reset();
     136             : 
     137          60 :   bool error() const { return error_type_ != kNone; }
     138         192 :   bool wasm_error() { return error_type_ >= kFirstWasmError; }
     139             :   const char* error_msg() { return error_msg_.c_str(); }
     140             : 
     141             :   Isolate* isolate() const { return isolate_; }
     142             : 
     143             :  private:
     144             :   enum ErrorType {
     145             :     kNone,
     146             :     // General errors.
     147             :     kTypeError,
     148             :     kRangeError,
     149             :     // Wasm errors.
     150             :     kCompileError,
     151             :     kLinkError,
     152             :     kRuntimeError,
     153             : 
     154             :     // Marker.
     155             :     kFirstWasmError = kCompileError
     156             :   };
     157             : 
     158             :   void Format(ErrorType error_type_, const char* fmt, va_list);
     159             : 
     160             :   Isolate* isolate_;
     161             :   const char* context_;
     162             :   ErrorType error_type_ = kNone;
     163             :   std::string error_msg_;
     164             : 
     165             :   // ErrorThrower should always be stack-allocated, since it constitutes a scope
     166             :   // (things happen in the destructor).
     167             :   DISALLOW_NEW_AND_DELETE()
     168             :   DISALLOW_COPY_AND_ASSIGN(ErrorThrower);
     169             : };
     170             : 
     171             : // Use {nullptr_t} as data value to indicate that this only stores the error,
     172             : // but no result value (the only valid value is {nullptr}).
     173             : // [Storing {void} would require template specialization.]
     174             : using VoidResult = Result<std::nullptr_t>;
     175             : 
     176             : }  // namespace wasm
     177             : }  // namespace internal
     178             : }  // namespace v8
     179             : 
     180             : #endif  // V8_WASM_WASM_RESULT_H_

Generated by: LCOV version 1.10