| Index: gin/converter.h
|
| diff --git a/gin/converter.h b/gin/converter.h
|
| index a07ada7effaaf6d6d96bc8b62f6f2f7b9b9a00d6..8d17d41c29fba56bd5bae0a66d895f7cd035d79b 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);
|
|
|
|
|