Home | History | Annotate | Download | only in fxjs
      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 
     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 
     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 
     67 CFXJSE_Value::CFXJSE_Value(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {}
     68 
     69 CFXJSE_Value::~CFXJSE_Value() {}
     70 
     71 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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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)
    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 
    348 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 
    357 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 
    366 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 
    375 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 
    384 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 
    393 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 
    402 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 
    411 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 
    420 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 
    429 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 
    438 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 
    445 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 
    452 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 
    459 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 
    466 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 
    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 
    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 
    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 
    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 
    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 
    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 
    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