• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
7 #include "fxjs/cfxjse_value.h"
8 
9 #include <math.h>
10 
11 #include "fxjs/cfxjse_class.h"
12 #include "fxjs/cfxjse_context.h"
13 
14 namespace {
15 
ftod(FX_FLOAT fNumber)16 double ftod(FX_FLOAT fNumber) {
17   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 
FXJSE_ThrowMessage(const CFX_ByteStringC & utf8Message)55 void FXJSE_ThrowMessage(const CFX_ByteStringC& utf8Message) {
56   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(
61       pIsolate, utf8Message.c_str(), v8::String::kNormalString,
62       utf8Message.GetLength());
63   v8::Local<v8::Value> hError = v8::Exception::Error(hMessage);
64   pIsolate->ThrowException(hError);
65 }
66 
CFXJSE_Value(v8::Isolate * pIsolate)67 CFXJSE_Value::CFXJSE_Value(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {}
68 
~CFXJSE_Value()69 CFXJSE_Value::~CFXJSE_Value() {}
70 
ToHostObject(CFXJSE_Class * lpClass) const71 CFXJSE_HostObject* CFXJSE_Value::ToHostObject(CFXJSE_Class* lpClass) const {
72   ASSERT(!m_hValue.IsEmpty());
73 
74   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
75   v8::Local<v8::Value> pValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
76   ASSERT(!pValue.IsEmpty());
77 
78   if (!pValue->IsObject())
79     return nullptr;
80 
81   return FXJSE_RetrieveObjectBinding(pValue.As<v8::Object>(), lpClass);
82 }
83 
SetObject(CFXJSE_HostObject * lpObject,CFXJSE_Class * pClass)84 void CFXJSE_Value::SetObject(CFXJSE_HostObject* lpObject,
85                              CFXJSE_Class* pClass) {
86   if (!pClass) {
87     ASSERT(!lpObject);
88     SetJSObject();
89     return;
90   }
91   SetHostObject(lpObject, pClass);
92 }
93 
SetHostObject(CFXJSE_HostObject * lpObject,CFXJSE_Class * lpClass)94 void CFXJSE_Value::SetHostObject(CFXJSE_HostObject* lpObject,
95                                  CFXJSE_Class* lpClass) {
96   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 
SetArray(const std::vector<std::unique_ptr<CFXJSE_Value>> & values)105 void CFXJSE_Value::SetArray(
106     const std::vector<std::unique_ptr<CFXJSE_Value>>& values) {
107   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
108   v8::Local<v8::Array> hArrayObject = v8::Array::New(m_pIsolate, values.size());
109   uint32_t count = 0;
110   for (auto& v : values) {
111     hArrayObject->Set(count++, v8::Local<v8::Value>::New(
112                                    m_pIsolate, v.get()->DirectGetValue()));
113   }
114   m_hValue.Reset(m_pIsolate, hArrayObject);
115 }
116 
SetDate(double dDouble)117 void CFXJSE_Value::SetDate(double dDouble) {
118   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
119   v8::Local<v8::Value> hDate = v8::Date::New(m_pIsolate, dDouble);
120   m_hValue.Reset(m_pIsolate, hDate);
121 }
122 
SetFloat(FX_FLOAT fFloat)123 void CFXJSE_Value::SetFloat(FX_FLOAT fFloat) {
124   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
125   v8::Local<v8::Value> pValue = v8::Number::New(m_pIsolate, ftod(fFloat));
126   m_hValue.Reset(m_pIsolate, pValue);
127 }
128 
SetObjectProperty(const CFX_ByteStringC & szPropName,CFXJSE_Value * lpPropValue)129 bool CFXJSE_Value::SetObjectProperty(const CFX_ByteStringC& szPropName,
130                                      CFXJSE_Value* lpPropValue) {
131   ASSERT(lpPropValue);
132   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
133   v8::Local<v8::Value> hObject =
134       v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
135   if (!hObject->IsObject())
136     return false;
137 
138   v8::Local<v8::Value> hPropValue =
139       v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->DirectGetValue());
140   return (bool)hObject.As<v8::Object>()->Set(
141       v8::String::NewFromUtf8(m_pIsolate, szPropName.c_str(),
142                               v8::String::kNormalString,
143                               szPropName.GetLength()),
144       hPropValue);
145 }
146 
GetObjectProperty(const CFX_ByteStringC & szPropName,CFXJSE_Value * lpPropValue)147 bool CFXJSE_Value::GetObjectProperty(const CFX_ByteStringC& szPropName,
148                                      CFXJSE_Value* lpPropValue) {
149   ASSERT(lpPropValue);
150   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
151   v8::Local<v8::Value> hObject =
152       v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
153   if (!hObject->IsObject())
154     return false;
155 
156   v8::Local<v8::Value> hPropValue =
157       hObject.As<v8::Object>()->Get(v8::String::NewFromUtf8(
158           m_pIsolate, szPropName.c_str(), v8::String::kNormalString,
159           szPropName.GetLength()));
160   lpPropValue->ForceSetValue(hPropValue);
161   return true;
162 }
163 
SetObjectProperty(uint32_t uPropIdx,CFXJSE_Value * lpPropValue)164 bool CFXJSE_Value::SetObjectProperty(uint32_t uPropIdx,
165                                      CFXJSE_Value* lpPropValue) {
166   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
167   v8::Local<v8::Value> hObject =
168       v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
169   if (!hObject->IsObject())
170     return false;
171 
172   v8::Local<v8::Value> hPropValue =
173       v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->DirectGetValue());
174   return (bool)hObject.As<v8::Object>()->Set(uPropIdx, hPropValue);
175 }
176 
GetObjectPropertyByIdx(uint32_t uPropIdx,CFXJSE_Value * lpPropValue)177 bool CFXJSE_Value::GetObjectPropertyByIdx(uint32_t uPropIdx,
178                                           CFXJSE_Value* lpPropValue) {
179   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
180   v8::Local<v8::Value> hObject =
181       v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
182   if (!hObject->IsObject())
183     return false;
184 
185   v8::Local<v8::Value> hPropValue = hObject.As<v8::Object>()->Get(uPropIdx);
186   lpPropValue->ForceSetValue(hPropValue);
187   return true;
188 }
189 
DeleteObjectProperty(const CFX_ByteStringC & szPropName)190 bool CFXJSE_Value::DeleteObjectProperty(const CFX_ByteStringC& szPropName) {
191   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
192   v8::Local<v8::Value> hObject =
193       v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
194   if (!hObject->IsObject())
195     return false;
196 
197   hObject.As<v8::Object>()->Delete(v8::String::NewFromUtf8(
198       m_pIsolate, szPropName.c_str(), v8::String::kNormalString,
199       szPropName.GetLength()));
200   return true;
201 }
202 
HasObjectOwnProperty(const CFX_ByteStringC & szPropName,bool bUseTypeGetter)203 bool CFXJSE_Value::HasObjectOwnProperty(const CFX_ByteStringC& szPropName,
204                                         bool bUseTypeGetter) {
205   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
206   v8::Local<v8::Value> hObject =
207       v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
208   if (!hObject->IsObject())
209     return false;
210 
211   v8::Local<v8::String> hKey = v8::String::NewFromUtf8(
212       m_pIsolate, szPropName.c_str(), v8::String::kNormalString,
213       szPropName.GetLength());
214   return hObject.As<v8::Object>()->HasRealNamedProperty(hKey) ||
215          (bUseTypeGetter &&
216           hObject.As<v8::Object>()
217               ->HasOwnProperty(m_pIsolate->GetCurrentContext(), hKey)
218               .FromMaybe(false));
219 }
220 
SetObjectOwnProperty(const CFX_ByteStringC & szPropName,CFXJSE_Value * lpPropValue)221 bool CFXJSE_Value::SetObjectOwnProperty(const CFX_ByteStringC& szPropName,
222                                         CFXJSE_Value* lpPropValue) {
223   ASSERT(lpPropValue);
224   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
225   v8::Local<v8::Value> hObject =
226       v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
227   if (!hObject->IsObject())
228     return false;
229 
230   v8::Local<v8::Value> pValue =
231       v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->m_hValue);
232   return hObject.As<v8::Object>()
233       ->DefineOwnProperty(
234           m_pIsolate->GetCurrentContext(),
235           v8::String::NewFromUtf8(m_pIsolate, szPropName.c_str(),
236                                   v8::String::kNormalString,
237                                   szPropName.GetLength()),
238           pValue)
239       .FromMaybe(false);
240 }
241 
SetFunctionBind(CFXJSE_Value * lpOldFunction,CFXJSE_Value * lpNewThis)242 bool CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction,
243                                    CFXJSE_Value* lpNewThis) {
244   ASSERT(lpOldFunction && lpNewThis);
245 
246   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
247   v8::Local<v8::Value> rgArgs[2];
248   v8::Local<v8::Value> hOldFunction =
249       v8::Local<v8::Value>::New(m_pIsolate, lpOldFunction->DirectGetValue());
250   if (hOldFunction.IsEmpty() || !hOldFunction->IsFunction())
251     return false;
252 
253   rgArgs[0] = hOldFunction;
254   v8::Local<v8::Value> hNewThis =
255       v8::Local<v8::Value>::New(m_pIsolate, lpNewThis->DirectGetValue());
256   if (hNewThis.IsEmpty())
257     return false;
258 
259   rgArgs[1] = hNewThis;
260   v8::Local<v8::String> hBinderFuncSource =
261       v8::String::NewFromUtf8(m_pIsolate,
262                               "(function (oldfunction, newthis) { return "
263                               "oldfunction.bind(newthis); })");
264   v8::Local<v8::Function> hBinderFunc =
265       v8::Script::Compile(hBinderFuncSource)->Run().As<v8::Function>();
266   v8::Local<v8::Value> hBoundFunction =
267       hBinderFunc->Call(m_pIsolate->GetCurrentContext()->Global(), 2, rgArgs);
268   if (hBoundFunction.IsEmpty() || !hBoundFunction->IsFunction())
269     return false;
270 
271   m_hValue.Reset(m_pIsolate, hBoundFunction);
272   return true;
273 }
274 
275 #define FXJSE_INVALID_PTR ((void*)(intptr_t)-1)
Call(CFXJSE_Value * lpReceiver,CFXJSE_Value * lpRetValue,uint32_t nArgCount,CFXJSE_Value ** lpArgs)276 bool CFXJSE_Value::Call(CFXJSE_Value* lpReceiver,
277                         CFXJSE_Value* lpRetValue,
278                         uint32_t nArgCount,
279                         CFXJSE_Value** lpArgs) {
280   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
281   v8::Local<v8::Value> hFunctionValue =
282       v8::Local<v8::Value>::New(m_pIsolate, DirectGetValue());
283   v8::Local<v8::Object> hFunctionObject =
284       !hFunctionValue.IsEmpty() && hFunctionValue->IsObject()
285           ? hFunctionValue.As<v8::Object>()
286           : v8::Local<v8::Object>();
287 
288   v8::TryCatch trycatch(m_pIsolate);
289   if (hFunctionObject.IsEmpty() || !hFunctionObject->IsCallable()) {
290     if (lpRetValue)
291       lpRetValue->ForceSetValue(FXJSE_CreateReturnValue(m_pIsolate, trycatch));
292     return false;
293   }
294 
295   v8::Local<v8::Value> hReturnValue;
296   v8::Local<v8::Value>* lpLocalArgs = NULL;
297   if (nArgCount) {
298     lpLocalArgs = FX_Alloc(v8::Local<v8::Value>, nArgCount);
299     for (uint32_t i = 0; i < nArgCount; i++) {
300       new (lpLocalArgs + i) v8::Local<v8::Value>;
301       CFXJSE_Value* lpArg = lpArgs[i];
302       if (lpArg) {
303         lpLocalArgs[i] =
304             v8::Local<v8::Value>::New(m_pIsolate, lpArg->DirectGetValue());
305       }
306       if (lpLocalArgs[i].IsEmpty()) {
307         lpLocalArgs[i] = v8::Undefined(m_pIsolate);
308       }
309     }
310   }
311 
312   bool bRetValue = true;
313   if (lpReceiver == FXJSE_INVALID_PTR) {
314     v8::MaybeLocal<v8::Value> maybe_retvalue =
315         hFunctionObject->CallAsConstructor(m_pIsolate->GetCurrentContext(),
316                                            nArgCount, lpLocalArgs);
317     hReturnValue = maybe_retvalue.FromMaybe(v8::Local<v8::Value>());
318   } else {
319     v8::Local<v8::Value> hReceiver;
320     if (lpReceiver) {
321       hReceiver =
322           v8::Local<v8::Value>::New(m_pIsolate, lpReceiver->DirectGetValue());
323     }
324     if (hReceiver.IsEmpty() || !hReceiver->IsObject())
325       hReceiver = v8::Object::New(m_pIsolate);
326 
327     v8::MaybeLocal<v8::Value> maybe_retvalue = hFunctionObject->CallAsFunction(
328         m_pIsolate->GetCurrentContext(), hReceiver, nArgCount, lpLocalArgs);
329     hReturnValue = maybe_retvalue.FromMaybe(v8::Local<v8::Value>());
330   }
331 
332   if (trycatch.HasCaught()) {
333     hReturnValue = FXJSE_CreateReturnValue(m_pIsolate, trycatch);
334     bRetValue = false;
335   }
336 
337   if (lpRetValue)
338     lpRetValue->ForceSetValue(hReturnValue);
339 
340   if (lpLocalArgs) {
341     for (uint32_t i = 0; i < nArgCount; i++)
342       lpLocalArgs[i].~Local();
343     FX_Free(lpLocalArgs);
344   }
345   return bRetValue;
346 }
347 
IsUndefined() const348 bool CFXJSE_Value::IsUndefined() const {
349   if (m_hValue.IsEmpty())
350     return false;
351 
352   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
353   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
354   return hValue->IsUndefined();
355 }
356 
IsNull() const357 bool CFXJSE_Value::IsNull() const {
358   if (m_hValue.IsEmpty())
359     return false;
360 
361   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
362   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
363   return hValue->IsNull();
364 }
365 
IsBoolean() const366 bool CFXJSE_Value::IsBoolean() const {
367   if (m_hValue.IsEmpty())
368     return false;
369 
370   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
371   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
372   return hValue->IsBoolean();
373 }
374 
IsString() const375 bool CFXJSE_Value::IsString() const {
376   if (m_hValue.IsEmpty())
377     return false;
378 
379   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
380   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
381   return hValue->IsString();
382 }
383 
IsNumber() const384 bool CFXJSE_Value::IsNumber() const {
385   if (m_hValue.IsEmpty())
386     return false;
387 
388   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
389   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
390   return hValue->IsNumber();
391 }
392 
IsInteger() const393 bool CFXJSE_Value::IsInteger() const {
394   if (m_hValue.IsEmpty())
395     return false;
396 
397   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
398   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
399   return hValue->IsInt32();
400 }
401 
IsObject() const402 bool CFXJSE_Value::IsObject() const {
403   if (m_hValue.IsEmpty())
404     return false;
405 
406   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
407   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
408   return hValue->IsObject();
409 }
410 
IsArray() const411 bool CFXJSE_Value::IsArray() const {
412   if (m_hValue.IsEmpty())
413     return false;
414 
415   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
416   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
417   return hValue->IsArray();
418 }
419 
IsFunction() const420 bool CFXJSE_Value::IsFunction() const {
421   if (m_hValue.IsEmpty())
422     return false;
423 
424   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
425   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
426   return hValue->IsFunction();
427 }
428 
IsDate() const429 bool CFXJSE_Value::IsDate() const {
430   if (m_hValue.IsEmpty())
431     return false;
432 
433   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
434   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
435   return hValue->IsDate();
436 }
437 
ToBoolean() const438 bool CFXJSE_Value::ToBoolean() const {
439   ASSERT(!m_hValue.IsEmpty());
440   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
441   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
442   return static_cast<bool>(hValue->BooleanValue());
443 }
444 
ToFloat() const445 FX_FLOAT CFXJSE_Value::ToFloat() const {
446   ASSERT(!m_hValue.IsEmpty());
447   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
448   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
449   return static_cast<FX_FLOAT>(hValue->NumberValue());
450 }
451 
ToDouble() const452 double CFXJSE_Value::ToDouble() const {
453   ASSERT(!m_hValue.IsEmpty());
454   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
455   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
456   return static_cast<double>(hValue->NumberValue());
457 }
458 
ToInteger() const459 int32_t CFXJSE_Value::ToInteger() const {
460   ASSERT(!m_hValue.IsEmpty());
461   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
462   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
463   return static_cast<int32_t>(hValue->NumberValue());
464 }
465 
ToString() const466 CFX_ByteString CFXJSE_Value::ToString() const {
467   ASSERT(!m_hValue.IsEmpty());
468   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
469   v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
470   v8::Local<v8::String> hString = hValue->ToString();
471   v8::String::Utf8Value hStringVal(hString);
472   return CFX_ByteString(*hStringVal);
473 }
474 
SetUndefined()475 void CFXJSE_Value::SetUndefined() {
476   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
477   v8::Local<v8::Value> hValue = v8::Undefined(m_pIsolate);
478   m_hValue.Reset(m_pIsolate, hValue);
479 }
480 
SetNull()481 void CFXJSE_Value::SetNull() {
482   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
483   v8::Local<v8::Value> hValue = v8::Null(m_pIsolate);
484   m_hValue.Reset(m_pIsolate, hValue);
485 }
486 
SetBoolean(bool bBoolean)487 void CFXJSE_Value::SetBoolean(bool bBoolean) {
488   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
489   v8::Local<v8::Value> hValue = v8::Boolean::New(m_pIsolate, bBoolean != false);
490   m_hValue.Reset(m_pIsolate, hValue);
491 }
492 
SetInteger(int32_t nInteger)493 void CFXJSE_Value::SetInteger(int32_t nInteger) {
494   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
495   v8::Local<v8::Value> hValue = v8::Integer::New(m_pIsolate, nInteger);
496   m_hValue.Reset(m_pIsolate, hValue);
497 }
498 
SetDouble(double dDouble)499 void CFXJSE_Value::SetDouble(double dDouble) {
500   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
501   v8::Local<v8::Value> hValue = v8::Number::New(m_pIsolate, dDouble);
502   m_hValue.Reset(m_pIsolate, hValue);
503 }
504 
SetString(const CFX_ByteStringC & szString)505 void CFXJSE_Value::SetString(const CFX_ByteStringC& szString) {
506   CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
507   v8::Local<v8::Value> hValue = v8::String::NewFromUtf8(
508       m_pIsolate, reinterpret_cast<const char*>(szString.raw_str()),
509       v8::String::kNormalString, szString.GetLength());
510   m_hValue.Reset(m_pIsolate, hValue);
511 }
512 
SetJSObject()513 void CFXJSE_Value::SetJSObject() {
514   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
515   v8::Local<v8::Value> hValue = v8::Object::New(m_pIsolate);
516   m_hValue.Reset(m_pIsolate, hValue);
517 }
518