blob: e139e265ab3281d587a4c4dfb12572d8bbeddfec [file] [log] [blame]
Tom Sepez3466e272020-03-18 23:33:35 +00001// Copyright 2020 PDFium 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// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7#include "fxjs/fxv8.h"
8
9namespace fxv8 {
10
Tom Sepezaf6371f2020-11-02 20:13:01 +000011bool IsUndefined(v8::Local<v8::Value> value) {
12 return !value.IsEmpty() && value->IsUndefined();
13}
14
15bool IsNull(v8::Local<v8::Value> value) {
16 return !value.IsEmpty() && value->IsNull();
17}
18
19bool IsBoolean(v8::Local<v8::Value> value) {
20 return !value.IsEmpty() && value->IsBoolean();
21}
22
23bool IsString(v8::Local<v8::Value> value) {
24 return !value.IsEmpty() && value->IsString();
25}
26
27bool IsNumber(v8::Local<v8::Value> value) {
28 return !value.IsEmpty() && value->IsNumber();
29}
30
31bool IsInteger(v8::Local<v8::Value> value) {
32 return !value.IsEmpty() && value->IsInt32();
33}
34
35bool IsObject(v8::Local<v8::Value> value) {
36 return !value.IsEmpty() && value->IsObject();
37}
38
39bool IsArray(v8::Local<v8::Value> value) {
40 return !value.IsEmpty() && value->IsArray();
41}
42
43bool IsDate(v8::Local<v8::Value> value) {
44 return !value.IsEmpty() && value->IsDate();
45}
46
47bool IsFunction(v8::Local<v8::Value> value) {
48 return !value.IsEmpty() && value->IsFunction();
49}
50
Tom Sepez1512c362020-03-19 22:13:52 +000051v8::Local<v8::Value> NewNullHelper(v8::Isolate* pIsolate) {
52 return v8::Null(pIsolate);
53}
54
55v8::Local<v8::Value> NewUndefinedHelper(v8::Isolate* pIsolate) {
56 return v8::Undefined(pIsolate);
57}
58
59v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, int number) {
60 return v8::Int32::New(pIsolate, number);
61}
62
63v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, double number) {
64 return v8::Number::New(pIsolate, number);
65}
66
67v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, float number) {
68 return v8::Number::New(pIsolate, number);
69}
70
71v8::Local<v8::Boolean> NewBooleanHelper(v8::Isolate* pIsolate, bool b) {
72 return v8::Boolean::New(pIsolate, b);
73}
74
Tom Sepez3466e272020-03-18 23:33:35 +000075v8::Local<v8::String> NewStringHelper(v8::Isolate* pIsolate,
76 ByteStringView str) {
77 return v8::String::NewFromUtf8(pIsolate, str.unterminated_c_str(),
78 v8::NewStringType::kNormal, str.GetLength())
79 .ToLocalChecked();
80}
81
82v8::Local<v8::String> NewStringHelper(v8::Isolate* pIsolate,
83 WideStringView str) {
84 return NewStringHelper(pIsolate, FX_UTF8Encode(str).AsStringView());
85}
86
Tom Sepez1512c362020-03-19 22:13:52 +000087v8::Local<v8::Array> NewArrayHelper(v8::Isolate* pIsolate) {
88 return v8::Array::New(pIsolate);
89}
90
Tom Sepez145e22d2020-11-18 00:49:06 +000091v8::Local<v8::Array> NewArrayHelper(v8::Isolate* pIsolate,
92 pdfium::span<v8::Local<v8::Value>> values) {
93 v8::Local<v8::Array> result = NewArrayHelper(pIsolate);
94 for (size_t i = 0; i < values.size(); ++i) {
95 fxv8::ReentrantPutArrayElementHelper(
96 pIsolate, result, i,
97 values[i].IsEmpty() ? fxv8::NewUndefinedHelper(pIsolate) : values[i]);
98 }
99 return result;
100}
101
Tom Sepez1512c362020-03-19 22:13:52 +0000102v8::Local<v8::Object> NewObjectHelper(v8::Isolate* pIsolate) {
103 return v8::Object::New(pIsolate);
104}
105
106v8::Local<v8::Date> NewDateHelper(v8::Isolate* pIsolate, double d) {
107 return v8::Date::New(pIsolate->GetCurrentContext(), d)
108 .ToLocalChecked()
109 .As<v8::Date>();
110}
111
Tom Sepez494efc72020-11-30 20:50:59 +0000112WideString ToWideString(v8::Isolate* pIsolate, v8::Local<v8::String> pValue) {
113 v8::String::Utf8Value s(pIsolate, pValue);
114 return WideString::FromUTF8(ByteStringView(*s, s.length()));
115}
116
117ByteString ToByteString(v8::Isolate* pIsolate, v8::Local<v8::String> pValue) {
118 v8::String::Utf8Value s(pIsolate, pValue);
119 return ByteString(*s, s.length());
120}
121
Tom Sepez3466e272020-03-18 23:33:35 +0000122int ReentrantToInt32Helper(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
123 if (pValue.IsEmpty())
124 return 0;
Tom Sepez5f3e5812020-08-11 22:46:10 +0000125 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepez3466e272020-03-18 23:33:35 +0000126 return pValue->Int32Value(pIsolate->GetCurrentContext()).FromMaybe(0);
127}
128
129bool ReentrantToBooleanHelper(v8::Isolate* pIsolate,
130 v8::Local<v8::Value> pValue) {
131 if (pValue.IsEmpty())
132 return false;
Tom Sepez5f3e5812020-08-11 22:46:10 +0000133 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepez3466e272020-03-18 23:33:35 +0000134 return pValue->BooleanValue(pIsolate);
135}
136
Tom Sepezd564b0d2020-11-06 18:28:10 +0000137float ReentrantToFloatHelper(v8::Isolate* pIsolate,
138 v8::Local<v8::Value> pValue) {
139 return static_cast<float>(ReentrantToDoubleHelper(pIsolate, pValue));
140}
141
Tom Sepez3466e272020-03-18 23:33:35 +0000142double ReentrantToDoubleHelper(v8::Isolate* pIsolate,
143 v8::Local<v8::Value> pValue) {
144 if (pValue.IsEmpty())
145 return 0.0;
Tom Sepez5f3e5812020-08-11 22:46:10 +0000146 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepez3466e272020-03-18 23:33:35 +0000147 return pValue->NumberValue(pIsolate->GetCurrentContext()).FromMaybe(0.0);
148}
149
150WideString ReentrantToWideStringHelper(v8::Isolate* pIsolate,
151 v8::Local<v8::Value> pValue) {
152 if (pValue.IsEmpty())
153 return WideString();
Tom Sepezc72e23f2020-03-19 18:58:17 +0000154
Tom Sepez5f3e5812020-08-11 22:46:10 +0000155 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepez3466e272020-03-18 23:33:35 +0000156 v8::MaybeLocal<v8::String> maybe_string =
157 pValue->ToString(pIsolate->GetCurrentContext());
158 if (maybe_string.IsEmpty())
159 return WideString();
Tom Sepezc72e23f2020-03-19 18:58:17 +0000160
Tom Sepez494efc72020-11-30 20:50:59 +0000161 return ToWideString(pIsolate, maybe_string.ToLocalChecked());
Tom Sepez3466e272020-03-18 23:33:35 +0000162}
163
164ByteString ReentrantToByteStringHelper(v8::Isolate* pIsolate,
165 v8::Local<v8::Value> pValue) {
166 if (pValue.IsEmpty())
167 return ByteString();
Tom Sepezc72e23f2020-03-19 18:58:17 +0000168
Tom Sepez5f3e5812020-08-11 22:46:10 +0000169 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepez3466e272020-03-18 23:33:35 +0000170 v8::MaybeLocal<v8::String> maybe_string =
171 pValue->ToString(pIsolate->GetCurrentContext());
172 if (maybe_string.IsEmpty())
173 return ByteString();
Tom Sepezc72e23f2020-03-19 18:58:17 +0000174
Tom Sepez494efc72020-11-30 20:50:59 +0000175 return ToByteString(pIsolate, maybe_string.ToLocalChecked());
Tom Sepez3466e272020-03-18 23:33:35 +0000176}
177
Tom Sepez1512c362020-03-19 22:13:52 +0000178v8::Local<v8::Object> ReentrantToObjectHelper(v8::Isolate* pIsolate,
179 v8::Local<v8::Value> pValue) {
Tom Sepezaf6371f2020-11-02 20:13:01 +0000180 if (!fxv8::IsObject(pValue))
Tom Sepez1512c362020-03-19 22:13:52 +0000181 return v8::Local<v8::Object>();
Tom Sepez5f3e5812020-08-11 22:46:10 +0000182
183 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepez1512c362020-03-19 22:13:52 +0000184 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
185 return pValue->ToObject(context).ToLocalChecked();
186}
187
188v8::Local<v8::Array> ReentrantToArrayHelper(v8::Isolate* pIsolate,
189 v8::Local<v8::Value> pValue) {
Tom Sepezaf6371f2020-11-02 20:13:01 +0000190 if (!fxv8::IsArray(pValue))
Tom Sepez1512c362020-03-19 22:13:52 +0000191 return v8::Local<v8::Array>();
Tom Sepez5f3e5812020-08-11 22:46:10 +0000192
193 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepez1512c362020-03-19 22:13:52 +0000194 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
195 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
196}
197
Tom Sepezc72e23f2020-03-19 18:58:17 +0000198v8::Local<v8::Value> ReentrantGetObjectPropertyHelper(
199 v8::Isolate* pIsolate,
200 v8::Local<v8::Object> pObj,
201 ByteStringView bsUTF8PropertyName) {
202 if (pObj.IsEmpty())
203 return v8::Local<v8::Value>();
204
Tom Sepez5f3e5812020-08-11 22:46:10 +0000205 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepezc72e23f2020-03-19 18:58:17 +0000206 v8::Local<v8::Value> val;
207 if (!pObj->Get(pIsolate->GetCurrentContext(),
208 NewStringHelper(pIsolate, bsUTF8PropertyName))
209 .ToLocal(&val)) {
210 return v8::Local<v8::Value>();
211 }
212 return val;
213}
214
215std::vector<WideString> ReentrantGetObjectPropertyNamesHelper(
216 v8::Isolate* pIsolate,
217 v8::Local<v8::Object> pObj) {
218 if (pObj.IsEmpty())
219 return std::vector<WideString>();
220
Tom Sepez5f3e5812020-08-11 22:46:10 +0000221 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepezc72e23f2020-03-19 18:58:17 +0000222 v8::Local<v8::Array> val;
223 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
224 if (!pObj->GetPropertyNames(context).ToLocal(&val))
225 return std::vector<WideString>();
226
227 std::vector<WideString> result;
228 for (uint32_t i = 0; i < val->Length(); ++i) {
229 result.push_back(ReentrantToWideStringHelper(
230 pIsolate, val->Get(context, i).ToLocalChecked()));
231 }
232 return result;
233}
234
Tom Sepezf4874452020-11-09 21:14:06 +0000235bool ReentrantHasObjectOwnPropertyHelper(v8::Isolate* pIsolate,
236 v8::Local<v8::Object> pObj,
Tom Sepez47793dc2021-05-26 20:03:38 +0000237 ByteStringView bsUTF8PropertyName) {
Tom Sepezf4874452020-11-09 21:14:06 +0000238 if (pObj.IsEmpty())
239 return false;
240
241 v8::TryCatch squash_exceptions(pIsolate);
242 v8::Local<v8::Context> pContext = pIsolate->GetCurrentContext();
243 v8::Local<v8::String> hKey =
244 fxv8::NewStringHelper(pIsolate, bsUTF8PropertyName);
Tom Sepez47793dc2021-05-26 20:03:38 +0000245 return pObj->HasRealNamedProperty(pContext, hKey).FromJust();
Tom Sepezf4874452020-11-09 21:14:06 +0000246}
247
248bool ReentrantSetObjectOwnPropertyHelper(v8::Isolate* pIsolate,
249 v8::Local<v8::Object> pObj,
250 ByteStringView bsUTF8PropertyName,
251 v8::Local<v8::Value> pValue) {
Tom Sepezab436ae2020-11-20 19:57:20 +0000252 if (pObj.IsEmpty() || pValue.IsEmpty())
Tom Sepezf4874452020-11-09 21:14:06 +0000253 return false;
254
255 v8::TryCatch squash_exceptions(pIsolate);
256 v8::Local<v8::String> name = NewStringHelper(pIsolate, bsUTF8PropertyName);
257 return pObj->DefineOwnProperty(pIsolate->GetCurrentContext(), name, pValue)
258 .FromMaybe(false);
259}
260
Tom Sepezc72e23f2020-03-19 18:58:17 +0000261bool ReentrantPutObjectPropertyHelper(v8::Isolate* pIsolate,
262 v8::Local<v8::Object> pObj,
263 ByteStringView bsUTF8PropertyName,
264 v8::Local<v8::Value> pPut) {
Tom Sepezab436ae2020-11-20 19:57:20 +0000265 if (pObj.IsEmpty() || pPut.IsEmpty())
Tom Sepezc72e23f2020-03-19 18:58:17 +0000266 return false;
267
Tom Sepez5f3e5812020-08-11 22:46:10 +0000268 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepezc72e23f2020-03-19 18:58:17 +0000269 v8::Local<v8::String> name = NewStringHelper(pIsolate, bsUTF8PropertyName);
Tom Sepez2fb992d2020-03-20 19:45:59 +0000270 v8::Maybe<bool> result = pObj->Set(pIsolate->GetCurrentContext(), name, pPut);
271 return result.IsJust() && result.FromJust();
Tom Sepezc72e23f2020-03-19 18:58:17 +0000272}
273
Tom Sepez4643cf62020-11-09 19:27:05 +0000274void ReentrantDeleteObjectPropertyHelper(v8::Isolate* pIsolate,
275 v8::Local<v8::Object> pObj,
276 ByteStringView bsUTF8PropertyName) {
277 v8::TryCatch squash_exceptions(pIsolate);
278 pObj->Delete(pIsolate->GetCurrentContext(),
279 fxv8::NewStringHelper(pIsolate, bsUTF8PropertyName))
280 .FromJust();
281}
282
Tom Sepez1512c362020-03-19 22:13:52 +0000283bool ReentrantPutArrayElementHelper(v8::Isolate* pIsolate,
284 v8::Local<v8::Array> pArray,
285 unsigned index,
286 v8::Local<v8::Value> pValue) {
287 if (pArray.IsEmpty())
288 return false;
Tom Sepez2fb992d2020-03-20 19:45:59 +0000289
Tom Sepez5f3e5812020-08-11 22:46:10 +0000290 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepez2fb992d2020-03-20 19:45:59 +0000291 v8::Maybe<bool> result =
292 pArray->Set(pIsolate->GetCurrentContext(), index, pValue);
293 return result.IsJust() && result.FromJust();
Tom Sepez1512c362020-03-19 22:13:52 +0000294}
295
296v8::Local<v8::Value> ReentrantGetArrayElementHelper(v8::Isolate* pIsolate,
297 v8::Local<v8::Array> pArray,
298 unsigned index) {
299 if (pArray.IsEmpty())
300 return v8::Local<v8::Value>();
Tom Sepez5f3e5812020-08-11 22:46:10 +0000301
302 v8::TryCatch squash_exceptions(pIsolate);
Tom Sepez1512c362020-03-19 22:13:52 +0000303 v8::Local<v8::Value> val;
304 if (!pArray->Get(pIsolate->GetCurrentContext(), index).ToLocal(&val))
305 return v8::Local<v8::Value>();
306 return val;
307}
308
309unsigned GetArrayLengthHelper(v8::Local<v8::Array> pArray) {
310 if (pArray.IsEmpty())
311 return 0;
312 return pArray->Length();
313}
314
Tom Sepezacc07782020-03-19 20:02:00 +0000315void ThrowExceptionHelper(v8::Isolate* pIsolate, ByteStringView str) {
316 pIsolate->ThrowException(NewStringHelper(pIsolate, str));
317}
318
319void ThrowExceptionHelper(v8::Isolate* pIsolate, WideStringView str) {
320 pIsolate->ThrowException(NewStringHelper(pIsolate, str));
321}
322
Tom Sepez3466e272020-03-18 23:33:35 +0000323} // namespace fxv8