#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/debug/leak_annotations.h"
#include "base/logging.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
+#include "gin/array_buffer.h"
+#include "gin/public/isolate_holder.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
#include "net/base/net_util.h"
// throughout this object's lifetime.
V8ExternalASCIILiteral(const char* ascii, size_t length)
: ascii_(ascii), length_(length) {
- DCHECK(IsStringASCII(ascii));
+ DCHECK(base::IsStringASCII(ascii));
}
virtual const char* data() const OVERRIDE {
}
// Converts an ASCII std::string to a V8 string.
-v8::Local<v8::String> ASCIIStringToV8String(const std::string& s) {
- DCHECK(IsStringASCII(s));
- return v8::String::New(s.data(), s.size());
+v8::Local<v8::String> ASCIIStringToV8String(v8::Isolate* isolate,
+ const std::string& s) {
+ DCHECK(base::IsStringASCII(s));
+ return v8::String::NewFromUtf8(isolate, s.data(), v8::String::kNormalString,
+ s.size());
}
// Converts a UTF16 base::string16 (warpped by a ProxyResolverScriptData) to a
// V8 string.
v8::Local<v8::String> ScriptDataToV8String(
- const scoped_refptr<ProxyResolverScriptData>& s) {
+ v8::Isolate* isolate, const scoped_refptr<ProxyResolverScriptData>& s) {
if (s->utf16().size() * 2 <= kMaxStringBytesForCopy) {
- return v8::String::New(
+ return v8::String::NewFromTwoByte(
+ isolate,
reinterpret_cast<const uint16_t*>(s->utf16().data()),
+ v8::String::kNormalString,
s->utf16().size());
}
- return v8::String::NewExternal(new V8ExternalStringFromScriptData(s));
+ return v8::String::NewExternal(isolate,
+ new V8ExternalStringFromScriptData(s));
}
// Converts an ASCII string literal to a V8 string.
-v8::Local<v8::String> ASCIILiteralToV8String(const char* ascii) {
- DCHECK(IsStringASCII(ascii));
+v8::Local<v8::String> ASCIILiteralToV8String(v8::Isolate* isolate,
+ const char* ascii) {
+ DCHECK(base::IsStringASCII(ascii));
size_t length = strlen(ascii);
if (length <= kMaxStringBytesForCopy)
- return v8::String::New(ascii, length);
- return v8::String::NewExternal(new V8ExternalASCIILiteral(ascii, length));
+ return v8::String::NewFromUtf8(isolate, ascii, v8::String::kNormalString,
+ length);
+ return v8::String::NewExternal(isolate,
+ new V8ExternalASCIILiteral(ascii, length));
}
// Stringizes a V8 object by calling its toString() method. Returns true
const base::string16 hostname_utf16 = V8StringToUTF16(args[0]->ToString());
// If the hostname is already in ASCII, simply return it as is.
- if (IsStringASCII(hostname_utf16)) {
- *hostname = UTF16ToASCII(hostname_utf16);
+ if (base::IsStringASCII(hostname_utf16)) {
+ *hostname = base::UTF16ToASCII(hostname_utf16);
return true;
}
// Otherwise try to convert it from IDN to punycode.
const int kInitialBufferSize = 256;
- url_canon::RawCanonOutputT<char16, kInitialBufferSize> punycode_output;
- if (!url_canon::IDNToASCII(hostname_utf16.data(),
- hostname_utf16.length(),
- &punycode_output)) {
+ url::RawCanonOutputT<base::char16, kInitialBufferSize> punycode_output;
+ if (!url::IDNToASCII(hostname_utf16.data(), hostname_utf16.length(),
+ &punycode_output)) {
return false;
}
// |punycode_output| should now be ASCII; convert it to a std::string.
// (We could use UTF16ToASCII() instead, but that requires an extra string
// copy. Since ASCII is a subset of UTF8 the following is equivalent).
- bool success = UTF16ToUTF8(punycode_output.data(),
+ bool success = base::UTF16ToUTF8(punycode_output.data(),
punycode_output.length(),
hostname);
DCHECK(success);
- DCHECK(IsStringASCII(*hostname));
+ DCHECK(base::IsStringASCII(*hostname));
return success;
}
// Strip all whitespace (mimics IE behavior).
std::string cleaned_ip_address_list;
- RemoveChars(ip_address_list, " \t", &cleaned_ip_address_list);
+ base::RemoveChars(ip_address_list, " \t", &cleaned_ip_address_list);
if (cleaned_ip_address_list.empty())
return false;
~Context() {
v8::Locker locked(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
- v8_this_.Dispose();
- v8_context_.Dispose();
+ v8_this_.Reset();
+ v8_context_.Reset();
}
JSBindings* js_bindings() {
int ResolveProxy(const GURL& query_url, ProxyInfo* results) {
v8::Locker locked(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
v8::HandleScope scope(isolate_);
v8::Local<v8::Context> context =
v8::Local<v8::Value> function;
if (!GetFindProxyForURL(&function)) {
js_bindings()->OnError(
- -1, ASCIIToUTF16("FindProxyForURL() is undefined."));
+ -1, base::ASCIIToUTF16("FindProxyForURL() is undefined."));
return ERR_PAC_SCRIPT_FAILED;
}
v8::Handle<v8::Value> argv[] = {
- ASCIIStringToV8String(query_url.spec()),
- ASCIIStringToV8String(query_url.HostNoBrackets()),
+ ASCIIStringToV8String(isolate_, query_url.spec()),
+ ASCIIStringToV8String(isolate_, query_url.HostNoBrackets()),
};
v8::TryCatch try_catch;
if (!ret->IsString()) {
js_bindings()->OnError(
- -1, ASCIIToUTF16("FindProxyForURL() did not return a string."));
+ -1, base::ASCIIToUTF16("FindProxyForURL() did not return a string."));
return ERR_PAC_SCRIPT_FAILED;
}
base::string16 ret_str = V8StringToUTF16(ret->ToString());
- if (!IsStringASCII(ret_str)) {
+ if (!base::IsStringASCII(ret_str)) {
// TODO(eroman): Rather than failing when a wide string is returned, we
// could extend the parsing to handle IDNA hostnames by
// converting them to ASCII punycode.
// crbug.com/47234
base::string16 error_message =
- ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string "
- "(crbug.com/47234): ") + ret_str;
+ base::ASCIIToUTF16("FindProxyForURL() returned a non-ASCII string "
+ "(crbug.com/47234): ") + ret_str;
js_bindings()->OnError(-1, error_message);
return ERR_PAC_SCRIPT_FAILED;
}
- results->UsePacString(UTF16ToASCII(ret_str));
+ results->UsePacString(base::UTF16ToASCII(ret_str));
return OK;
}
int InitV8(const scoped_refptr<ProxyResolverScriptData>& pac_script) {
v8::Locker locked(isolate_);
+ v8::Isolate::Scope isolate_scope(isolate_);
v8::HandleScope scope(isolate_);
- v8_this_.Reset(isolate_, v8::External::New(this));
+ v8_this_.Reset(isolate_, v8::External::New(isolate_, this));
v8::Local<v8::External> v8_this =
v8::Local<v8::External>::New(isolate_, v8_this_);
- v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ v8::Local<v8::ObjectTemplate> global_template =
+ v8::ObjectTemplate::New(isolate_);
// Attach the javascript bindings.
v8::Local<v8::FunctionTemplate> alert_template =
- v8::FunctionTemplate::New(&AlertCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String("alert"), alert_template);
+ v8::FunctionTemplate::New(isolate_, &AlertCallback, v8_this);
+ global_template->Set(ASCIILiteralToV8String(isolate_, "alert"),
+ alert_template);
v8::Local<v8::FunctionTemplate> my_ip_address_template =
- v8::FunctionTemplate::New(&MyIpAddressCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String("myIpAddress"),
- my_ip_address_template);
+ v8::FunctionTemplate::New(isolate_, &MyIpAddressCallback, v8_this);
+ global_template->Set(ASCIILiteralToV8String(isolate_, "myIpAddress"),
+ my_ip_address_template);
v8::Local<v8::FunctionTemplate> dns_resolve_template =
- v8::FunctionTemplate::New(&DnsResolveCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String("dnsResolve"),
- dns_resolve_template);
+ v8::FunctionTemplate::New(isolate_, &DnsResolveCallback, v8_this);
+ global_template->Set(ASCIILiteralToV8String(isolate_, "dnsResolve"),
+ dns_resolve_template);
// Microsoft's PAC extensions:
v8::Local<v8::FunctionTemplate> dns_resolve_ex_template =
- v8::FunctionTemplate::New(&DnsResolveExCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String("dnsResolveEx"),
+ v8::FunctionTemplate::New(isolate_, &DnsResolveExCallback, v8_this);
+ global_template->Set(ASCIILiteralToV8String(isolate_, "dnsResolveEx"),
dns_resolve_ex_template);
v8::Local<v8::FunctionTemplate> my_ip_address_ex_template =
- v8::FunctionTemplate::New(&MyIpAddressExCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String("myIpAddressEx"),
+ v8::FunctionTemplate::New(isolate_, &MyIpAddressExCallback, v8_this);
+ global_template->Set(ASCIILiteralToV8String(isolate_, "myIpAddressEx"),
my_ip_address_ex_template);
v8::Local<v8::FunctionTemplate> sort_ip_address_list_template =
- v8::FunctionTemplate::New(&SortIpAddressListCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String("sortIpAddressList"),
+ v8::FunctionTemplate::New(isolate_,
+ &SortIpAddressListCallback,
+ v8_this);
+ global_template->Set(ASCIILiteralToV8String(isolate_, "sortIpAddressList"),
sort_ip_address_list_template);
v8::Local<v8::FunctionTemplate> is_in_net_ex_template =
- v8::FunctionTemplate::New(&IsInNetExCallback, v8_this);
- global_template->Set(ASCIILiteralToV8String("isInNetEx"),
+ v8::FunctionTemplate::New(isolate_, &IsInNetExCallback, v8_this);
+ global_template->Set(ASCIILiteralToV8String(isolate_, "isInNetEx"),
is_in_net_ex_template);
v8_context_.Reset(
// Note that the two string literals are concatenated.
int rv = RunScript(
ASCIILiteralToV8String(
+ isolate_,
PROXY_RESOLVER_SCRIPT
PROXY_RESOLVER_SCRIPT_EX),
kPacUtilityResourceName);
}
// Add the user's PAC code to the environment.
- rv = RunScript(ScriptDataToV8String(pac_script), kPacResourceName);
+ rv =
+ RunScript(ScriptDataToV8String(isolate_, pac_script), kPacResourceName);
if (rv != OK)
return rv;
v8::Local<v8::Value> function;
if (!GetFindProxyForURL(&function)) {
js_bindings()->OnError(
- -1, ASCIIToUTF16("FindProxyForURL() is undefined."));
+ -1, base::ASCIIToUTF16("FindProxyForURL() is undefined."));
return ERR_PAC_SCRIPT_FAILED;
}
return OK;
}
- void PurgeMemory() {
- v8::Locker locked(isolate_);
- v8::V8::LowMemoryNotification();
- }
-
private:
bool GetFindProxyForURL(v8::Local<v8::Value>* function) {
v8::Local<v8::Context> context =
- v8::Local<v8::Context>::New(v8::Isolate::GetCurrent(), v8_context_);
+ v8::Local<v8::Context>::New(isolate_, v8_context_);
*function =
- context->Global()->Get(ASCIILiteralToV8String("FindProxyForURL"));
+ context->Global()->Get(
+ ASCIILiteralToV8String(isolate_, "FindProxyForURL"));
return (*function)->IsFunction();
}
// Compile the script.
v8::ScriptOrigin origin =
- v8::ScriptOrigin(ASCIILiteralToV8String(script_name));
+ v8::ScriptOrigin(ASCIILiteralToV8String(isolate_, script_name));
v8::Local<v8::Script> code = v8::Script::Compile(script, &origin);
// Execute.
// disregard any arguments beyond the first.
base::string16 message;
if (args.Length() == 0) {
- message = ASCIIToUTF16("undefined");
+ message = base::ASCIIToUTF16("undefined");
} else {
if (!V8ObjectToUTF16String(args[0], &message, args.GetIsolate()))
return; // toString() threw an exception.
v8::V8::TerminateExecution(args.GetIsolate());
if (success) {
- args.GetReturnValue().Set(ASCIIStringToV8String(result));
+ args.GetReturnValue().Set(
+ ASCIIStringToV8String(args.GetIsolate(), result));
return;
}
args.GetReturnValue().SetEmptyString();
return;
case JSBindings::MY_IP_ADDRESS:
- args.GetReturnValue().Set(ASCIILiteralToV8String("127.0.0.1"));
+ args.GetReturnValue().Set(
+ ASCIILiteralToV8String(args.GetIsolate(), "127.0.0.1"));
return;
case JSBindings::MY_IP_ADDRESS_EX:
args.GetReturnValue().SetEmptyString();
}
std::string ip_address_list = V8StringToUTF8(args[0]->ToString());
- if (!IsStringASCII(ip_address_list)) {
+ if (!base::IsStringASCII(ip_address_list)) {
args.GetReturnValue().SetNull();
return;
}
args.GetReturnValue().Set(false);
return;
}
- args.GetReturnValue().Set(ASCIIStringToV8String(sorted_ip_address_list));
+ args.GetReturnValue().Set(
+ ASCIIStringToV8String(args.GetIsolate(), sorted_ip_address_list));
}
// V8 callback for when "isInNetEx()" is invoked by the PAC script.
}
std::string ip_address = V8StringToUTF8(args[0]->ToString());
- if (!IsStringASCII(ip_address)) {
+ if (!base::IsStringASCII(ip_address)) {
args.GetReturnValue().Set(false);
return;
}
std::string ip_prefix = V8StringToUTF8(args[1]->ToString());
- if (!IsStringASCII(ip_prefix)) {
+ if (!base::IsStringASCII(ip_prefix)) {
args.GetReturnValue().Set(false);
return;
}
NOTREACHED();
}
-void ProxyResolverV8::PurgeMemory() {
- if (context_)
- context_->PurgeMemory();
-}
-
int ProxyResolverV8::SetPacScript(
const scoped_refptr<ProxyResolverScriptData>& script_data,
const CompletionCallback& /*callback*/) {
}
// static
-void ProxyResolverV8::RememberDefaultIsolate() {
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- DCHECK(isolate)
- << "ProxyResolverV8::RememberDefaultIsolate called on wrong thread";
- DCHECK(g_default_isolate_ == NULL || g_default_isolate_ == isolate)
- << "Default Isolate can not be changed";
- g_default_isolate_ = isolate;
-}
-
-#if defined(OS_WIN)
-// static
-void ProxyResolverV8::CreateIsolate() {
- v8::Isolate* isolate = v8::Isolate::New();
- DCHECK(isolate);
- DCHECK(g_default_isolate_ == NULL) << "Default Isolate can not be set twice";
-
- isolate->Enter();
- v8::V8::Initialize();
-
- g_default_isolate_ = isolate;
+void ProxyResolverV8::EnsureIsolateCreated() {
+ if (g_proxy_resolver_isolate_)
+ return;
+ gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
+ gin::ArrayBufferAllocator::SharedInstance());
+ g_proxy_resolver_isolate_ = new gin::IsolateHolder;
+ ANNOTATE_LEAKING_OBJECT_PTR(g_proxy_resolver_isolate_);
}
-#endif // defined(OS_WIN)
// static
v8::Isolate* ProxyResolverV8::GetDefaultIsolate() {
- DCHECK(g_default_isolate_)
- << "Must call ProxyResolverV8::RememberDefaultIsolate() first";
- return g_default_isolate_;
+ DCHECK(g_proxy_resolver_isolate_)
+ << "Must call ProxyResolverV8::EnsureIsolateCreated() first";
+ return g_proxy_resolver_isolate_->isolate();
}
-v8::Isolate* ProxyResolverV8::g_default_isolate_ = NULL;
+gin::IsolateHolder* ProxyResolverV8::g_proxy_resolver_isolate_ = NULL;
// static
size_t ProxyResolverV8::GetTotalHeapSize() {
- if (!g_default_isolate_)
+ if (!g_proxy_resolver_isolate_)
return 0;
- v8::Locker locked(g_default_isolate_);
+ v8::Locker locked(g_proxy_resolver_isolate_->isolate());
+ v8::Isolate::Scope isolate_scope(g_proxy_resolver_isolate_->isolate());
v8::HeapStatistics heap_statistics;
- g_default_isolate_->GetHeapStatistics(&heap_statistics);
+ g_proxy_resolver_isolate_->isolate()->GetHeapStatistics(&heap_statistics);
return heap_statistics.total_heap_size();
}
// static
size_t ProxyResolverV8::GetUsedHeapSize() {
- if (!g_default_isolate_)
+ if (!g_proxy_resolver_isolate_)
return 0;
- v8::Locker locked(g_default_isolate_);
+ v8::Locker locked(g_proxy_resolver_isolate_->isolate());
+ v8::Isolate::Scope isolate_scope(g_proxy_resolver_isolate_->isolate());
v8::HeapStatistics heap_statistics;
- g_default_isolate_->GetHeapStatistics(&heap_statistics);
+ g_proxy_resolver_isolate_->isolate()->GetHeapStatistics(&heap_statistics);
return heap_statistics.used_heap_size();
}