<commit_before>// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include <string>
#include <vector>

#include "base/compiler_specific.h"

#include "third_party/WebKit/Source/WebCore/config.h"
MSVC_PUSH_WARNING_LEVEL(0);
#include "Frame.h"  // NOLINT(build/include)
#include "ScriptController.h"  // NOLINT(build/include)
#include "ScriptControllerBase.h"  // NOLINT(build/include)
#include "V8Binding.h"  // NOLINT(build/include)
#include "V8RecursionScope.h"  // NOLINT(build/include)
MSVC_POP_WARNING();
#undef LOG

#include "libcef/v8_impl.h"

#include "libcef/browser_impl.h"
#include "libcef/cef_context.h"
#include "libcef/tracker.h"

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptController.h"

#define CEF_REQUIRE_UI_THREAD(var) \
  if (!CefThread::CurrentlyOn(CefThread::UI)) { \
    NOTREACHED() << "called on invalid thread"; \
    return var; \
  }

#define CEF_REQUIRE_VALID_CONTEXT(var) \
  if (!CONTEXT_STATE_VALID()) { \
    NOTREACHED() << "context not valid"; \
    return var; \
  }

namespace {

static const char kCefTrackObject[] = "Cef::TrackObject";
static const char kCefContextState[] = "Cef::ContextState";

// Memory manager.

class CefV8TrackManager {
 public:
  CefV8TrackManager() {
    const CefSettings& settings = _Context->settings();
    if (settings.context_safety_implementation < 0)
      context_safety_impl_ = IMPL_DISABLED;
    else if (settings.context_safety_implementation == 1)
      context_safety_impl_ = IMPL_VALUE;
    else
      context_safety_impl_ = IMPL_HASH;
  }

  scoped_refptr<CefV8ContextState> GetContextState(
      v8::Handle<v8::Context> context) {
    if (context_safety_impl_ == IMPL_DISABLED)
      return scoped_refptr<CefV8ContextState>();

    if (context.IsEmpty()) {
      if (v8::Context::InContext())
        context = v8::Context::GetCurrent();
      else
        return scoped_refptr<CefV8ContextState>();
    }

    if (context_safety_impl_ == IMPL_HASH) {
      int hash = context->Global()->GetIdentityHash();
      ContextMap::const_iterator it = context_map_.find(hash);
      if (it != context_map_.end())
        return it->second;

      scoped_refptr<CefV8ContextState> state = new CefV8ContextState();
      context_map_.insert(std::make_pair(hash, state));

      return state;
    } else {
      if (context_state_key_.IsEmpty()) {
        context_state_key_ =
            v8::Persistent<v8::String>::New(v8::String::New(kCefContextState));
      }

      v8::Handle<v8::Object> object = context->Global();
      v8::Handle<v8::Value> value = object->GetHiddenValue(context_state_key_);
      if (!value.IsEmpty())
        return static_cast<CefV8ContextState*>(v8::External::Unwrap(value));

      scoped_refptr<CefV8ContextState> state = new CefV8ContextState();
      object->SetHiddenValue(context_state_key_,
                             v8::External::New(state.get()));

      // Reference will be released in ReleaseContext.
      state->AddRef();

      return state;
    }
  }

  void ReleaseContext(v8::Handle<v8::Context> context) {
    if (context_safety_impl_ == IMPL_DISABLED)
      return;

    if (context_safety_impl_ == IMPL_HASH) {
      int hash = context->Global()->GetIdentityHash();
      ContextMap::iterator it = context_map_.find(hash);
      if (it != context_map_.end()) {
        it->second->Detach();
        context_map_.erase(it);
      }
    } else {
      if (context_state_key_.IsEmpty())
        return;

      v8::Handle<v8::Object> object = context->Global();
      v8::Handle<v8::Value> value = object->GetHiddenValue(context_state_key_);
      scoped_refptr<CefV8ContextState> state =
          static_cast<CefV8ContextState*>(v8::External::Unwrap(value));
      state->Detach();
      object->DeleteHiddenValue(context_state_key_);

      // Match the AddRef in GetContextState.<commit_msg>Fix potential crash if a context with no bindings is released (issue #736).<commit_after>// Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include <string>
#include <vector>

#include "base/compiler_specific.h"

#include "third_party/WebKit/Source/WebCore/config.h"
MSVC_PUSH_WARNING_LEVEL(0);
#include "Frame.h"  // NOLINT(build/include)
#include "ScriptController.h"  // NOLINT(build/include)
#include "ScriptControllerBase.h"  // NOLINT(build/include)
#include "V8Binding.h"  // NOLINT(build/include)
#include "V8RecursionScope.h"  // NOLINT(build/include)
MSVC_POP_WARNING();
#undef LOG

#include "libcef/v8_impl.h"

#include "libcef/browser_impl.h"
#include "libcef/cef_context.h"
#include "libcef/tracker.h"

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptController.h"

#define CEF_REQUIRE_UI_THREAD(var) \
  if (!CefThread::CurrentlyOn(CefThread::UI)) { \
    NOTREACHED() << "called on invalid thread"; \
    return var; \
  }

#define CEF_REQUIRE_VALID_CONTEXT(var) \
  if (!CONTEXT_STATE_VALID()) { \
    NOTREACHED() << "context not valid"; \
    return var; \
  }

namespace {

static const char kCefTrackObject[] = "Cef::TrackObject";
static const char kCefContextState[] = "Cef::ContextState";

// Memory manager.

class CefV8TrackManager {
 public:
  CefV8TrackManager() {
    const CefSettings& settings = _Context->settings();
    if (settings.context_safety_implementation < 0)
      context_safety_impl_ = IMPL_DISABLED;
    else if (settings.context_safety_implementation == 1)
      context_safety_impl_ = IMPL_VALUE;
    else
      context_safety_impl_ = IMPL_HASH;
  }

  scoped_refptr<CefV8ContextState> GetContextState(
      v8::Handle<v8::Context> context) {
    if (context_safety_impl_ == IMPL_DISABLED)
      return scoped_refptr<CefV8ContextState>();

    if (context.IsEmpty()) {
      if (v8::Context::InContext())
        context = v8::Context::GetCurrent();
      else
        return scoped_refptr<CefV8ContextState>();
    }

    if (context_safety_impl_ == IMPL_HASH) {
      int hash = context->Global()->GetIdentityHash();
      ContextMap::const_iterator it = context_map_.find(hash);
      if (it != context_map_.end())
        return it->second;

      scoped_refptr<CefV8ContextState> state = new CefV8ContextState();
      context_map_.insert(std::make_pair(hash, state));

      return state;
    } else {
      if (context_state_key_.IsEmpty()) {
        context_state_key_ =
            v8::Persistent<v8::String>::New(v8::String::New(kCefContextState));
      }

      v8::Handle<v8::Object> object = context->Global();
      v8::Handle<v8::Value> value = object->GetHiddenValue(context_state_key_);
      if (!value.IsEmpty())
        return static_cast<CefV8ContextState*>(v8::External::Unwrap(value));

      scoped_refptr<CefV8ContextState> state = new CefV8ContextState();
      object->SetHiddenValue(context_state_key_,
                             v8::External::New(state.get()));

      // Reference will be released in ReleaseContext.
      state->AddRef();

      return state;
    }
  }

  void ReleaseContext(v8::Handle<v8::Context> context) {
    if (context_safety_impl_ == IMPL_DISABLED)
      return;

    if (context_safety_impl_ == IMPL_HASH) {
      int hash = context->Global()->GetIdentityHash();
      ContextMap::iterator it = context_map_.find(hash);
      if (it != context_map_.end()) {
        it->second->Detach();
        context_map_.erase(it);
      }
    } else {
      if (context_state_key_.IsEmpty())
        return;

      v8::Handle<v8::Object> object = context->Global();
      v8::Handle<v8::Value> value = object->GetHiddenValue(context_state_key_);
      if (value.IsEmpty())
        return;

      scoped_refptr<CefV8ContextState> state =
          static_cast<CefV8ContextState*>(v8::External::Unwrap(value));
      state->Detach();
      object->DeleteHiddenValue(context_state_key_);

      // Match the AddRef in GetContextState.
{'fraction_non_alphanumeric': 0.13245033112582782, 'fraction_numerical': 0.010288552507095554, 'mean_word_length': 3.764507042253521, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 69, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7084214', 'n_tokens_mistral': 2884, 'n_tokens_neox': 2824, 'n_words': 500}