blob: 48be87c458ac96788d6f0534fcd62d9d7253a073 [file] [log] [blame]
[email protected]a22998a2013-11-10 05:00:501// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef GIN_CONVERTER_H_
6#define GIN_CONVERTER_H_
7
avi90e658dd2015-12-21 07:16:198#include <stdint.h>
9
[email protected]a22998a2013-11-10 05:00:5010#include <string>
Jeremy Romaneb8a2f172018-01-29 17:33:4011#include <type_traits>
[email protected]a22998a2013-11-10 05:00:5012#include <vector>
13
bashidbd2ef9bb2015-06-02 01:39:3214#include "base/logging.h"
[email protected]b520e132013-11-29 03:21:4815#include "base/strings/string_piece.h"
[email protected]48c21632013-12-12 21:32:3416#include "gin/gin_export.h"
[email protected]a22998a2013-11-10 05:00:5017#include "v8/include/v8.h"
18
19namespace gin {
20
bashidbd2ef9bb2015-06-02 01:39:3221template<typename KeyType>
22bool SetProperty(v8::Isolate* isolate,
23 v8::Local<v8::Object> object,
24 KeyType key,
25 v8::Local<v8::Value> value) {
rdevlin.cronin415b73b2015-11-13 01:14:4726 auto maybe =
27 object->DefineOwnProperty(isolate->GetCurrentContext(), key, value);
bashidbd2ef9bb2015-06-02 01:39:3228 return !maybe.IsNothing() && maybe.FromJust();
29}
30
Ken Rockot2b0f07652017-04-12 19:10:4931template <typename T, typename Enable = void>
bashidbd2ef9bb2015-06-02 01:39:3232struct ToV8ReturnsMaybe {
33 static const bool value = false;
34};
35
[email protected]cf76c84a2013-12-06 14:07:0736template<typename T, typename Enable = void>
[email protected]a22998a2013-11-10 05:00:5037struct Converter {};
38
39template<>
[email protected]48c21632013-12-12 21:32:3440struct GIN_EXPORT Converter<bool> {
deepak.sfaaa1b62015-04-30 07:30:4841 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5042 bool val);
[email protected]7618ebbb2013-11-27 03:38:2643 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4844 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5045 bool* out);
46};
47
48template<>
[email protected]48c21632013-12-12 21:32:3449struct GIN_EXPORT Converter<int32_t> {
deepak.sfaaa1b62015-04-30 07:30:4850 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5051 int32_t val);
[email protected]7618ebbb2013-11-27 03:38:2652 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4853 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5054 int32_t* out);
55};
56
57template<>
[email protected]48c21632013-12-12 21:32:3458struct GIN_EXPORT Converter<uint32_t> {
deepak.sfaaa1b62015-04-30 07:30:4859 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5060 uint32_t val);
[email protected]7618ebbb2013-11-27 03:38:2661 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4862 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5063 uint32_t* out);
64};
65
66template<>
[email protected]48c21632013-12-12 21:32:3467struct GIN_EXPORT Converter<int64_t> {
[email protected]e87f3122013-11-12 00:41:2768 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4869 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2770 int64_t val);
[email protected]7618ebbb2013-11-27 03:38:2671 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4872 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2773 int64_t* out);
74};
75
76template<>
[email protected]48c21632013-12-12 21:32:3477struct GIN_EXPORT Converter<uint64_t> {
[email protected]e87f3122013-11-12 00:41:2778 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4879 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2780 uint64_t val);
[email protected]7618ebbb2013-11-27 03:38:2681 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4882 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2783 uint64_t* out);
84};
85
86template<>
[email protected]d73341d12013-12-21 00:48:4687struct GIN_EXPORT Converter<float> {
deepak.sfaaa1b62015-04-30 07:30:4888 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]d73341d12013-12-21 00:48:4689 float val);
90 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4891 v8::Local<v8::Value> val,
[email protected]d73341d12013-12-21 00:48:4692 float* out);
93};
94
95template<>
[email protected]48c21632013-12-12 21:32:3496struct GIN_EXPORT Converter<double> {
deepak.sfaaa1b62015-04-30 07:30:4897 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5098 double val);
[email protected]7618ebbb2013-11-27 03:38:2699 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48100 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50101 double* out);
102};
103
104template<>
[email protected]48c21632013-12-12 21:32:34105struct GIN_EXPORT Converter<base::StringPiece> {
bashidbd2ef9bb2015-06-02 01:39:32106 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48107 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]b520e132013-11-29 03:21:48108 const base::StringPiece& val);
109 // No conversion out is possible because StringPiece does not contain storage.
110};
111
112template<>
[email protected]48c21632013-12-12 21:32:34113struct GIN_EXPORT Converter<std::string> {
bashidbd2ef9bb2015-06-02 01:39:32114 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48115 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50116 const std::string& val);
[email protected]7618ebbb2013-11-27 03:38:26117 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48118 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50119 std::string* out);
120};
121
122template<>
deepak.sfaaa1b62015-04-30 07:30:48123struct GIN_EXPORT Converter<v8::Local<v8::Function> > {
Nitish Sakhawalkarf7bbaa522019-02-11 16:19:09124 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
125 v8::Local<v8::Function> val);
[email protected]7618ebbb2013-11-27 03:38:26126 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48127 v8::Local<v8::Value> val,
128 v8::Local<v8::Function>* out);
[email protected]a22998a2013-11-10 05:00:50129};
130
131template<>
deepak.sfaaa1b62015-04-30 07:30:48132struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
133 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
134 v8::Local<v8::Object> val);
[email protected]7618ebbb2013-11-27 03:38:26135 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48136 v8::Local<v8::Value> val,
137 v8::Local<v8::Object>* out);
[email protected]a22998a2013-11-10 05:00:50138};
139
Scott Grahamd2f4ed4b2018-10-17 01:57:27140template <>
141struct GIN_EXPORT Converter<v8::Local<v8::Promise>> {
142 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
143 v8::Local<v8::Promise> val);
144 static bool FromV8(v8::Isolate* isolate,
145 v8::Local<v8::Value> val,
146 v8::Local<v8::Promise>* out);
147};
148
[email protected]97f21ca2013-11-17 17:46:07149template<>
deepak.sfaaa1b62015-04-30 07:30:48150struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
151 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
152 v8::Local<v8::ArrayBuffer> val);
[email protected]7618ebbb2013-11-27 03:38:26153 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48154 v8::Local<v8::Value> val,
155 v8::Local<v8::ArrayBuffer>* out);
[email protected]ec95fdf2013-11-24 19:10:11156};
157
158template<>
deepak.sfaaa1b62015-04-30 07:30:48159struct GIN_EXPORT Converter<v8::Local<v8::External> > {
160 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
161 v8::Local<v8::External> val);
[email protected]7618ebbb2013-11-27 03:38:26162 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48163 v8::Local<v8::Value> val,
164 v8::Local<v8::External>* out);
[email protected]97f21ca2013-11-17 17:46:07165};
166
167template<>
deepak.sfaaa1b62015-04-30 07:30:48168struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
169 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
170 v8::Local<v8::Value> val);
[email protected]7618ebbb2013-11-27 03:38:26171 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48172 v8::Local<v8::Value> val,
173 v8::Local<v8::Value>* out);
[email protected]97f21ca2013-11-17 17:46:07174};
175
[email protected]a22998a2013-11-10 05:00:50176template<typename T>
177struct Converter<std::vector<T> > {
Jeremy Romaneb8a2f172018-01-29 17:33:40178 static std::conditional_t<ToV8ReturnsMaybe<T>::value,
179 v8::MaybeLocal<v8::Value>,
180 v8::Local<v8::Value>>
181 ToV8(v8::Isolate* isolate, const std::vector<T>& val) {
182 v8::Local<v8::Context> context = isolate->GetCurrentContext();
deepak.sfaaa1b62015-04-30 07:30:48183 v8::Local<v8::Array> result(
[email protected]91cd4fe2013-11-28 09:31:58184 v8::Array::New(isolate, static_cast<int>(val.size())));
bashidbd2ef9bb2015-06-02 01:39:32185 for (uint32_t i = 0; i < val.size(); ++i) {
Jeremy Romaneb8a2f172018-01-29 17:33:40186 v8::MaybeLocal<v8::Value> maybe = Converter<T>::ToV8(isolate, val[i]);
187 v8::Local<v8::Value> element;
188 if (!maybe.ToLocal(&element))
189 return {};
190 bool property_created;
191 if (!result->CreateDataProperty(context, i, element)
192 .To(&property_created) ||
193 !property_created) {
194 NOTREACHED() << "CreateDataProperty should always succeed here.";
195 }
[email protected]a22998a2013-11-10 05:00:50196 }
197 return result;
198 }
199
[email protected]7618ebbb2013-11-27 03:38:26200 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48201 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50202 std::vector<T>* out) {
203 if (!val->IsArray())
204 return false;
205
206 std::vector<T> result;
deepak.sfaaa1b62015-04-30 07:30:48207 v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
[email protected]a22998a2013-11-10 05:00:50208 uint32_t length = array->Length();
209 for (uint32_t i = 0; i < length; ++i) {
bashidbd2ef9bb2015-06-02 01:39:32210 v8::Local<v8::Value> v8_item;
211 if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
212 return false;
[email protected]a22998a2013-11-10 05:00:50213 T item;
bashidbd2ef9bb2015-06-02 01:39:32214 if (!Converter<T>::FromV8(isolate, v8_item, &item))
[email protected]a22998a2013-11-10 05:00:50215 return false;
216 result.push_back(item);
217 }
218
219 out->swap(result);
220 return true;
221 }
222};
223
bashidbd2ef9bb2015-06-02 01:39:32224template<typename T>
225struct ToV8ReturnsMaybe<std::vector<T>> {
Jeremy Romaneb8a2f172018-01-29 17:33:40226 static const bool value = ToV8ReturnsMaybe<T>::value;
bashidbd2ef9bb2015-06-02 01:39:32227};
228
[email protected]a22998a2013-11-10 05:00:50229// Convenience functions that deduce T.
Jeremy Romaneb8a2f172018-01-29 17:33:40230template <typename T>
231std::conditional_t<ToV8ReturnsMaybe<T>::value,
232 v8::MaybeLocal<v8::Value>,
233 v8::Local<v8::Value>>
Jeremy Apthorp6a3480292018-04-26 18:53:59234ConvertToV8(v8::Isolate* isolate, const T& input) {
[email protected]a22998a2013-11-10 05:00:50235 return Converter<T>::ToV8(isolate, input);
236}
237
Jeremy Roman44bda444b2018-03-16 17:33:45238template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59239std::enable_if_t<ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
240 v8::Isolate* isolate,
241 const T& input,
242 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45243 return ConvertToV8(isolate, input).ToLocal(output);
244}
bashidbd2ef9bb2015-06-02 01:39:32245
246template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59247std::enable_if_t<!ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
248 v8::Isolate* isolate,
249 const T& input,
250 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45251 *output = ConvertToV8(isolate, input);
252 return true;
bashidbd2ef9bb2015-06-02 01:39:32253}
254
255// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48256GIN_EXPORT inline v8::Local<v8::String> StringToV8(
[email protected]48c21632013-12-12 21:32:34257 v8::Isolate* isolate,
258 const base::StringPiece& input) {
[email protected]a22998a2013-11-10 05:00:50259 return ConvertToV8(isolate, input).As<v8::String>();
260}
261
bashidbd2ef9bb2015-06-02 01:39:32262// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48263GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
[email protected]48c21632013-12-12 21:32:34264 const base::StringPiece& val);
[email protected]e87f3122013-11-12 00:41:27265
[email protected]a22998a2013-11-10 05:00:50266template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48267bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
[email protected]7618ebbb2013-11-27 03:38:26268 T* result) {
Dan Elphick712beaa2018-07-24 17:37:24269 DCHECK(isolate);
[email protected]7618ebbb2013-11-27 03:38:26270 return Converter<T>::FromV8(isolate, input, result);
[email protected]a22998a2013-11-10 05:00:50271}
272
Dan Elphick38a508052018-07-23 22:19:53273GIN_EXPORT std::string V8ToString(v8::Isolate* isolate,
274 v8::Local<v8::Value> value);
[email protected]2f703422013-11-25 21:26:15275
[email protected]a22998a2013-11-10 05:00:50276} // namespace gin
277
278#endif // GIN_CONVERTER_H_