/*
 * Copyright (C) 2009 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_DOM_WRAPPER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_DOM_WRAPPER_H_

#include "base/stl_util.h"
#include "third_party/blink/renderer/platform/bindings/binding_security_for_platform.h"
#include "third_party/blink/renderer/platform/bindings/custom_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/dom_data_store.h"
#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding.h"
#include "third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/compiler.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "v8/include/v8.h"

namespace blink {

struct WrapperTypeInfo;

// Contains utility methods to create wrappers, associate ScriptWrappable
// objects with wrappers and set fields in wrappers.
class V8DOMWrapper {
  STATIC_ONLY(V8DOMWrapper);

 public:
  PLATFORM_EXPORT static v8::Local<v8::Object> CreateWrapper(
      v8::Isolate*,
      v8::Local<v8::Object> creation_context,
      const WrapperTypeInfo*);
  PLATFORM_EXPORT static bool IsWrapper(v8::Isolate*, v8::Local<v8::Value>);

  // Associates the given ScriptWrappable with the given |wrapper| if the
  // ScriptWrappable is not yet associated with any wrapper.  Returns the
  // wrapper already associated or |wrapper| if not yet associated.
  // The caller should always use the returned value rather than |wrapper|.
  PLATFORM_EXPORT WARN_UNUSED_RESULT static v8::Local<v8::Object>
  AssociateObjectWithWrapper(v8::Isolate*,
                             ScriptWrappable*,
                             const WrapperTypeInfo*,
                             v8::Local<v8::Object> wrapper);
  static void AssociateObjectWithWrapper(v8::Isolate*,
                                         CustomWrappable*,
                                         const WrapperTypeInfo*,
                                         v8::Local<v8::Object> wrapper);
  static void SetNativeInfo(v8::Isolate* isolate,
                            v8::Local<v8::Object> wrapper,
                            const WrapperTypeInfo* wrapper_type_info,
                            ScriptWrappable* script_wrappable) {
    SetNativeInfoInternal(isolate, wrapper, wrapper_type_info,
                          script_wrappable);
  }
  static void SetNativeInfo(v8::Isolate* isolate,
                            v8::Local<v8::Object> wrapper,
                            const WrapperTypeInfo* wrapper_type_info,
                            CustomWrappable* custom_wrappable) {
    SetNativeInfoInternal(isolate, wrapper, wrapper_type_info,
                          custom_wrappable);
  }
  static void ClearNativeInfo(v8::Isolate*, v8::Local<v8::Object>);

  // hasInternalFieldsSet only checks if the value has the internal fields for
  // wrapper obejct and type, and does not check if it's valid or not.  The
  // value may not be a Blink's wrapper object.  In order to make sure of it,
  // Use isWrapper function instead.
  PLATFORM_EXPORT static bool HasInternalFieldsSet(v8::Local<v8::Value>);

 private:
  static void SetNativeInfoInternal(v8::Isolate*,
                                    v8::Local<v8::Object>,
                                    const WrapperTypeInfo*,
                                    void*);
};

inline void V8DOMWrapper::SetNativeInfoInternal(
    v8::Isolate* isolate,
    v8::Local<v8::Object> wrapper,
    const WrapperTypeInfo* wrapper_type_info,
    void* wrappable) {
  DCHECK_GE(wrapper->InternalFieldCount(), 2);
  DCHECK(wrappable);
  DCHECK(wrapper_type_info);
  int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex};
  void* values[] = {wrappable, const_cast<WrapperTypeInfo*>(wrapper_type_info)};
  wrapper->SetAlignedPointerInInternalFields(base::size(indices), indices,
                                             values);
  // The following write barrier is necessary as V8 might not see the newly
  // created object during garbage collection, e.g., when the object is black
  // allocated.
  ScriptWrappableMarkingVisitor::WriteBarrier(isolate, wrapper_type_info,
                                              wrappable);
  UnifiedHeapMarkingVisitor::WriteBarrier(isolate, wrapper_type_info,
                                          wrappable);
}

inline void V8DOMWrapper::ClearNativeInfo(v8::Isolate* isolate,
                                          v8::Local<v8::Object> wrapper) {
  int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex};
  void* values[] = {nullptr, nullptr};
  wrapper->SetAlignedPointerInInternalFields(base::size(indices), indices,
                                             values);
}

inline v8::Local<v8::Object> V8DOMWrapper::AssociateObjectWithWrapper(
    v8::Isolate* isolate,
    ScriptWrappable* impl,
    const WrapperTypeInfo* wrapper_type_info,
    v8::Local<v8::Object> wrapper) {
  RUNTIME_CALL_TIMER_SCOPE(
      isolate, RuntimeCallStats::CounterId::kAssociateObjectWithWrapper);
  if (DOMDataStore::SetWrapper(isolate, impl, wrapper_type_info, wrapper)) {
    WrapperTypeInfo::WrapperCreated();
    SetNativeInfo(isolate, wrapper, wrapper_type_info, impl);
    DCHECK(HasInternalFieldsSet(wrapper));
  }
  SECURITY_CHECK(ToScriptWrappable(wrapper) == impl);
  return wrapper;
}

inline void V8DOMWrapper::AssociateObjectWithWrapper(
    v8::Isolate* isolate,
    CustomWrappable* impl,
    const WrapperTypeInfo* wrapper_type_info,
    v8::Local<v8::Object> wrapper) {
  RUNTIME_CALL_TIMER_SCOPE(
      isolate, RuntimeCallStats::CounterId::kAssociateObjectWithWrapper);
  WrapperTypeInfo::WrapperCreated();
  SetNativeInfo(isolate, wrapper, wrapper_type_info, impl);
  DCHECK(HasInternalFieldsSet(wrapper));
  SECURITY_CHECK(ToCustomWrappable(wrapper) == impl);
}

class V8WrapperInstantiationScope {
  STACK_ALLOCATED();

 public:
  V8WrapperInstantiationScope(v8::Local<v8::Object> creation_context,
                              v8::Isolate* isolate,
                              const WrapperTypeInfo* type)
      : did_enter_context_(false),
        context_(isolate->GetCurrentContext()),
        try_catch_(isolate),
        type_(type),
        access_check_failed_(false) {
    // creationContext should not be empty. Because if we have an
    // empty creationContext, we will end up creating
    // a new object in the context currently entered. This is wrong.
    CHECK(!creation_context.IsEmpty());
    v8::Local<v8::Context> context_for_wrapper =
        creation_context->CreationContext();

    // For performance, we enter the context only if the currently running
    // context is different from the context that we are about to enter.
    if (context_for_wrapper == context_)
      return;

    if (!BindingSecurityForPlatform::ShouldAllowWrapperCreationOrThrowException(
            isolate->GetCurrentContext(), context_for_wrapper, type_)) {
      DCHECK(try_catch_.HasCaught());
      try_catch_.ReThrow();
      access_check_failed_ = true;
      return;
    }

    did_enter_context_ = true;
    context_ = context_for_wrapper;
    context_->Enter();
  }

  ~V8WrapperInstantiationScope() {
    if (!did_enter_context_) {
      try_catch_.ReThrow();
      return;
    }
    context_->Exit();

    if (access_check_failed_ || !try_catch_.HasCaught())
      return;

    // Any exception caught here is a cross context exception and it may not be
    // safe to directly rethrow the exception in the current context (without
    // converting it). rethrowCrossContextException converts the exception in
    // such a scenario.
    v8::Local<v8::Value> caught_exception = try_catch_.Exception();
    try_catch_.Reset();
    BindingSecurityForPlatform::RethrowWrapperCreationException(
        context_->GetIsolate()->GetCurrentContext(), context_, type_,
        caught_exception);
    try_catch_.ReThrow();
  }

  v8::Local<v8::Context> GetContext() const { return context_; }
  bool AccessCheckFailed() const { return access_check_failed_; }

 private:
  bool did_enter_context_;
  v8::Local<v8::Context> context_;
  v8::TryCatch try_catch_;
  const WrapperTypeInfo* type_;
  bool access_check_failed_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_DOM_WRAPPER_H_
