Commit eb8a2f17 authored by Jeremy Roman's avatar Jeremy Roman Committed by Commit Bot

[gin] Make Converter<std::vector<T>> return v8::Local if Converter<T> does.

For consistency between the methods, have all converters take v8::Isolate*,
as all of the ones that presently take v8::Local<v8::Context> implicitly
assume it to be the current context anyhow.

Bug: None
Change-Id: I565fb54bdc7a1d5ac1796ef5d7c1c69ca83290bb
Reviewed-on: https://chromium-review.googlesource.com/876563
Commit-Queue: Jeremy Roman <jbroman@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#532473}
parent 587c33f0
...@@ -158,6 +158,8 @@ test("gin_unittests") { ...@@ -158,6 +158,8 @@ test("gin_unittests") {
":gin_shell", ":gin_shell",
":gin_test", ":gin_test",
"//base/test:test_support", "//base/test:test_support",
"//testing/gmock",
"//testing/gtest",
"//v8", "//v8",
] ]
......
...@@ -74,8 +74,7 @@ TEST_F(ArgumentsTest, TestGetAll) { ...@@ -74,8 +74,7 @@ TEST_F(ArgumentsTest, TestGetAll) {
V8List list1 = { V8List list1 = {
gin::ConvertToV8(isolate, 1), gin::StringToV8(isolate, "some string"), gin::ConvertToV8(isolate, 1), gin::StringToV8(isolate, "some string"),
gin::ConvertToV8(context, std::vector<double>({2.0, 3.0})) gin::ConvertToV8(isolate, std::vector<double>({2.0, 3.0})),
.ToLocalChecked(),
}; };
bool called1 = false; bool called1 = false;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <type_traits>
#include <vector> #include <vector>
#include "base/logging.h" #include "base/logging.h"
...@@ -163,15 +164,24 @@ struct GIN_EXPORT Converter<v8::Local<v8::Value> > { ...@@ -163,15 +164,24 @@ struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
template<typename T> template<typename T>
struct Converter<std::vector<T> > { struct Converter<std::vector<T> > {
static v8::MaybeLocal<v8::Value> ToV8(v8::Local<v8::Context> context, static std::conditional_t<ToV8ReturnsMaybe<T>::value,
const std::vector<T>& val) { v8::MaybeLocal<v8::Value>,
v8::Isolate* isolate = context->GetIsolate(); v8::Local<v8::Value>>
ToV8(v8::Isolate* isolate, const std::vector<T>& val) {
v8::Local<v8::Context> context = isolate->GetCurrentContext();
v8::Local<v8::Array> result( v8::Local<v8::Array> result(
v8::Array::New(isolate, static_cast<int>(val.size()))); v8::Array::New(isolate, static_cast<int>(val.size())));
for (uint32_t i = 0; i < val.size(); ++i) { for (uint32_t i = 0; i < val.size(); ++i) {
auto maybe = result->Set(context, i, Converter<T>::ToV8(isolate, val[i])); v8::MaybeLocal<v8::Value> maybe = Converter<T>::ToV8(isolate, val[i]);
if (maybe.IsNothing() || !maybe.FromJust()) v8::Local<v8::Value> element;
return v8::MaybeLocal<v8::Value>(); if (!maybe.ToLocal(&element))
return {};
bool property_created;
if (!result->CreateDataProperty(context, i, element)
.To(&property_created) ||
!property_created) {
NOTREACHED() << "CreateDataProperty should always succeed here.";
}
} }
return result; return result;
} }
...@@ -202,20 +212,18 @@ struct Converter<std::vector<T> > { ...@@ -202,20 +212,18 @@ struct Converter<std::vector<T> > {
template<typename T> template<typename T>
struct ToV8ReturnsMaybe<std::vector<T>> { struct ToV8ReturnsMaybe<std::vector<T>> {
static const bool value = true; static const bool value = ToV8ReturnsMaybe<T>::value;
}; };
// Convenience functions that deduce T. // Convenience functions that deduce T.
template<typename T> template <typename T>
v8::Local<v8::Value> ConvertToV8(v8::Isolate* isolate, T input) { std::conditional_t<ToV8ReturnsMaybe<T>::value,
v8::MaybeLocal<v8::Value>,
v8::Local<v8::Value>>
ConvertToV8(v8::Isolate* isolate, T input) {
return Converter<T>::ToV8(isolate, 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, bool = ToV8ReturnsMaybe<T>::value> struct ToV8Traits;
template <typename T> template <typename T>
......
...@@ -9,8 +9,11 @@ ...@@ -9,8 +9,11 @@
#include <stdint.h> #include <stdint.h>
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "gin/handle.h"
#include "gin/public/isolate_holder.h" #include "gin/public/isolate_holder.h"
#include "gin/test/v8_test.h" #include "gin/test/v8_test.h"
#include "gin/wrappable.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
...@@ -116,16 +119,58 @@ TEST_F(ConverterTest, Vector) { ...@@ -116,16 +119,58 @@ TEST_F(ConverterTest, Vector) {
expected.push_back(0); expected.push_back(0);
expected.push_back(1); expected.push_back(1);
auto maybe = Converter<std::vector<int>>::ToV8( auto js_array =
instance_->isolate()->GetCurrentContext(), expected); Converter<std::vector<int>>::ToV8(instance_->isolate(), expected)
Local<Value> js_value; .As<Array>();
EXPECT_TRUE(maybe.ToLocal(&js_value)); EXPECT_EQ(3u, js_array->Length());
Local<Array> js_array2 = Local<Array>::Cast(js_value);
EXPECT_EQ(3u, js_array2->Length());
for (size_t i = 0; i < expected.size(); ++i) { for (size_t i = 0; i < expected.size(); ++i) {
EXPECT_TRUE(Integer::New(instance_->isolate(), expected[i]) EXPECT_TRUE(Integer::New(instance_->isolate(), expected[i])
->StrictEquals(js_array2->Get(static_cast<int>(i)))); ->StrictEquals(js_array->Get(static_cast<int>(i))));
} }
} }
TEST_F(ConverterTest, VectorOfVectors) {
HandleScope handle_scope(instance_->isolate());
std::vector<std::vector<int>> vector_of_vectors = {
{1, 2, 3}, {4, 5, 6},
};
v8::Local<v8::Value> v8_value =
ConvertToV8(instance_->isolate(), vector_of_vectors);
std::vector<std::vector<int>> out_value;
ASSERT_TRUE(ConvertFromV8(instance_->isolate(), v8_value, &out_value));
EXPECT_THAT(out_value, testing::ContainerEq(vector_of_vectors));
}
namespace {
class MyObject : public Wrappable<MyObject> {
public:
static WrapperInfo kWrapperInfo;
static gin::Handle<MyObject> Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new MyObject());
}
};
WrapperInfo MyObject::kWrapperInfo = {kEmbedderNativeGin};
} // namespace
TEST_F(ConverterTest, VectorOfWrappables) {
v8::Isolate* isolate = instance_->isolate();
v8::HandleScope handle_scope(isolate);
Handle<MyObject> obj = MyObject::Create(isolate);
std::vector<MyObject*> vector = {obj.get()};
v8::MaybeLocal<v8::Value> maybe = ConvertToV8(isolate, vector);
v8::Local<v8::Value> array;
ASSERT_TRUE(maybe.ToLocal(&array));
std::vector<MyObject*> out_value;
ASSERT_TRUE(ConvertFromV8(isolate, array, &out_value));
EXPECT_THAT(out_value, testing::ContainerEq(vector));
}
} // namespace gin } // namespace gin
...@@ -151,7 +151,7 @@ class InterceptorTest : public V8Test { ...@@ -151,7 +151,7 @@ class InterceptorTest : public V8Test {
v8::Local<v8::Function> func; v8::Local<v8::Function> func;
EXPECT_TRUE(ConvertFromV8(isolate, val, &func)); EXPECT_TRUE(ConvertFromV8(isolate, val, &func));
v8::Local<v8::Value> argv[] = { v8::Local<v8::Value> argv[] = {
ConvertToV8(isolate->GetCurrentContext(), obj.get()).ToLocalChecked(), ConvertToV8(isolate, obj.get()).ToLocalChecked(),
}; };
func->Call(v8::Undefined(isolate), 1, argv); func->Call(v8::Undefined(isolate), 1, argv);
EXPECT_FALSE(try_catch.HasCaught()); EXPECT_FALSE(try_catch.HasCaught());
......
...@@ -115,10 +115,9 @@ template <typename T> ...@@ -115,10 +115,9 @@ template <typename T>
struct Converter<T*, struct Converter<T*,
typename std::enable_if< typename std::enable_if<
std::is_convertible<T*, WrappableBase*>::value>::type> { std::is_convertible<T*, WrappableBase*>::value>::type> {
static v8::MaybeLocal<v8::Value> ToV8(v8::Local<v8::Context> context, static v8::MaybeLocal<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
T* val) {
v8::Local<v8::Object> wrapper; v8::Local<v8::Object> wrapper;
if (!val->GetWrapper(context->GetIsolate()).ToLocal(&wrapper)) if (!val->GetWrapper(isolate).ToLocal(&wrapper))
return v8::MaybeLocal<v8::Value>(); return v8::MaybeLocal<v8::Value>();
return v8::MaybeLocal<v8::Value>(wrapper); return v8::MaybeLocal<v8::Value>(wrapper);
} }
......
...@@ -74,7 +74,7 @@ TEST_F(WrappableTest, WrapAndUnwrap) { ...@@ -74,7 +74,7 @@ TEST_F(WrappableTest, WrapAndUnwrap) {
Handle<MyObject> obj = MyObject::Create(isolate); Handle<MyObject> obj = MyObject::Create(isolate);
v8::Local<v8::Value> wrapper = v8::Local<v8::Value> wrapper =
ConvertToV8(isolate->GetCurrentContext(), obj.get()).ToLocalChecked(); ConvertToV8(isolate, obj.get()).ToLocalChecked();
EXPECT_FALSE(wrapper.IsEmpty()); EXPECT_FALSE(wrapper.IsEmpty());
MyObject* unwrapped = NULL; MyObject* unwrapped = NULL;
...@@ -99,8 +99,7 @@ TEST_F(WrappableTest, UnwrapFailures) { ...@@ -99,8 +99,7 @@ TEST_F(WrappableTest, UnwrapFailures) {
// An object that's wrapping a C++ object of the wrong type. // An object that's wrapping a C++ object of the wrong type.
thing.Clear(); thing.Clear();
thing = ConvertToV8(isolate->GetCurrentContext(), new MyObject2()) thing = ConvertToV8(isolate, new MyObject2()).ToLocalChecked();
.ToLocalChecked();
EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped)); EXPECT_FALSE(ConvertFromV8(isolate, thing, &unwrapped));
EXPECT_FALSE(unwrapped); EXPECT_FALSE(unwrapped);
} }
...@@ -128,7 +127,7 @@ TEST_F(WrappableTest, GetAndSetProperty) { ...@@ -128,7 +127,7 @@ TEST_F(WrappableTest, GetAndSetProperty) {
v8::Local<v8::Function> func; v8::Local<v8::Function> func;
EXPECT_TRUE(ConvertFromV8(isolate, val, &func)); EXPECT_TRUE(ConvertFromV8(isolate, val, &func));
v8::Local<v8::Value> argv[] = { v8::Local<v8::Value> argv[] = {
ConvertToV8(isolate->GetCurrentContext(), obj.get()).ToLocalChecked(), ConvertToV8(isolate, obj.get()).ToLocalChecked(),
}; };
func->Call(v8::Undefined(isolate), 1, argv); func->Call(v8::Undefined(isolate), 1, argv);
EXPECT_FALSE(try_catch.HasCaught()); EXPECT_FALSE(try_catch.HasCaught());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment