blob: b1fc0784e8d23d770288ee61e397ea42eeea8dde [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// Copyright 2014 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
dsinclair08fea802016-07-12 10:37:52 -07007#include "fxjs/include/cfxjse_value.h"
Dan Sinclair1770c022016-03-14 14:14:16 -04008
9#include <math.h>
10
dsinclair08fea802016-07-12 10:37:52 -070011#include "fxjs/include/cfxjse_class.h"
12#include "fxjs/include/cfxjse_context.h"
Dan Sinclair1770c022016-03-14 14:14:16 -040013
dsinclair4044d2d2016-06-13 12:38:29 -070014namespace {
15
dsinclair08fea802016-07-12 10:37:52 -070016double ftod(FX_FLOAT fNumber) {
dsinclair4044d2d2016-06-13 12:38:29 -070017 static_assert(sizeof(FX_FLOAT) == 4, "FX_FLOAT of incorrect size");
18
19 uint32_t nFloatBits = (uint32_t&)fNumber;
20 uint8_t nExponent = (uint8_t)(nFloatBits >> 23);
21 if (nExponent == 0 || nExponent == 255)
22 return fNumber;
23
24 int8_t nErrExp = nExponent - 150;
25 if (nErrExp >= 0)
26 return fNumber;
27
28 double dwError = pow(2.0, nErrExp), dwErrorHalf = dwError / 2;
29 double dNumber = fNumber, dNumberAbs = fabs(fNumber);
30 double dNumberAbsMin = dNumberAbs - dwErrorHalf,
31 dNumberAbsMax = dNumberAbs + dwErrorHalf;
32 int32_t iErrPos = 0;
33 if (floor(dNumberAbsMin) == floor(dNumberAbsMax)) {
34 dNumberAbsMin = fmod(dNumberAbsMin, 1.0);
35 dNumberAbsMax = fmod(dNumberAbsMax, 1.0);
36 int32_t iErrPosMin = 1, iErrPosMax = 38;
37 do {
38 int32_t iMid = (iErrPosMin + iErrPosMax) / 2;
39 double dPow = pow(10.0, iMid);
40 if (floor(dNumberAbsMin * dPow) == floor(dNumberAbsMax * dPow)) {
41 iErrPosMin = iMid + 1;
42 } else {
43 iErrPosMax = iMid;
44 }
45 } while (iErrPosMin < iErrPosMax);
46 iErrPos = iErrPosMax;
47 }
48 double dPow = pow(10.0, iErrPos);
49 return fNumber < 0 ? ceil(dNumber * dPow - 0.5) / dPow
50 : floor(dNumber * dPow + 0.5) / dPow;
51}
52
53} // namespace
54
dsinclair769b1372016-06-08 13:12:41 -070055void FXJSE_ThrowMessage(const CFX_ByteStringC& utf8Message) {
Dan Sinclair1770c022016-03-14 14:14:16 -040056 v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
57 ASSERT(pIsolate);
58
59 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
60 v8::Local<v8::String> hMessage = v8::String::NewFromUtf8(
dsinclair179bebb2016-04-05 11:02:18 -070061 pIsolate, utf8Message.c_str(), v8::String::kNormalString,
Dan Sinclair1770c022016-03-14 14:14:16 -040062 utf8Message.GetLength());
dsinclair769b1372016-06-08 13:12:41 -070063 v8::Local<v8::Value> hError = v8::Exception::Error(hMessage);
Dan Sinclair1770c022016-03-14 14:14:16 -040064 pIsolate->ThrowException(hError);
65}
66
weilieec3a362016-06-18 06:25:37 -070067CFXJSE_Value::CFXJSE_Value(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {}
68
69CFXJSE_Value::~CFXJSE_Value() {}
70
dsinclair8f3074b2016-06-02 17:45:25 -070071CFXJSE_HostObject* CFXJSE_Value::ToHostObject(CFXJSE_Class* lpClass) const {
Dan Sinclair1770c022016-03-14 14:14:16 -040072 ASSERT(!m_hValue.IsEmpty());
73
74 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
dsinclair12a6b0c2016-05-26 11:14:08 -070075 v8::Local<v8::Value> pValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
76 ASSERT(!pValue.IsEmpty());
Dan Sinclair1770c022016-03-14 14:14:16 -040077
dsinclair12a6b0c2016-05-26 11:14:08 -070078 if (!pValue->IsObject())
Dan Sinclair1770c022016-03-14 14:14:16 -040079 return nullptr;
80
dsinclair12a6b0c2016-05-26 11:14:08 -070081 return FXJSE_RetrieveObjectBinding(pValue.As<v8::Object>(), lpClass);
Dan Sinclair1770c022016-03-14 14:14:16 -040082}
83
dsinclairf27aeec2016-06-07 19:36:18 -070084void CFXJSE_Value::SetObject(CFXJSE_HostObject* lpObject,
85 CFXJSE_Class* pClass) {
86 if (!pClass) {
87 ASSERT(!lpObject);
88 SetJSObject();
89 return;
Dan Sinclair1770c022016-03-14 14:14:16 -040090 }
dsinclairf27aeec2016-06-07 19:36:18 -070091 SetHostObject(lpObject, pClass);
Dan Sinclair1770c022016-03-14 14:14:16 -040092}
93
tsepez29adee72016-05-31 14:22:09 -070094void CFXJSE_Value::SetHostObject(CFXJSE_HostObject* lpObject,
95 CFXJSE_Class* lpClass) {
Dan Sinclair1770c022016-03-14 14:14:16 -040096 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
97 ASSERT(lpClass);
98 v8::Local<v8::FunctionTemplate> hClass =
99 v8::Local<v8::FunctionTemplate>::New(m_pIsolate, lpClass->m_hTemplate);
100 v8::Local<v8::Object> hObject = hClass->InstanceTemplate()->NewInstance();
101 FXJSE_UpdateObjectBinding(hObject, lpObject);
102 m_hValue.Reset(m_pIsolate, hObject);
103}
104
105void CFXJSE_Value::SetArray(uint32_t uValueCount, CFXJSE_Value** rgValues) {
106 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
107 v8::Local<v8::Array> hArrayObject = v8::Array::New(m_pIsolate, uValueCount);
108 if (rgValues) {
109 for (uint32_t i = 0; i < uValueCount; i++) {
110 if (rgValues[i]) {
111 hArrayObject->Set(i, v8::Local<v8::Value>::New(
112 m_pIsolate, rgValues[i]->DirectGetValue()));
113 }
114 }
115 }
116 m_hValue.Reset(m_pIsolate, hArrayObject);
117}
118
dsinclair04fd27b2016-03-30 12:59:04 -0700119void CFXJSE_Value::SetDate(double dDouble) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400120 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
121 v8::Local<v8::Value> hDate = v8::Date::New(m_pIsolate, dDouble);
122 m_hValue.Reset(m_pIsolate, hDate);
123}
124
dsinclair4044d2d2016-06-13 12:38:29 -0700125void CFXJSE_Value::SetFloat(FX_FLOAT fFloat) {
126 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
dsinclair08fea802016-07-12 10:37:52 -0700127 v8::Local<v8::Value> pValue = v8::Number::New(m_pIsolate, ftod(fFloat));
dsinclair4044d2d2016-06-13 12:38:29 -0700128 m_hValue.Reset(m_pIsolate, pValue);
129}
130
Dan Sinclair1770c022016-03-14 14:14:16 -0400131FX_BOOL CFXJSE_Value::SetObjectProperty(const CFX_ByteStringC& szPropName,
132 CFXJSE_Value* lpPropValue) {
dsinclairf27aeec2016-06-07 19:36:18 -0700133 ASSERT(lpPropValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400134 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
135 v8::Local<v8::Value> hObject =
136 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
137 if (!hObject->IsObject())
138 return FALSE;
139
140 v8::Local<v8::Value> hPropValue =
141 v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->DirectGetValue());
142 return (FX_BOOL)hObject.As<v8::Object>()->Set(
dsinclair179bebb2016-04-05 11:02:18 -0700143 v8::String::NewFromUtf8(m_pIsolate, szPropName.c_str(),
Dan Sinclair1770c022016-03-14 14:14:16 -0400144 v8::String::kNormalString,
145 szPropName.GetLength()),
146 hPropValue);
147}
148
149FX_BOOL CFXJSE_Value::GetObjectProperty(const CFX_ByteStringC& szPropName,
150 CFXJSE_Value* lpPropValue) {
dsinclairf27aeec2016-06-07 19:36:18 -0700151 ASSERT(lpPropValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400152 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
153 v8::Local<v8::Value> hObject =
154 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
155 if (!hObject->IsObject())
156 return FALSE;
157
158 v8::Local<v8::Value> hPropValue =
159 hObject.As<v8::Object>()->Get(v8::String::NewFromUtf8(
dsinclair179bebb2016-04-05 11:02:18 -0700160 m_pIsolate, szPropName.c_str(), v8::String::kNormalString,
Dan Sinclair1770c022016-03-14 14:14:16 -0400161 szPropName.GetLength()));
162 lpPropValue->ForceSetValue(hPropValue);
163 return TRUE;
164}
165
166FX_BOOL CFXJSE_Value::SetObjectProperty(uint32_t uPropIdx,
167 CFXJSE_Value* lpPropValue) {
168 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
169 v8::Local<v8::Value> hObject =
170 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
171 if (!hObject->IsObject())
172 return FALSE;
173
174 v8::Local<v8::Value> hPropValue =
175 v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->DirectGetValue());
176 return (FX_BOOL)hObject.As<v8::Object>()->Set(uPropIdx, hPropValue);
177}
178
dsinclairf27aeec2016-06-07 19:36:18 -0700179FX_BOOL CFXJSE_Value::GetObjectPropertyByIdx(uint32_t uPropIdx,
180 CFXJSE_Value* lpPropValue) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400181 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
182 v8::Local<v8::Value> hObject =
183 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
184 if (!hObject->IsObject())
185 return FALSE;
186
187 v8::Local<v8::Value> hPropValue = hObject.As<v8::Object>()->Get(uPropIdx);
188 lpPropValue->ForceSetValue(hPropValue);
189 return TRUE;
190}
191
192FX_BOOL CFXJSE_Value::DeleteObjectProperty(const CFX_ByteStringC& szPropName) {
193 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
194 v8::Local<v8::Value> hObject =
195 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
196 if (!hObject->IsObject())
197 return FALSE;
198
199 hObject.As<v8::Object>()->Delete(v8::String::NewFromUtf8(
dsinclair179bebb2016-04-05 11:02:18 -0700200 m_pIsolate, szPropName.c_str(), v8::String::kNormalString,
Dan Sinclair1770c022016-03-14 14:14:16 -0400201 szPropName.GetLength()));
202 return TRUE;
203}
204
205FX_BOOL CFXJSE_Value::HasObjectOwnProperty(const CFX_ByteStringC& szPropName,
206 FX_BOOL bUseTypeGetter) {
207 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
208 v8::Local<v8::Value> hObject =
209 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
210 if (!hObject->IsObject())
211 return FALSE;
212
213 v8::Local<v8::String> hKey = v8::String::NewFromUtf8(
dsinclair179bebb2016-04-05 11:02:18 -0700214 m_pIsolate, szPropName.c_str(), v8::String::kNormalString,
Dan Sinclair1770c022016-03-14 14:14:16 -0400215 szPropName.GetLength());
216 return hObject.As<v8::Object>()->HasRealNamedProperty(hKey) ||
217 (bUseTypeGetter &&
218 hObject.As<v8::Object>()
219 ->HasOwnProperty(m_pIsolate->GetCurrentContext(), hKey)
220 .FromMaybe(false));
221}
222
223FX_BOOL CFXJSE_Value::SetObjectOwnProperty(const CFX_ByteStringC& szPropName,
224 CFXJSE_Value* lpPropValue) {
dsinclairf27aeec2016-06-07 19:36:18 -0700225 ASSERT(lpPropValue);
Dan Sinclair1770c022016-03-14 14:14:16 -0400226 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
227 v8::Local<v8::Value> hObject =
228 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
229 if (!hObject->IsObject())
230 return FALSE;
231
dsinclair12a6b0c2016-05-26 11:14:08 -0700232 v8::Local<v8::Value> pValue =
Dan Sinclair1770c022016-03-14 14:14:16 -0400233 v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->m_hValue);
234 return hObject.As<v8::Object>()
235 ->DefineOwnProperty(
236 m_pIsolate->GetCurrentContext(),
dsinclair179bebb2016-04-05 11:02:18 -0700237 v8::String::NewFromUtf8(m_pIsolate, szPropName.c_str(),
Dan Sinclair1770c022016-03-14 14:14:16 -0400238 v8::String::kNormalString,
239 szPropName.GetLength()),
dsinclair12a6b0c2016-05-26 11:14:08 -0700240 pValue)
Dan Sinclair1770c022016-03-14 14:14:16 -0400241 .FromMaybe(false);
242}
243
244FX_BOOL CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction,
245 CFXJSE_Value* lpNewThis) {
dsinclairf27aeec2016-06-07 19:36:18 -0700246 ASSERT(lpOldFunction && lpNewThis);
247
Dan Sinclair1770c022016-03-14 14:14:16 -0400248 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
249 v8::Local<v8::Value> rgArgs[2];
250 v8::Local<v8::Value> hOldFunction =
251 v8::Local<v8::Value>::New(m_pIsolate, lpOldFunction->DirectGetValue());
252 if (hOldFunction.IsEmpty() || !hOldFunction->IsFunction())
253 return FALSE;
254
255 rgArgs[0] = hOldFunction;
256 v8::Local<v8::Value> hNewThis =
257 v8::Local<v8::Value>::New(m_pIsolate, lpNewThis->DirectGetValue());
258 if (hNewThis.IsEmpty())
259 return FALSE;
260
261 rgArgs[1] = hNewThis;
262 v8::Local<v8::String> hBinderFuncSource =
263 v8::String::NewFromUtf8(m_pIsolate,
264 "(function (oldfunction, newthis) { return "
265 "oldfunction.bind(newthis); })");
266 v8::Local<v8::Function> hBinderFunc =
267 v8::Script::Compile(hBinderFuncSource)->Run().As<v8::Function>();
268 v8::Local<v8::Value> hBoundFunction =
269 hBinderFunc->Call(m_pIsolate->GetCurrentContext()->Global(), 2, rgArgs);
270 if (hBoundFunction.IsEmpty() || !hBoundFunction->IsFunction())
271 return FALSE;
272
273 m_hValue.Reset(m_pIsolate, hBoundFunction);
274 return TRUE;
275}
276
277#define FXJSE_INVALID_PTR ((void*)(intptr_t)-1)
278FX_BOOL CFXJSE_Value::Call(CFXJSE_Value* lpReceiver,
279 CFXJSE_Value* lpRetValue,
280 uint32_t nArgCount,
dsinclair12a6b0c2016-05-26 11:14:08 -0700281 CFXJSE_Value** lpArgs) {
Dan Sinclair1770c022016-03-14 14:14:16 -0400282 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
283 v8::Local<v8::Value> hFunctionValue =
284 v8::Local<v8::Value>::New(m_pIsolate, DirectGetValue());
285 v8::Local<v8::Object> hFunctionObject =
286 !hFunctionValue.IsEmpty() && hFunctionValue->IsObject()
287 ? hFunctionValue.As<v8::Object>()
288 : v8::Local<v8::Object>();
289
290 v8::TryCatch trycatch(m_pIsolate);
291 if (hFunctionObject.IsEmpty() || !hFunctionObject->IsCallable()) {
292 if (lpRetValue)
293 lpRetValue->ForceSetValue(FXJSE_CreateReturnValue(m_pIsolate, trycatch));
294 return FALSE;
295 }
296
297 v8::Local<v8::Value> hReturnValue;
298 v8::Local<v8::Value>* lpLocalArgs = NULL;
299 if (nArgCount) {
300 lpLocalArgs = FX_Alloc(v8::Local<v8::Value>, nArgCount);
301 for (uint32_t i = 0; i < nArgCount; i++) {
302 new (lpLocalArgs + i) v8::Local<v8::Value>;
dsinclair12a6b0c2016-05-26 11:14:08 -0700303 CFXJSE_Value* lpArg = lpArgs[i];
Dan Sinclair1770c022016-03-14 14:14:16 -0400304 if (lpArg) {
305 lpLocalArgs[i] =
306 v8::Local<v8::Value>::New(m_pIsolate, lpArg->DirectGetValue());
307 }
308 if (lpLocalArgs[i].IsEmpty()) {
309 lpLocalArgs[i] = v8::Undefined(m_pIsolate);
310 }
311 }
312 }
313
314 FX_BOOL bRetValue = TRUE;
315 if (lpReceiver == FXJSE_INVALID_PTR) {
316 v8::MaybeLocal<v8::Value> maybe_retvalue =
317 hFunctionObject->CallAsConstructor(m_pIsolate->GetCurrentContext(),
318 nArgCount, lpLocalArgs);
319 hReturnValue = maybe_retvalue.FromMaybe(v8::Local<v8::Value>());
320 } else {
321 v8::Local<v8::Value> hReceiver;
322 if (lpReceiver) {
323 hReceiver =
324 v8::Local<v8::Value>::New(m_pIsolate, lpReceiver->DirectGetValue());
325 }
326 if (hReceiver.IsEmpty() || !hReceiver->IsObject())
327 hReceiver = v8::Object::New(m_pIsolate);
328
329 v8::MaybeLocal<v8::Value> maybe_retvalue = hFunctionObject->CallAsFunction(
330 m_pIsolate->GetCurrentContext(), hReceiver, nArgCount, lpLocalArgs);
331 hReturnValue = maybe_retvalue.FromMaybe(v8::Local<v8::Value>());
332 }
333
334 if (trycatch.HasCaught()) {
335 hReturnValue = FXJSE_CreateReturnValue(m_pIsolate, trycatch);
336 bRetValue = FALSE;
337 }
338
339 if (lpRetValue)
340 lpRetValue->ForceSetValue(hReturnValue);
341
342 if (lpLocalArgs) {
343 for (uint32_t i = 0; i < nArgCount; i++)
344 lpLocalArgs[i].~Local();
345 FX_Free(lpLocalArgs);
346 }
347 return bRetValue;
348}
dsinclair08fea802016-07-12 10:37:52 -0700349
350FX_BOOL CFXJSE_Value::IsUndefined() const {
351 if (m_hValue.IsEmpty())
352 return FALSE;
353
354 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
355 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
356 return hValue->IsUndefined();
357}
358
359FX_BOOL CFXJSE_Value::IsNull() const {
360 if (m_hValue.IsEmpty())
361 return FALSE;
362
363 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
364 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
365 return hValue->IsNull();
366}
367
368FX_BOOL CFXJSE_Value::IsBoolean() const {
369 if (m_hValue.IsEmpty())
370 return FALSE;
371
372 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
373 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
374 return hValue->IsBoolean();
375}
376
377FX_BOOL CFXJSE_Value::IsString() const {
378 if (m_hValue.IsEmpty())
379 return FALSE;
380
381 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
382 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
383 return hValue->IsString();
384}
385
386FX_BOOL CFXJSE_Value::IsNumber() const {
387 if (m_hValue.IsEmpty())
388 return FALSE;
389
390 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
391 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
392 return hValue->IsNumber();
393}
394
395FX_BOOL CFXJSE_Value::IsInteger() const {
396 if (m_hValue.IsEmpty())
397 return FALSE;
398
399 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
400 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
401 return hValue->IsInt32();
402}
403
404FX_BOOL CFXJSE_Value::IsObject() const {
405 if (m_hValue.IsEmpty())
406 return FALSE;
407
408 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
409 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
410 return hValue->IsObject();
411}
412
413FX_BOOL CFXJSE_Value::IsArray() const {
414 if (m_hValue.IsEmpty())
415 return FALSE;
416
417 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
418 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
419 return hValue->IsArray();
420}
421
422FX_BOOL CFXJSE_Value::IsFunction() const {
423 if (m_hValue.IsEmpty())
424 return FALSE;
425
426 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
427 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
428 return hValue->IsFunction();
429}
430
431FX_BOOL CFXJSE_Value::IsDate() const {
432 if (m_hValue.IsEmpty())
433 return FALSE;
434
435 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
436 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
437 return hValue->IsDate();
438}
439
440FX_BOOL CFXJSE_Value::ToBoolean() const {
441 ASSERT(!m_hValue.IsEmpty());
442 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
443 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
444 return static_cast<FX_BOOL>(hValue->BooleanValue());
445}
446
447FX_FLOAT CFXJSE_Value::ToFloat() const {
448 ASSERT(!m_hValue.IsEmpty());
449 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
450 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
451 return static_cast<FX_FLOAT>(hValue->NumberValue());
452}
453
454double CFXJSE_Value::ToDouble() const {
455 ASSERT(!m_hValue.IsEmpty());
456 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
457 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
458 return static_cast<double>(hValue->NumberValue());
459}
460
461int32_t CFXJSE_Value::ToInteger() const {
462 ASSERT(!m_hValue.IsEmpty());
463 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
464 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
465 return static_cast<int32_t>(hValue->NumberValue());
466}
467
468CFX_ByteString CFXJSE_Value::ToString() const {
469 ASSERT(!m_hValue.IsEmpty());
470 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
471 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
472 v8::Local<v8::String> hString = hValue->ToString();
473 v8::String::Utf8Value hStringVal(hString);
474 return CFX_ByteString(*hStringVal);
475}
476
477void CFXJSE_Value::SetUndefined() {
478 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
479 v8::Local<v8::Value> hValue = v8::Undefined(m_pIsolate);
480 m_hValue.Reset(m_pIsolate, hValue);
481}
482
483void CFXJSE_Value::SetNull() {
484 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
485 v8::Local<v8::Value> hValue = v8::Null(m_pIsolate);
486 m_hValue.Reset(m_pIsolate, hValue);
487}
488
489void CFXJSE_Value::SetBoolean(FX_BOOL bBoolean) {
490 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
491 v8::Local<v8::Value> hValue = v8::Boolean::New(m_pIsolate, bBoolean != FALSE);
492 m_hValue.Reset(m_pIsolate, hValue);
493}
494
495void CFXJSE_Value::SetInteger(int32_t nInteger) {
496 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
497 v8::Local<v8::Value> hValue = v8::Integer::New(m_pIsolate, nInteger);
498 m_hValue.Reset(m_pIsolate, hValue);
499}
500
501void CFXJSE_Value::SetDouble(double dDouble) {
502 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
503 v8::Local<v8::Value> hValue = v8::Number::New(m_pIsolate, dDouble);
504 m_hValue.Reset(m_pIsolate, hValue);
505}
506
507void CFXJSE_Value::SetString(const CFX_ByteStringC& szString) {
508 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
509 v8::Local<v8::Value> hValue = v8::String::NewFromUtf8(
510 m_pIsolate, reinterpret_cast<const char*>(szString.raw_str()),
511 v8::String::kNormalString, szString.GetLength());
512 m_hValue.Reset(m_pIsolate, hValue);
513}
514
515void CFXJSE_Value::SetJSObject() {
516 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
517 v8::Local<v8::Value> hValue = v8::Object::New(m_pIsolate);
518 m_hValue.Reset(m_pIsolate, hValue);
519}