blob: 3621dae819241a6c6badee7afbf886aa07ea668e [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
Hans Wennborg5cd6d192020-06-18 11:14:5610#include <ostream>
[email protected]a22998a2013-11-10 05:00:5011#include <string>
Jeremy Romaneb8a2f172018-01-29 17:33:4012#include <type_traits>
[email protected]a22998a2013-11-10 05:00:5013#include <vector>
14
Hans Wennborgc8b134b2020-06-19 21:15:3915#include "base/check.h"
16#include "base/notreached.h"
[email protected]b520e132013-11-29 03:21:4817#include "base/strings/string_piece.h"
[email protected]48c21632013-12-12 21:32:3418#include "gin/gin_export.h"
Dan Elphick05acd602021-08-30 15:22:0719#include "v8/include/v8-container.h"
20#include "v8/include/v8-forward.h"
21#include "v8/include/v8-isolate.h"
[email protected]a22998a2013-11-10 05:00:5022
23namespace gin {
24
bashidbd2ef9bb2015-06-02 01:39:3225template<typename KeyType>
26bool SetProperty(v8::Isolate* isolate,
27 v8::Local<v8::Object> object,
28 KeyType key,
29 v8::Local<v8::Value> value) {
rdevlin.cronin415b73b2015-11-13 01:14:4730 auto maybe =
31 object->DefineOwnProperty(isolate->GetCurrentContext(), key, value);
bashidbd2ef9bb2015-06-02 01:39:3232 return !maybe.IsNothing() && maybe.FromJust();
33}
34
Ken Rockot2b0f07652017-04-12 19:10:4935template <typename T, typename Enable = void>
bashidbd2ef9bb2015-06-02 01:39:3236struct ToV8ReturnsMaybe {
37 static const bool value = false;
38};
39
[email protected]cf76c84a2013-12-06 14:07:0740template<typename T, typename Enable = void>
[email protected]a22998a2013-11-10 05:00:5041struct Converter {};
42
43template<>
[email protected]48c21632013-12-12 21:32:3444struct GIN_EXPORT Converter<bool> {
deepak.sfaaa1b62015-04-30 07:30:4845 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5046 bool val);
[email protected]7618ebbb2013-11-27 03:38:2647 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4848 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5049 bool* out);
50};
51
52template<>
[email protected]48c21632013-12-12 21:32:3453struct GIN_EXPORT Converter<int32_t> {
deepak.sfaaa1b62015-04-30 07:30:4854 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5055 int32_t val);
[email protected]7618ebbb2013-11-27 03:38:2656 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4857 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5058 int32_t* out);
59};
60
61template<>
[email protected]48c21632013-12-12 21:32:3462struct GIN_EXPORT Converter<uint32_t> {
deepak.sfaaa1b62015-04-30 07:30:4863 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:5064 uint32_t val);
[email protected]7618ebbb2013-11-27 03:38:2665 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4866 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:5067 uint32_t* out);
68};
69
70template<>
[email protected]48c21632013-12-12 21:32:3471struct GIN_EXPORT Converter<int64_t> {
[email protected]e87f3122013-11-12 00:41:2772 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4873 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2774 int64_t val);
[email protected]7618ebbb2013-11-27 03:38:2675 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4876 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2777 int64_t* out);
78};
79
80template<>
[email protected]48c21632013-12-12 21:32:3481struct GIN_EXPORT Converter<uint64_t> {
[email protected]e87f3122013-11-12 00:41:2782 // Warning: JavaScript cannot represent 64 integers precisely.
deepak.sfaaa1b62015-04-30 07:30:4883 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]e87f3122013-11-12 00:41:2784 uint64_t val);
[email protected]7618ebbb2013-11-27 03:38:2685 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4886 v8::Local<v8::Value> val,
[email protected]e87f3122013-11-12 00:41:2787 uint64_t* out);
88};
89
90template<>
[email protected]d73341d12013-12-21 00:48:4691struct GIN_EXPORT Converter<float> {
deepak.sfaaa1b62015-04-30 07:30:4892 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]d73341d12013-12-21 00:48:4693 float val);
94 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:4895 v8::Local<v8::Value> val,
[email protected]d73341d12013-12-21 00:48:4696 float* out);
97};
98
99template<>
[email protected]48c21632013-12-12 21:32:34100struct GIN_EXPORT Converter<double> {
deepak.sfaaa1b62015-04-30 07:30:48101 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50102 double val);
[email protected]7618ebbb2013-11-27 03:38:26103 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48104 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50105 double* out);
106};
107
108template<>
[email protected]48c21632013-12-12 21:32:34109struct GIN_EXPORT Converter<base::StringPiece> {
bashidbd2ef9bb2015-06-02 01:39:32110 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48111 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]b520e132013-11-29 03:21:48112 const base::StringPiece& val);
113 // No conversion out is possible because StringPiece does not contain storage.
114};
115
116template<>
[email protected]48c21632013-12-12 21:32:34117struct GIN_EXPORT Converter<std::string> {
bashidbd2ef9bb2015-06-02 01:39:32118 // This crashes when val.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48119 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
[email protected]a22998a2013-11-10 05:00:50120 const std::string& val);
[email protected]7618ebbb2013-11-27 03:38:26121 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48122 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50123 std::string* out);
124};
125
Shimi Zhang15708bfc2019-08-13 19:24:48126template <>
Jan Wilken Dörrie739ccc212021-03-11 18:13:05127struct GIN_EXPORT Converter<std::u16string> {
Shimi Zhang15708bfc2019-08-13 19:24:48128 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
Jan Wilken Dörrie739ccc212021-03-11 18:13:05129 const std::u16string& val);
Shimi Zhang15708bfc2019-08-13 19:24:48130 static bool FromV8(v8::Isolate* isolate,
131 v8::Local<v8::Value> val,
Jan Wilken Dörrie739ccc212021-03-11 18:13:05132 std::u16string* out);
Shimi Zhang15708bfc2019-08-13 19:24:48133};
134
Shimi Zhang15708bfc2019-08-13 19:24:48135template <>
136struct GIN_EXPORT Converter<v8::Local<v8::Function>> {
Nitish Sakhawalkarf7bbaa522019-02-11 16:19:09137 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
138 v8::Local<v8::Function> val);
[email protected]7618ebbb2013-11-27 03:38:26139 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48140 v8::Local<v8::Value> val,
141 v8::Local<v8::Function>* out);
[email protected]a22998a2013-11-10 05:00:50142};
143
144template<>
deepak.sfaaa1b62015-04-30 07:30:48145struct GIN_EXPORT Converter<v8::Local<v8::Object> > {
146 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
147 v8::Local<v8::Object> val);
[email protected]7618ebbb2013-11-27 03:38:26148 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48149 v8::Local<v8::Value> val,
150 v8::Local<v8::Object>* out);
[email protected]a22998a2013-11-10 05:00:50151};
152
Scott Grahamd2f4ed4b2018-10-17 01:57:27153template <>
154struct GIN_EXPORT Converter<v8::Local<v8::Promise>> {
155 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
156 v8::Local<v8::Promise> val);
157 static bool FromV8(v8::Isolate* isolate,
158 v8::Local<v8::Value> val,
159 v8::Local<v8::Promise>* out);
160};
161
[email protected]97f21ca2013-11-17 17:46:07162template<>
deepak.sfaaa1b62015-04-30 07:30:48163struct GIN_EXPORT Converter<v8::Local<v8::ArrayBuffer> > {
164 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
165 v8::Local<v8::ArrayBuffer> val);
[email protected]7618ebbb2013-11-27 03:38:26166 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48167 v8::Local<v8::Value> val,
168 v8::Local<v8::ArrayBuffer>* out);
[email protected]ec95fdf2013-11-24 19:10:11169};
170
171template<>
deepak.sfaaa1b62015-04-30 07:30:48172struct GIN_EXPORT Converter<v8::Local<v8::External> > {
173 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
174 v8::Local<v8::External> val);
[email protected]7618ebbb2013-11-27 03:38:26175 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48176 v8::Local<v8::Value> val,
177 v8::Local<v8::External>* out);
[email protected]97f21ca2013-11-17 17:46:07178};
179
180template<>
deepak.sfaaa1b62015-04-30 07:30:48181struct GIN_EXPORT Converter<v8::Local<v8::Value> > {
182 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
183 v8::Local<v8::Value> val);
[email protected]7618ebbb2013-11-27 03:38:26184 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48185 v8::Local<v8::Value> val,
186 v8::Local<v8::Value>* out);
[email protected]97f21ca2013-11-17 17:46:07187};
188
[email protected]a22998a2013-11-10 05:00:50189template<typename T>
190struct Converter<std::vector<T> > {
Jeremy Romaneb8a2f172018-01-29 17:33:40191 static std::conditional_t<ToV8ReturnsMaybe<T>::value,
192 v8::MaybeLocal<v8::Value>,
193 v8::Local<v8::Value>>
194 ToV8(v8::Isolate* isolate, const std::vector<T>& val) {
195 v8::Local<v8::Context> context = isolate->GetCurrentContext();
deepak.sfaaa1b62015-04-30 07:30:48196 v8::Local<v8::Array> result(
[email protected]91cd4fe2013-11-28 09:31:58197 v8::Array::New(isolate, static_cast<int>(val.size())));
bashidbd2ef9bb2015-06-02 01:39:32198 for (uint32_t i = 0; i < val.size(); ++i) {
Jeremy Romaneb8a2f172018-01-29 17:33:40199 v8::MaybeLocal<v8::Value> maybe = Converter<T>::ToV8(isolate, val[i]);
200 v8::Local<v8::Value> element;
201 if (!maybe.ToLocal(&element))
202 return {};
203 bool property_created;
204 if (!result->CreateDataProperty(context, i, element)
205 .To(&property_created) ||
206 !property_created) {
207 NOTREACHED() << "CreateDataProperty should always succeed here.";
208 }
[email protected]a22998a2013-11-10 05:00:50209 }
210 return result;
211 }
212
[email protected]7618ebbb2013-11-27 03:38:26213 static bool FromV8(v8::Isolate* isolate,
deepak.sfaaa1b62015-04-30 07:30:48214 v8::Local<v8::Value> val,
[email protected]a22998a2013-11-10 05:00:50215 std::vector<T>* out) {
216 if (!val->IsArray())
217 return false;
218
219 std::vector<T> result;
deepak.sfaaa1b62015-04-30 07:30:48220 v8::Local<v8::Array> array(v8::Local<v8::Array>::Cast(val));
[email protected]a22998a2013-11-10 05:00:50221 uint32_t length = array->Length();
222 for (uint32_t i = 0; i < length; ++i) {
bashidbd2ef9bb2015-06-02 01:39:32223 v8::Local<v8::Value> v8_item;
224 if (!array->Get(isolate->GetCurrentContext(), i).ToLocal(&v8_item))
225 return false;
[email protected]a22998a2013-11-10 05:00:50226 T item;
bashidbd2ef9bb2015-06-02 01:39:32227 if (!Converter<T>::FromV8(isolate, v8_item, &item))
[email protected]a22998a2013-11-10 05:00:50228 return false;
229 result.push_back(item);
230 }
231
232 out->swap(result);
233 return true;
234 }
235};
236
bashidbd2ef9bb2015-06-02 01:39:32237template<typename T>
238struct ToV8ReturnsMaybe<std::vector<T>> {
Jeremy Romaneb8a2f172018-01-29 17:33:40239 static const bool value = ToV8ReturnsMaybe<T>::value;
bashidbd2ef9bb2015-06-02 01:39:32240};
241
[email protected]a22998a2013-11-10 05:00:50242// Convenience functions that deduce T.
Jeremy Romaneb8a2f172018-01-29 17:33:40243template <typename T>
244std::conditional_t<ToV8ReturnsMaybe<T>::value,
245 v8::MaybeLocal<v8::Value>,
246 v8::Local<v8::Value>>
Jeremy Apthorp6a3480292018-04-26 18:53:59247ConvertToV8(v8::Isolate* isolate, const T& input) {
[email protected]a22998a2013-11-10 05:00:50248 return Converter<T>::ToV8(isolate, input);
249}
250
Jeremy Roman44bda444b2018-03-16 17:33:45251template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59252std::enable_if_t<ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
253 v8::Isolate* isolate,
254 const T& input,
255 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45256 return ConvertToV8(isolate, input).ToLocal(output);
257}
bashidbd2ef9bb2015-06-02 01:39:32258
259template <typename T>
Jeremy Apthorp6a3480292018-04-26 18:53:59260std::enable_if_t<!ToV8ReturnsMaybe<T>::value, bool> TryConvertToV8(
261 v8::Isolate* isolate,
262 const T& input,
263 v8::Local<v8::Value>* output) {
Jeremy Roman44bda444b2018-03-16 17:33:45264 *output = ConvertToV8(isolate, input);
265 return true;
bashidbd2ef9bb2015-06-02 01:39:32266}
267
268// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48269GIN_EXPORT inline v8::Local<v8::String> StringToV8(
[email protected]48c21632013-12-12 21:32:34270 v8::Isolate* isolate,
271 const base::StringPiece& input) {
[email protected]a22998a2013-11-10 05:00:50272 return ConvertToV8(isolate, input).As<v8::String>();
273}
274
bashidbd2ef9bb2015-06-02 01:39:32275// This crashes when input.size() > v8::String::kMaxLength.
deepak.sfaaa1b62015-04-30 07:30:48276GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
[email protected]48c21632013-12-12 21:32:34277 const base::StringPiece& val);
[email protected]e87f3122013-11-12 00:41:27278
Shimi Zhang15708bfc2019-08-13 19:24:48279// This crashes when input.size() > v8::String::kMaxLength.
280GIN_EXPORT v8::Local<v8::String> StringToSymbol(v8::Isolate* isolate,
281 const base::StringPiece16& val);
282
[email protected]a22998a2013-11-10 05:00:50283template<typename T>
deepak.sfaaa1b62015-04-30 07:30:48284bool ConvertFromV8(v8::Isolate* isolate, v8::Local<v8::Value> input,
[email protected]7618ebbb2013-11-27 03:38:26285 T* result) {
Dan Elphick712beaa2018-07-24 17:37:24286 DCHECK(isolate);
[email protected]7618ebbb2013-11-27 03:38:26287 return Converter<T>::FromV8(isolate, input, result);
[email protected]a22998a2013-11-10 05:00:50288}
289
Dan Elphick38a508052018-07-23 22:19:53290GIN_EXPORT std::string V8ToString(v8::Isolate* isolate,
291 v8::Local<v8::Value> value);
[email protected]2f703422013-11-25 21:26:15292
[email protected]a22998a2013-11-10 05:00:50293} // namespace gin
294
295#endif // GIN_CONVERTER_H_