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

Generated by: LCOV version 1.10