// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_WASM_WASM_RESULT_H_
#define V8_WASM_WASM_RESULT_H_

#include <cstdarg>
#include <memory>

#include "src/base/compiler-specific.h"
#include "src/base/macros.h"
#include "src/base/platform/platform.h"

#include "src/common/globals.h"

namespace v8 {
namespace internal {

class Isolate;
template <typename T>
class Handle;

namespace wasm {

class V8_EXPORT_PRIVATE WasmError {
 public:
  WasmError() = default;

  WasmError(uint32_t offset, std::string message)
      : offset_(offset), message_(std::move(message)) {
    // The error message must not be empty, otherwise {empty()} would be true.
    DCHECK(!message_.empty());
  }

  PRINTF_FORMAT(3, 4)
  WasmError(uint32_t offset, const char* format, ...) : offset_(offset) {
    va_list args;
    va_start(args, format);
    message_ = FormatError(format, args);
    va_end(args);
    // The error message must not be empty, otherwise {empty()} would be true.
    DCHECK(!message_.empty());
  }

  bool empty() const { return message_.empty(); }
  bool has_error() const { return !message_.empty(); }

  uint32_t offset() const { return offset_; }
  const std::string& message() const& { return message_; }
  std::string&& message() && { return std::move(message_); }

 protected:
  static std::string FormatError(const char* format, va_list args);

 private:
  uint32_t offset_ = 0;
  std::string message_;
};

// Either a result of type T, or a WasmError.
template <typename T>
class Result {
 public:
  Result() = default;
  Result(const Result&) = delete;
  Result& operator=(const Result&) = delete;

  template <typename S>
  explicit Result(S&& value) : value_(std::forward<S>(value)) {}

  template <typename S>
  Result(Result<S>&& other) V8_NOEXCEPT : value_(std::move(other.value_)),
                                          error_(std::move(other.error_)) {}

  explicit Result(WasmError error) : error_(std::move(error)) {}

  template <typename S>
  Result& operator=(Result<S>&& other) V8_NOEXCEPT {
    value_ = std::move(other.value_);
    error_ = std::move(other.error_);
    return *this;
  }

  bool ok() const { return error_.empty(); }
  bool failed() const { return error_.has_error(); }
  const WasmError& error() const& { return error_; }
  WasmError&& error() && { return std::move(error_); }

  // Accessor for the value. Returns const reference if {this} is l-value or
  // const, and returns r-value reference if {this} is r-value. This allows to
  // extract non-copyable values like {std::unique_ptr} by using
  // {std::move(result).value()}.
  const T& value() const & {
    DCHECK(ok());
    return value_;
  }
  T&& value() && {
    DCHECK(ok());
    return std::move(value_);
  }

 private:
  template <typename S>
  friend class Result;

  T value_ = T{};
  WasmError error_;
};

// A helper for generating error messages that bubble up to JS exceptions.
class V8_EXPORT_PRIVATE ErrorThrower {
 public:
  ErrorThrower(Isolate* isolate, const char* context)
      : isolate_(isolate), context_(context) {}
  // Explicitly allow move-construction. Disallow copy.
  ErrorThrower(ErrorThrower&& other) V8_NOEXCEPT;
  ErrorThrower(const ErrorThrower&) = delete;
  ErrorThrower& operator=(const ErrorThrower&) = delete;
  ~ErrorThrower();

  PRINTF_FORMAT(2, 3) void TypeError(const char* fmt, ...);
  PRINTF_FORMAT(2, 3) void RangeError(const char* fmt, ...);
  PRINTF_FORMAT(2, 3) void CompileError(const char* fmt, ...);
  PRINTF_FORMAT(2, 3) void LinkError(const char* fmt, ...);
  PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...);

  void CompileFailed(const WasmError& error) {
    DCHECK(error.has_error());
    CompileError("%s @+%u", error.message().c_str(), error.offset());
  }

  // Create and return exception object.
  V8_WARN_UNUSED_RESULT Handle<Object> Reify();

  // Reset any error which was set on this thrower.
  void Reset();

  bool error() const { return error_type_ != kNone; }
  bool wasm_error() { return error_type_ >= kFirstWasmError; }
  const char* error_msg() { return error_msg_.c_str(); }

  Isolate* isolate() const { return isolate_; }

 private:
  enum ErrorType {
    kNone,
    // General errors.
    kTypeError,
    kRangeError,
    // Wasm errors.
    kCompileError,
    kLinkError,
    kRuntimeError,

    // Marker.
    kFirstWasmError = kCompileError
  };

  void Format(ErrorType error_type_, const char* fmt, va_list);

  Isolate* isolate_;
  const char* context_;
  ErrorType error_type_ = kNone;
  std::string error_msg_;

  // ErrorThrower should always be stack-allocated, since it constitutes a scope
  // (things happen in the destructor).
  DISALLOW_NEW_AND_DELETE()
};

// Like an ErrorThrower, but turns all pending exceptions into scheduled
// exceptions when going out of scope. Use this in API methods.
// Note that pending exceptions are not necessarily created by the ErrorThrower,
// but e.g. by the wasm start function. There might also be a scheduled
// exception, created by another API call (e.g. v8::Object::Get). But there
// should never be both pending and scheduled exceptions.
class V8_EXPORT_PRIVATE ScheduledErrorThrower : public ErrorThrower {
 public:
  ScheduledErrorThrower(i::Isolate* isolate, const char* context)
      : ErrorThrower(isolate, context) {}

  ~ScheduledErrorThrower();
};

// Use {nullptr_t} as data value to indicate that this only stores the error,
// but no result value (the only valid value is {nullptr}).
// [Storing {void} would require template specialization.]
using VoidResult = Result<std::nullptr_t>;

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_WASM_RESULT_H_
