diff options
author | bashi <bashi@chromium.org> | 2015-05-28 21:06:05 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-05-29 04:06:44 +0000 |
commit | 7a6acf6c7d45e24f07781c69249d90967013bbe4 (patch) | |
tree | 6389c0ac1910a4674fbf2c791a1efa3eaa4c4059 /gin | |
parent | a719b2b6e63d2bc558db5392934de984fcd91e8c (diff) | |
download | chromium_src-7a6acf6c7d45e24f07781c69249d90967013bbe4.zip chromium_src-7a6acf6c7d45e24f07781c69249d90967013bbe4.tar.gz chromium_src-7a6acf6c7d45e24f07781c69249d90967013bbe4.tar.bz2 |
gin: Use V8 Maybe APIs
TEST=gin_unittests
BUG=479439
Review URL: https://codereview.chromium.org/1106393002
Cr-Commit-Position: refs/heads/master@{#331923}
Diffstat (limited to 'gin')
-rw-r--r-- | gin/arguments.h | 5 | ||||
-rw-r--r-- | gin/converter.cc | 47 | ||||
-rw-r--r-- | gin/converter.h | 77 | ||||
-rw-r--r-- | gin/converter_unittest.cc | 17 | ||||
-rw-r--r-- | gin/dictionary.h | 14 | ||||
-rw-r--r-- | gin/interceptor_unittest.cc | 2 | ||||
-rw-r--r-- | gin/modules/console.cc | 2 | ||||
-rw-r--r-- | gin/modules/module_registry.cc | 33 | ||||
-rw-r--r-- | gin/modules/module_registry.h | 6 | ||||
-rw-r--r-- | gin/object_template_builder.cc | 14 | ||||
-rw-r--r-- | gin/shell/gin_main.cc | 4 | ||||
-rw-r--r-- | gin/shell_runner.cc | 25 | ||||
-rw-r--r-- | gin/test/file.cc | 6 | ||||
-rw-r--r-- | gin/try_catch.cc | 16 | ||||
-rw-r--r-- | gin/try_catch.h | 3 | ||||
-rw-r--r-- | gin/wrappable.cc | 4 | ||||
-rw-r--r-- | gin/wrappable_unittest.cc | 8 |
17 files changed, 204 insertions, 79 deletions
diff --git a/gin/arguments.h b/gin/arguments.h index 4ac38a7..1affa2c 100644 --- a/gin/arguments.h +++ b/gin/arguments.h @@ -69,7 +69,10 @@ class GIN_EXPORT Arguments { template<typename T> void Return(T val) { - info_->GetReturnValue().Set(ConvertToV8(isolate_, val)); + v8::Local<v8::Value> v8_value; + if (!TryConvertToV8(isolate_, val, &v8_value)) + return; + info_->GetReturnValue().Set(v8_value); } v8::Local<v8::Value> PeekNext() const; diff --git a/gin/converter.cc b/gin/converter.cc index d870beb..9a3462d 100644 --- a/gin/converter.cc +++ b/gin/converter.cc @@ -10,14 +10,30 @@ using v8::ArrayBuffer; using v8::Boolean; using v8::External; using v8::Function; +using v8::Int32; using v8::Integer; using v8::Isolate; using v8::Local; +using v8::Maybe; +using v8::MaybeLocal; using v8::Number; using v8::Object; using v8::String; +using v8::Uint32; using v8::Value; +namespace { + +template <typename T, typename U> +bool FromMaybe(Maybe<T> maybe, U* out) { + if (maybe.IsNothing()) + return false; + *out = static_cast<U>(maybe.FromJust()); + return true; +} + +} // namespace + namespace gin { Local<Value> Converter<bool>::ToV8(Isolate* isolate, bool val) { @@ -25,8 +41,7 @@ Local<Value> Converter<bool>::ToV8(Isolate* isolate, bool val) { } bool Converter<bool>::FromV8(Isolate* isolate, Local<Value> val, bool* out) { - *out = val->BooleanValue(); - return true; + return FromMaybe(val->BooleanValue(isolate->GetCurrentContext()), out); } Local<Value> Converter<int32_t>::ToV8(Isolate* isolate, int32_t val) { @@ -38,7 +53,7 @@ bool Converter<int32_t>::FromV8(Isolate* isolate, int32_t* out) { if (!val->IsInt32()) return false; - *out = val->Int32Value(); + *out = val.As<Int32>()->Value(); return true; } @@ -51,7 +66,7 @@ bool Converter<uint32_t>::FromV8(Isolate* isolate, uint32_t* out) { if (!val->IsUint32()) return false; - *out = val->Uint32Value(); + *out = val.As<Uint32>()->Value(); return true; } @@ -66,8 +81,7 @@ bool Converter<int64_t>::FromV8(Isolate* isolate, return false; // Even though IntegerValue returns int64_t, JavaScript cannot represent // the full precision of int64_t, which means some rounding might occur. - *out = val->IntegerValue(); - return true; + return FromMaybe(val->IntegerValue(isolate->GetCurrentContext()), out); } Local<Value> Converter<uint64_t>::ToV8(Isolate* isolate, uint64_t val) { @@ -79,8 +93,7 @@ bool Converter<uint64_t>::FromV8(Isolate* isolate, uint64_t* out) { if (!val->IsNumber()) return false; - *out = static_cast<uint64_t>(val->IntegerValue()); - return true; + return FromMaybe(val->IntegerValue(isolate->GetCurrentContext()), out); } Local<Value> Converter<float>::ToV8(Isolate* isolate, float val) { @@ -90,7 +103,7 @@ Local<Value> Converter<float>::ToV8(Isolate* isolate, float val) { bool Converter<float>::FromV8(Isolate* isolate, Local<Value> val, float* out) { if (!val->IsNumber()) return false; - *out = static_cast<float>(val->NumberValue()); + *out = static_cast<float>(val.As<Number>()->Value()); return true; } @@ -103,14 +116,16 @@ bool Converter<double>::FromV8(Isolate* isolate, double* out) { if (!val->IsNumber()) return false; - *out = val->NumberValue(); + *out = val.As<Number>()->Value(); return true; } Local<Value> Converter<base::StringPiece>::ToV8(Isolate* isolate, const base::StringPiece& val) { - return String::NewFromUtf8(isolate, val.data(), String::kNormalString, - static_cast<uint32_t>(val.length())); + return String::NewFromUtf8(isolate, val.data(), + v8::NewStringType::kNormal, + static_cast<uint32_t>(val.length())) + .ToLocalChecked(); } Local<Value> Converter<std::string>::ToV8(Isolate* isolate, @@ -194,10 +209,10 @@ bool Converter<Local<Value>>::FromV8(Isolate* isolate, v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate, const base::StringPiece& val) { - return String::NewFromUtf8(isolate, - val.data(), - String::kInternalizedString, - static_cast<uint32_t>(val.length())); + return String::NewFromUtf8(isolate, val.data(), + v8::NewStringType::kInternalized, + static_cast<uint32_t>(val.length())) + .ToLocalChecked(); } std::string V8ToString(v8::Local<v8::Value> value) { diff --git a/gin/converter.h b/gin/converter.h index a07ada7..8d17d41 100644 --- a/gin/converter.h +++ b/gin/converter.h @@ -8,12 +8,27 @@ #include <string> #include <vector> +#include "base/logging.h" #include "base/strings/string_piece.h" #include "gin/gin_export.h" #include "v8/include/v8.h" namespace gin { +template<typename KeyType> +bool SetProperty(v8::Isolate* isolate, + v8::Local<v8::Object> object, + KeyType key, + v8::Local<v8::Value> value) { + auto maybe = object->Set(isolate->GetCurrentContext(), key, value); + return !maybe.IsNothing() && maybe.FromJust(); +} + +template<typename T> +struct ToV8ReturnsMaybe { + static const bool value = false; +}; + template<typename T, typename Enable = void> struct Converter {}; @@ -84,6 +99,7 @@ struct GIN_EXPORT Converter<double> { template<> struct GIN_EXPORT Converter<base::StringPiece> { + // This crashes when val.size() > v8::String::kMaxLength. static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const base::StringPiece& val); // No conversion out is possible because StringPiece does not contain storage. @@ -91,6 +107,7 @@ struct GIN_EXPORT Converter<base::StringPiece> { template<> struct GIN_EXPORT Converter<std::string> { + // This crashes when val.size() > v8::String::kMaxLength. static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, const std::string& val); static bool FromV8(v8::Isolate* isolate, @@ -143,12 +160,15 @@ struct GIN_EXPORT Converter<v8::Local<v8::Value> > { template<typename T> struct Converter<std::vector<T> > { - static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, - const std::vector<T>& val) { + static v8::MaybeLocal<v8::Value> ToV8(v8::Local<v8::Context> context, + const std::vector<T>& val) { + v8::Isolate* isolate = context->GetIsolate(); v8::Local<v8::Array> result( v8::Array::New(isolate, static_cast<int>(val.size()))); - for (size_t i = 0; i < val.size(); ++i) { - result->Set(static_cast<int>(i), Converter<T>::ToV8(isolate, val[i])); + for (uint32_t i = 0; i < val.size(); ++i) { + auto maybe = result->Set(context, i, Converter<T>::ToV8(isolate, val[i])); + if (maybe.IsNothing() || !maybe.FromJust()) + return v8::MaybeLocal<v8::Value>(); } return result; } @@ -163,8 +183,11 @@ struct Converter<std::vector<T> > { v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val)); uint32_t length = array->Length(); for (uint32_t i = 0; i < length; ++i) { + v8::Local<v8::Value> v8_item; + if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item)) + return false; T item; - if (!Converter<T>::FromV8(isolate, array->Get(i), &item)) + if (!Converter<T>::FromV8(isolate, v8_item, &item)) return false; result.push_back(item); } @@ -174,18 +197,62 @@ struct Converter<std::vector<T> > { } }; +template<typename T> +struct ToV8ReturnsMaybe<std::vector<T>> { + static const bool value = true; +}; + // Convenience functions that deduce T. template<typename T> v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, T input) { return Converter<T>::ToV8(isolate, input); } +template<typename T> +v8::MaybeLocal<v8::Value> ConvertToV8(v8::Local<v8::Context> context, T input) { + return Converter<T>::ToV8(context, input); +} + +template<typename T, bool = ToV8ReturnsMaybe<T>::value> struct ToV8Traits; + +template <typename T> +struct ToV8Traits<T, true> { + static bool TryConvertToV8(v8::Isolate* isolate, + T input, + v8::Local<v8::Value>* output) { + auto maybe = ConvertToV8(isolate->GetCurrentContext(), input); + if (maybe.IsEmpty()) + return false; + *output = maybe.ToLocalChecked(); + return true; + } +}; + +template <typename T> +struct ToV8Traits<T, false> { + static bool TryConvertToV8(v8::Isolate* isolate, + T input, + v8::Local<v8::Value>* output) { + *output = ConvertToV8(isolate, input); + return true; + } +}; + +template <typename T> +bool TryConvertToV8(v8::Isolate* isolate, + T input, + v8::Local<v8::Value>* output) { + return ToV8Traits<T>::TryConvertToV8(isolate, input, output); +} + +// This crashes when input.size() > v8::String::kMaxLength. GIN_EXPORT inline v8::Local<v8::String> StringToV8( v8::Isolate* isolate, const base::StringPiece& input) { return ConvertToV8(isolate, input).As<v8::String>(); } +// This crashes when input.size() > v8::String::kMaxLength. GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate, const base::StringPiece& val); diff --git a/gin/converter_unittest.cc b/gin/converter_unittest.cc index 8b9adf4..a7c3547 100644 --- a/gin/converter_unittest.cc +++ b/gin/converter_unittest.cc @@ -116,19 +116,16 @@ TEST_F(ConverterTest, Vector) { expected.push_back(0); expected.push_back(1); - Local<Array> js_array = Local<Array>::Cast( - Converter<std::vector<int>>::ToV8(instance_->isolate(), expected)); - ASSERT_FALSE(js_array.IsEmpty()); - EXPECT_EQ(3u, js_array->Length()); + auto maybe = Converter<std::vector<int>>::ToV8( + instance_->isolate()->GetCurrentContext(), expected); + Local<Value> js_value; + EXPECT_TRUE(maybe.ToLocal(&js_value)); + Local<Array> js_array2 = Local<Array>::Cast(js_value); + EXPECT_EQ(3u, js_array2->Length()); for (size_t i = 0; i < expected.size(); ++i) { EXPECT_TRUE(Integer::New(instance_->isolate(), expected[i]) - ->StrictEquals(js_array->Get(static_cast<int>(i)))); + ->StrictEquals(js_array2->Get(static_cast<int>(i)))); } - - std::vector<int> actual; - EXPECT_TRUE(Converter<std::vector<int> >::FromV8(instance_->isolate(), - js_array, &actual)); - EXPECT_EQ(expected, actual); } } // namespace gin diff --git a/gin/dictionary.h b/gin/dictionary.h index efebfa8..64736b1d 100644 --- a/gin/dictionary.h +++ b/gin/dictionary.h @@ -32,13 +32,23 @@ class GIN_EXPORT Dictionary { template<typename T> bool Get(const std::string& key, T* out) { - v8::Local<v8::Value> val = object_->Get(StringToV8(isolate_, key)); + v8::Local<v8::Value> val; + if (!object_->Get(isolate_->GetCurrentContext(), StringToV8(isolate_, key)) + .ToLocal(&val)) { + return false; + } return ConvertFromV8(isolate_, val, out); } template<typename T> bool Set(const std::string& key, T val) { - return object_->Set(StringToV8(isolate_, key), ConvertToV8(isolate_, val)); + v8::Local<v8::Value> v8_value; + if (!TryConvertToV8(isolate_, val, &v8_value)) + return false; + v8::Maybe<bool> result = + object_->Set(isolate_->GetCurrentContext(), StringToV8(isolate_, key), + v8_value); + return !result.IsNothing() && result.FromJust(); } v8::Isolate* isolate() const { return isolate_; } diff --git a/gin/interceptor_unittest.cc b/gin/interceptor_unittest.cc index 01c6ba9..02fb10d 100644 --- a/gin/interceptor_unittest.cc +++ b/gin/interceptor_unittest.cc @@ -139,7 +139,7 @@ class InterceptorTest : public V8Test { v8::Local<v8::String> source = StringToV8(isolate, script_source); EXPECT_FALSE(source.IsEmpty()); - gin::TryCatch try_catch; + gin::TryCatch try_catch(isolate); v8::Local<v8::Script> script = v8::Script::Compile(source); EXPECT_FALSE(script.IsEmpty()); v8::Local<v8::Value> val = script->Run(); diff --git a/gin/modules/console.cc b/gin/modules/console.cc index d172373..75241df 100644 --- a/gin/modules/console.cc +++ b/gin/modules/console.cc @@ -43,7 +43,7 @@ v8::Local<v8::Value> Console::GetModule(v8::Isolate* isolate) { .Build(); data->SetObjectTemplate(&g_wrapper_info, templ); } - return templ->NewInstance(); + return templ->NewInstance(isolate->GetCurrentContext()).ToLocalChecked(); } } // namespace gin diff --git a/gin/modules/module_registry.cc b/gin/modules/module_registry.cc index 6c3e898..036e98d 100644 --- a/gin/modules/module_registry.cc +++ b/gin/modules/module_registry.cc @@ -113,10 +113,14 @@ void ModuleRegistry::RegisterGlobals(Isolate* isolate, } // static -void ModuleRegistry::InstallGlobals(v8::Isolate* isolate, +bool ModuleRegistry::InstallGlobals(v8::Isolate* isolate, v8::Local<v8::Object> obj) { - obj->Set(StringToSymbol(isolate, "define"), - GetDefineTemplate(isolate)->GetFunction()); + v8::Local<v8::Function> function; + auto maybe_function = + GetDefineTemplate(isolate)->GetFunction(isolate->GetCurrentContext()); + if (!maybe_function.ToLocal(&function)) + return false; + return SetProperty(isolate, obj, StringToSymbol(isolate, "define"), function); } // static @@ -177,16 +181,17 @@ void ModuleRegistry::LoadModule(Isolate* isolate, unsatisfied_dependencies_.insert(id); } -void ModuleRegistry::RegisterModule(Isolate* isolate, +bool ModuleRegistry::RegisterModule(Isolate* isolate, const std::string& id, v8::Local<Value> module) { if (id.empty() || module.IsEmpty()) - return; + return false; + v8::Local<Object> modules = Local<Object>::New(isolate, modules_); + if (!SetProperty(isolate, modules, StringToSymbol(isolate, id), module)) + return false; unsatisfied_dependencies_.erase(id); available_modules_.insert(id); - v8::Local<Object> modules = Local<Object>::New(isolate, modules_); - modules->Set(StringToSymbol(isolate, id), module); std::pair<LoadModuleCallbackMap::iterator, LoadModuleCallbackMap::iterator> range = waiting_callbacks_.equal_range(id); @@ -203,6 +208,7 @@ void ModuleRegistry::RegisterModule(Isolate* isolate, // Should we call the callback asynchronously? it->Run(module); } + return true; } bool ModuleRegistry::CheckDependencies(PendingModule* pending) { @@ -218,9 +224,9 @@ bool ModuleRegistry::CheckDependencies(PendingModule* pending) { return num_missing_dependencies == 0; } -void ModuleRegistry::Load(Isolate* isolate, scoped_ptr<PendingModule> pending) { +bool ModuleRegistry::Load(Isolate* isolate, scoped_ptr<PendingModule> pending) { if (!pending->id.empty() && available_modules_.count(pending->id)) - return; // We've already loaded this module. + return true; // We've already loaded this module. uint32_t argc = static_cast<uint32_t>(pending->dependencies.size()); std::vector<v8::Local<Value> > argv(argc); @@ -240,7 +246,7 @@ void ModuleRegistry::Load(Isolate* isolate, scoped_ptr<PendingModule> pending) { &pending->id); } - RegisterModule(isolate, pending->id, module); + return RegisterModule(isolate, pending->id, module); } bool ModuleRegistry::AttemptToLoad(Isolate* isolate, @@ -249,16 +255,15 @@ bool ModuleRegistry::AttemptToLoad(Isolate* isolate, pending_modules_.push_back(pending.release()); return false; } - Load(isolate, pending.Pass()); - return true; + return Load(isolate, pending.Pass()); } v8::Local<v8::Value> ModuleRegistry::GetModule(v8::Isolate* isolate, const std::string& id) { v8::Local<Object> modules = Local<Object>::New(isolate, modules_); v8::Local<String> key = StringToSymbol(isolate, id); - DCHECK(modules->HasOwnProperty(key)); - return modules->Get(key); + DCHECK(modules->HasOwnProperty(isolate->GetCurrentContext(), key).FromJust()); + return modules->Get(isolate->GetCurrentContext(), key).ToLocalChecked(); } void ModuleRegistry::AttemptToLoadMoreModules(Isolate* isolate) { diff --git a/gin/modules/module_registry.h b/gin/modules/module_registry.h index c53155a..b67387b 100644 --- a/gin/modules/module_registry.h +++ b/gin/modules/module_registry.h @@ -47,7 +47,7 @@ class GIN_EXPORT ModuleRegistry { // Installs the necessary functions needed for modules. // WARNING: this may execute script in the page. - static void InstallGlobals(v8::Isolate* isolate, v8::Local<v8::Object> obj); + static bool InstallGlobals(v8::Isolate* isolate, v8::Local<v8::Object> obj); void AddObserver(ModuleRegistryObserver* observer); void RemoveObserver(ModuleRegistryObserver* observer); @@ -81,8 +81,8 @@ class GIN_EXPORT ModuleRegistry { explicit ModuleRegistry(v8::Isolate* isolate); - void Load(v8::Isolate* isolate, scoped_ptr<PendingModule> pending); - void RegisterModule(v8::Isolate* isolate, + bool Load(v8::Isolate* isolate, scoped_ptr<PendingModule> pending); + bool RegisterModule(v8::Isolate* isolate, const std::string& id, v8::Local<v8::Value> module); diff --git a/gin/object_template_builder.cc b/gin/object_template_builder.cc index 264552f9..28c9791 100644 --- a/gin/object_template_builder.cc +++ b/gin/object_template_builder.cc @@ -93,8 +93,11 @@ void NamedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { NamedInterceptorFromV8(isolate, info.Holder()); if (!interceptor) return; - info.GetReturnValue().Set(v8::Local<v8::Array>::Cast( - ConvertToV8(isolate, interceptor->EnumerateNamedProperties(isolate)))); + v8::Local<v8::Value> properties; + if (!TryConvertToV8(isolate, interceptor->EnumerateNamedProperties(isolate), + &properties)) + return; + info.GetReturnValue().Set(v8::Local<v8::Array>::Cast(properties)); } void IndexedPropertyGetter(uint32_t index, @@ -126,8 +129,11 @@ void IndexedPropertyEnumerator( IndexedInterceptorFromV8(isolate, info.Holder()); if (!interceptor) return; - info.GetReturnValue().Set(v8::Local<v8::Array>::Cast( - ConvertToV8(isolate, interceptor->EnumerateIndexedProperties(isolate)))); + v8::Local<v8::Value> properties; + if (!TryConvertToV8(isolate, interceptor->EnumerateIndexedProperties(isolate), + &properties)) + return; + info.GetReturnValue().Set(v8::Local<v8::Array>::Cast(properties)); } } // namespace diff --git a/gin/shell/gin_main.cc b/gin/shell/gin_main.cc index d3bab72..62143c9 100644 --- a/gin/shell/gin_main.cc +++ b/gin/shell/gin_main.cc @@ -75,7 +75,9 @@ int main(int argc, char** argv) { { gin::Runner::Scope scope(&runner); - v8::V8::SetCaptureStackTraceForUncaughtExceptions(true); + runner.GetContextHolder() + ->isolate() + ->SetCaptureStackTraceForUncaughtExceptions(true); } base::CommandLine::StringVector args = diff --git a/gin/shell_runner.cc b/gin/shell_runner.cc index eccee9f6..0e534e4 100644 --- a/gin/shell_runner.cc +++ b/gin/shell_runner.cc @@ -65,11 +65,13 @@ ShellRunner::~ShellRunner() { void ShellRunner::Run(const std::string& source, const std::string& resource_name) { - TryCatch try_catch; v8::Isolate* isolate = GetContextHolder()->isolate(); - v8::Local<Script> script = Script::Compile( - StringToV8(isolate, source), StringToV8(isolate, resource_name)); - if (try_catch.HasCaught()) { + TryCatch try_catch(isolate); + v8::ScriptOrigin origin(StringToV8(isolate, resource_name)); + auto maybe_script = Script::Compile(GetContextHolder()->context(), + StringToV8(isolate, source), &origin); + v8::Local<Script> script; + if (!maybe_script.ToLocal(&script)) { delegate_->UnhandledException(this, try_catch); return; } @@ -81,13 +83,15 @@ v8::Local<v8::Value> ShellRunner::Call(v8::Local<v8::Function> function, v8::Local<v8::Value> receiver, int argc, v8::Local<v8::Value> argv[]) { - TryCatch try_catch; + TryCatch try_catch(GetContextHolder()->isolate()); delegate_->WillRunScript(this); - v8::Local<v8::Value> result = function->Call(receiver, argc, argv); + auto maybe_result = + function->Call(GetContextHolder()->context(), receiver, argc, argv); delegate_->DidRunScript(this); - if (try_catch.HasCaught()) + v8::Local<v8::Value> result; + if (!maybe_result.ToLocal(&result)) delegate_->UnhandledException(this, try_catch); return result; @@ -98,13 +102,14 @@ ContextHolder* ShellRunner::GetContextHolder() { } void ShellRunner::Run(v8::Local<Script> script) { - TryCatch try_catch; + TryCatch try_catch(GetContextHolder()->isolate()); delegate_->WillRunScript(this); - script->Run(); + auto maybe = script->Run(GetContextHolder()->context()); delegate_->DidRunScript(this); - if (try_catch.HasCaught()) { + v8::Local<v8::Value> result; + if (!maybe.ToLocal(&result)) { delegate_->UnhandledException(this, try_catch); } } diff --git a/gin/test/file.cc b/gin/test/file.cc index adcb341..38efbb4 100644 --- a/gin/test/file.cc +++ b/gin/test/file.cc @@ -59,8 +59,10 @@ v8::Local<v8::Value> GetFilesInDirectory(gin::Arguments* args) { names.push_back(name.BaseName().AsUTF8Unsafe()); } - return gin::Converter<std::vector<std::string> >::ToV8(args->isolate(), - names); + v8::Local<v8::Value> v8_names; + if (!TryConvertToV8(args->isolate(), names, &v8_names)) + return v8::Null(args->isolate()); + return v8_names; } gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin }; diff --git a/gin/try_catch.cc b/gin/try_catch.cc index 97e7fe1..df27b9c 100644 --- a/gin/try_catch.cc +++ b/gin/try_catch.cc @@ -8,9 +8,21 @@ #include "gin/converter.h" +namespace { + +v8::Local<v8::String> GetSourceLine(v8::Isolate* isolate, + v8::Local<v8::Message> message) { + auto maybe = message->GetSourceLine(isolate->GetCurrentContext()); + v8::Local<v8::String> source_line; + return maybe.ToLocal(&source_line) ? source_line : v8::String::Empty(isolate); +} + +} // namespace + namespace gin { -TryCatch::TryCatch() { +TryCatch::TryCatch(v8::Isolate* isolate) + : isolate_(isolate), try_catch_(isolate) { } TryCatch::~TryCatch() { @@ -28,7 +40,7 @@ std::string TryCatch::GetStackTrace() { std::stringstream ss; v8::Local<v8::Message> message = try_catch_.Message(); ss << V8ToString(message->Get()) << std::endl - << V8ToString(message->GetSourceLine()) << std::endl; + << V8ToString(GetSourceLine(isolate_, message)) << std::endl; v8::Local<v8::StackTrace> trace = message->GetStackTrace(); if (trace.IsEmpty()) diff --git a/gin/try_catch.h b/gin/try_catch.h index 633b909..84b2ae1 100644 --- a/gin/try_catch.h +++ b/gin/try_catch.h @@ -16,13 +16,14 @@ namespace gin { // TryCatch is a convenient wrapper around v8::TryCatch. class GIN_EXPORT TryCatch { public: - TryCatch(); + explicit TryCatch(v8::Isolate* isolate); ~TryCatch(); bool HasCaught(); std::string GetStackTrace(); private: + v8::Isolate* isolate_; v8::TryCatch try_catch_; DISALLOW_COPY_AND_ASSIGN(TryCatch); diff --git a/gin/wrappable.cc b/gin/wrappable.cc index 09c17a3..27c58df 100644 --- a/gin/wrappable.cc +++ b/gin/wrappable.cc @@ -49,10 +49,10 @@ v8::Local<v8::Object> WrappableBase::GetWrapperImpl(v8::Isolate* isolate, data->SetObjectTemplate(info, templ); } CHECK_EQ(kNumberOfInternalFields, templ->InternalFieldCount()); - v8::Local<v8::Object> wrapper = templ->NewInstance(); + v8::Local<v8::Object> wrapper; // |wrapper| may be empty in some extreme cases, e.g., when // Object.prototype.constructor is overwritten. - if (wrapper.IsEmpty()) { + if (!templ->NewInstance(isolate->GetCurrentContext()).ToLocal(&wrapper)) { // The current wrappable object will be no longer managed by V8. Delete this // now. delete this; diff --git a/gin/wrappable_unittest.cc b/gin/wrappable_unittest.cc index 3d79571..70cb224 100644 --- a/gin/wrappable_unittest.cc +++ b/gin/wrappable_unittest.cc @@ -183,7 +183,7 @@ TEST_F(WrappableTest, GetAndSetProperty) { " else obj.value = 191; })"); EXPECT_FALSE(source.IsEmpty()); - gin::TryCatch try_catch; + gin::TryCatch try_catch(isolate); v8::Local<v8::Script> script = v8::Script::Compile(source); EXPECT_FALSE(script.IsEmpty()); v8::Local<v8::Value> val = script->Run(); @@ -209,7 +209,7 @@ TEST_F(WrappableTest, WrappableSubclass) { "(function(obj) {" "obj.sayHello('Lily');" "})"); - gin::TryCatch try_catch; + gin::TryCatch try_catch(isolate); v8::Local<v8::Script> script = v8::Script::Compile(source); v8::Local<v8::Value> val = script->Run(); v8::Local<v8::Function> func; @@ -232,7 +232,7 @@ TEST_F(WrappableTest, CallAsFunction) { "(function(obj) {" "obj(42, 2, 5);" "})"); - gin::TryCatch try_catch; + gin::TryCatch try_catch(isolate); v8::Local<v8::Script> script = v8::Script::Compile(source); v8::Local<v8::Value> val = script->Run(); v8::Local<v8::Function> func; @@ -255,7 +255,7 @@ TEST_F(WrappableTest, CallAsConstructor) { "(function(obj) {" "new obj(42, 2, 5);" "})"); - gin::TryCatch try_catch; + gin::TryCatch try_catch(isolate); v8::Local<v8::Script> script = v8::Script::Compile(source); v8::Local<v8::Value> val = script->Run(); v8::Local<v8::Function> func; |