Remove backpointer to CJS_Runtime from CJS_Value

Review-Url: https://codereview.chromium.org/2227673005
diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp
index 8175fba..40e1312 100644
--- a/fpdfsdk/javascript/Document.cpp
+++ b/fpdfsdk/javascript/Document.cpp
@@ -201,10 +201,8 @@
 FX_BOOL Document::ADBE(IJS_Context* cc,
                        CJS_PropValue& vp,
                        CFX_WideString& sError) {
-  if (vp.IsGetting()) {
-    vp.SetNull();
-  } else {
-  }
+  if (vp.IsGetting())
+    vp.GetJSValue()->SetNull(CJS_Runtime::FromContext(cc));
 
   return TRUE;
 }
@@ -283,31 +281,33 @@
                            const std::vector<CJS_Value>& params,
                            CJS_Value& vRet,
                            CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
   if (params.size() < 1) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  CFX_WideString wideName = params[0].ToCFXWideString();
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
 
+  CFX_WideString wideName = params[0].ToCFXWideString(pIsolate);
   CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
   CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
   if (pPDFForm->CountFields(wideName) <= 0) {
-    vRet.SetNull();
+    vRet.SetNull(pRuntime);
     return TRUE;
   }
 
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  v8::Local<v8::Object> pFieldObj = FXJS_NewFxDynamicObj(
-      pRuntime->GetIsolate(), pRuntime, CJS_Field::g_nObjDefnID);
+  v8::Local<v8::Object> pFieldObj =
+      FXJS_NewFxDynamicObj(pIsolate, pRuntime, CJS_Field::g_nObjDefnID);
 
-  v8::Isolate* isolate = GetIsolate(cc);
-  CJS_Field* pJSField = (CJS_Field*)FXJS_GetPrivate(isolate, pFieldObj);
-  Field* pField = (Field*)pJSField->GetEmbedObject();
+  CJS_Field* pJSField =
+      static_cast<CJS_Field*>(FXJS_GetPrivate(pIsolate, pFieldObj));
+  Field* pField = static_cast<Field*>(pJSField->GetEmbedObject());
   pField->AttachField(this, wideName);
 
-  vRet = pJSField;
+  vRet = CJS_Value(pRuntime, pJSField);
   return TRUE;
 }
 
@@ -316,13 +316,17 @@
                                   const std::vector<CJS_Value>& params,
                                   CJS_Value& vRet,
                                   CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
   if (params.size() != 1) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  int nIndex = params[0].ToInt();
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+
+  int nIndex = params[0].ToInt(pIsolate);
   if (nIndex < 0) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
     return FALSE;
@@ -334,7 +338,7 @@
   if (!pField)
     return FALSE;
 
-  vRet = pField->GetFullName().c_str();
+  vRet = CJS_Value(pRuntime, pField->GetFullName().c_str());
   return TRUE;
 }
 
@@ -373,28 +377,30 @@
                            const std::vector<CJS_Value>& params,
                            CJS_Value& vRet,
                            CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
   if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
     return FALSE;
 
   int iLength = params.size();
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
 
-  FX_BOOL bUI = iLength > 0 ? params[0].ToBool() : TRUE;
-  CFX_WideString cTo = iLength > 1 ? params[1].ToCFXWideString() : L"";
-  CFX_WideString cCc = iLength > 2 ? params[2].ToCFXWideString() : L"";
-  CFX_WideString cBcc = iLength > 3 ? params[3].ToCFXWideString() : L"";
-  CFX_WideString cSubject = iLength > 4 ? params[4].ToCFXWideString() : L"";
-  CFX_WideString cMsg = iLength > 5 ? params[5].ToCFXWideString() : L"";
+  FX_BOOL bUI = iLength > 0 ? params[0].ToBool(pIsolate) : TRUE;
+  CFX_WideString cTo = iLength > 1 ? params[1].ToCFXWideString(pIsolate) : L"";
+  CFX_WideString cCc = iLength > 2 ? params[2].ToCFXWideString(pIsolate) : L"";
+  CFX_WideString cBcc = iLength > 3 ? params[3].ToCFXWideString(pIsolate) : L"";
+  CFX_WideString cSubject =
+      iLength > 4 ? params[4].ToCFXWideString(pIsolate) : L"";
+  CFX_WideString cMsg = iLength > 5 ? params[5].ToCFXWideString(pIsolate) : L"";
 
   CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
   CFX_ByteTextBuf textBuf;
   if (!pInterForm->ExportFormToFDFTextBuf(textBuf))
     return FALSE;
 
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CPDFDoc_Environment* pEnv = pContext->GetReaderApp();
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-
   pRuntime->BeginBlock();
+  CPDFDoc_Environment* pEnv = pContext->GetReaderApp();
   pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI,
                        cTo.c_str(), cSubject.c_str(), cCc.c_str(), cBcc.c_str(),
                        cMsg.c_str());
@@ -406,6 +412,10 @@
                         const std::vector<CJS_Value>& params,
                         CJS_Value& vRet,
                         CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+
   FX_BOOL bUI = TRUE;
   int nStart = 0;
   int nEnd = 0;
@@ -418,9 +428,9 @@
   int nlength = params.size();
   if (nlength == 9) {
     if (params[8].GetType() == CJS_Value::VT_object) {
-      v8::Local<v8::Object> pObj = params[8].ToV8Object();
+      v8::Local<v8::Object> pObj = params[8].ToV8Object(pIsolate);
       if (FXJS_GetObjDefnID(pObj) == CJS_PrintParamsObj::g_nObjDefnID) {
-        if (CJS_Object* pJSObj = params[8].ToCJSObject()) {
+        if (CJS_Object* pJSObj = params[8].ToCJSObject(pIsolate)) {
           if (PrintParamsObj* pprintparamsObj =
                   static_cast<PrintParamsObj*>(pJSObj->GetEmbedObject())) {
             bUI = pprintparamsObj->bUI;
@@ -437,21 +447,21 @@
     }
   } else {
     if (nlength >= 1)
-      bUI = params[0].ToBool();
+      bUI = params[0].ToBool(pIsolate);
     if (nlength >= 2)
-      nStart = params[1].ToInt();
+      nStart = params[1].ToInt(pIsolate);
     if (nlength >= 3)
-      nEnd = params[2].ToInt();
+      nEnd = params[2].ToInt(pIsolate);
     if (nlength >= 4)
-      bSilent = params[3].ToBool();
+      bSilent = params[3].ToBool(pIsolate);
     if (nlength >= 5)
-      bShrinkToFit = params[4].ToBool();
+      bShrinkToFit = params[4].ToBool(pIsolate);
     if (nlength >= 6)
-      bPrintAsImage = params[5].ToBool();
+      bPrintAsImage = params[5].ToBool(pIsolate);
     if (nlength >= 7)
-      bReverse = params[6].ToBool();
+      bReverse = params[6].ToBool(pIsolate);
     if (nlength >= 8)
-      bAnnotations = params[7].ToBool();
+      bAnnotations = params[7].ToBool(pIsolate);
   }
 
   if (CPDFDoc_Environment* pEnv = m_pDocument->GetEnv()) {
@@ -474,13 +484,17 @@
         m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM)))
     return FALSE;
 
-  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
   if (params.size() != 1) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  CFX_WideString sFieldName = params[0].ToCFXWideString();
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+
+  CFX_WideString sFieldName = params[0].ToCFXWideString(pIsolate);
   CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
   std::vector<CPDFSDK_Widget*> widgets;
   pInterForm->GetWidgets(sFieldName, &widgets);
@@ -515,6 +529,8 @@
                             const std::vector<CJS_Value>& params,
                             CJS_Value& vRet,
                             CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
   if (!(m_pDocument->GetPermissions(FPDFPERM_MODIFY) ||
         m_pDocument->GetPermissions(FPDFPERM_ANNOT_FORM) ||
         m_pDocument->GetPermissions(FPDFPERM_FILL_FORM)))
@@ -522,7 +538,6 @@
 
   CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
   CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_Array aName;
 
   if (params.empty()) {
@@ -531,9 +546,12 @@
     return TRUE;
   }
 
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+
   switch (params[0].GetType()) {
     default:
-      aName.Attach(params[0].ToV8Array());
+      aName.Attach(params[0].ToV8Array(pIsolate));
       break;
     case CJS_Value::VT_string:
       aName.SetElement(pRuntime->GetIsolate(), 0, params[0]);
@@ -544,7 +562,7 @@
   for (int i = 0, isz = aName.GetLength(); i < isz; ++i) {
     CJS_Value valElement(pRuntime);
     aName.GetElement(pRuntime->GetIsolate(), i, valElement);
-    CFX_WideString swVal = valElement.ToCFXWideString();
+    CFX_WideString swVal = valElement.ToCFXWideString(pIsolate);
     for (int j = 0, jsz = pPDFForm->CountFields(swVal); j < jsz; ++j)
       aFields.push_back(pPDFForm->GetField(j, swVal));
   }
@@ -569,43 +587,46 @@
                              const std::vector<CJS_Value>& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
   int nSize = params.size();
   if (nSize < 1) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  v8::Isolate* isolate = pRuntime->GetIsolate();
   CJS_Array aFields;
   CFX_WideString strURL;
   FX_BOOL bFDF = TRUE;
   FX_BOOL bEmpty = FALSE;
 
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+
   CJS_Value v = params[0];
   if (v.GetType() == CJS_Value::VT_string) {
-    strURL = params[0].ToCFXWideString();
+    strURL = params[0].ToCFXWideString(pIsolate);
     if (nSize > 1)
-      bFDF = params[1].ToBool();
+      bFDF = params[1].ToBool(pIsolate);
     if (nSize > 2)
-      bEmpty = params[2].ToBool();
+      bEmpty = params[2].ToBool(pIsolate);
     if (nSize > 3)
-      aFields.Attach(params[3].ToV8Array());
+      aFields.Attach(params[3].ToV8Array(pIsolate));
   } else if (v.GetType() == CJS_Value::VT_object) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
-    v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"cURL");
+    v8::Local<v8::Object> pObj = params[0].ToV8Object(pIsolate);
+    v8::Local<v8::Value> pValue =
+        FXJS_GetObjectElement(pIsolate, pObj, L"cURL");
     if (!pValue.IsEmpty())
-      strURL = CJS_Value(pRuntime, pValue).ToCFXWideString();
+      strURL = CJS_Value(pRuntime, pValue).ToCFXWideString(pIsolate);
 
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"bFDF");
-    bFDF = CJS_Value(pRuntime, pValue).ToBool();
+    pValue = FXJS_GetObjectElement(pIsolate, pObj, L"bFDF");
+    bFDF = CJS_Value(pRuntime, pValue).ToBool(pIsolate);
 
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"bEmpty");
-    bEmpty = CJS_Value(pRuntime, pValue).ToBool();
+    pValue = FXJS_GetObjectElement(pIsolate, pObj, L"bEmpty");
+    bEmpty = CJS_Value(pRuntime, pValue).ToBool(pIsolate);
 
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"aFields");
-    aFields.Attach(CJS_Value(pRuntime, pValue).ToV8Array());
+    pValue = FXJS_GetObjectElement(pIsolate, pObj, L"aFields");
+    aFields.Attach(CJS_Value(pRuntime, pValue).ToV8Array(pIsolate));
   }
 
   CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
@@ -624,7 +645,7 @@
     CJS_Value valName(pRuntime);
     aFields.GetElement(pRuntime->GetIsolate(), i, valName);
 
-    CFX_WideString sName = valName.ToCFXWideString();
+    CFX_WideString sName = valName.ToCFXWideString(pIsolate);
     CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
     for (int j = 0, jsz = pPDFForm->CountFields(sName); j < jsz; ++j) {
       CPDF_FormField* pField = pPDFForm->GetField(j, sName);
@@ -661,6 +682,10 @@
                           const std::vector<CJS_Value>& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
+  // TODO(tsepez): Check maximum number of allowed params.
+
   FX_BOOL bUI = TRUE;
   CFX_WideString cTo = L"";
   CFX_WideString cCc = L"";
@@ -668,42 +693,42 @@
   CFX_WideString cSubject = L"";
   CFX_WideString cMsg = L"";
 
-  if (params.size() >= 1)
-    bUI = params[0].ToBool();
-  if (params.size() >= 2)
-    cTo = params[1].ToCFXWideString();
-  if (params.size() >= 3)
-    cCc = params[2].ToCFXWideString();
-  if (params.size() >= 4)
-    cBcc = params[3].ToCFXWideString();
-  if (params.size() >= 5)
-    cSubject = params[4].ToCFXWideString();
-  if (params.size() >= 6)
-    cMsg = params[5].ToCFXWideString();
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
 
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-  v8::Isolate* isolate = pRuntime->GetIsolate();
+  if (params.size() >= 1)
+    bUI = params[0].ToBool(pIsolate);
+  if (params.size() >= 2)
+    cTo = params[1].ToCFXWideString(pIsolate);
+  if (params.size() >= 3)
+    cCc = params[2].ToCFXWideString(pIsolate);
+  if (params.size() >= 4)
+    cBcc = params[3].ToCFXWideString(pIsolate);
+  if (params.size() >= 5)
+    cSubject = params[4].ToCFXWideString(pIsolate);
+  if (params.size() >= 6)
+    cMsg = params[5].ToCFXWideString(pIsolate);
 
   if (params.size() >= 1 && params[0].GetType() == CJS_Value::VT_object) {
-    v8::Local<v8::Object> pObj = params[0].ToV8Object();
+    v8::Local<v8::Object> pObj = params[0].ToV8Object(pIsolate);
 
-    v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"bUI");
-    bUI = CJS_Value(pRuntime, pValue).ToInt();
+    v8::Local<v8::Value> pValue = FXJS_GetObjectElement(pIsolate, pObj, L"bUI");
+    bUI = CJS_Value(pRuntime, pValue).ToInt(pIsolate);
 
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cTo");
-    cTo = CJS_Value(pRuntime, pValue).ToCFXWideString();
+    pValue = FXJS_GetObjectElement(pIsolate, pObj, L"cTo");
+    cTo = CJS_Value(pRuntime, pValue).ToCFXWideString(pIsolate);
 
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cCc");
-    cCc = CJS_Value(pRuntime, pValue).ToCFXWideString();
+    pValue = FXJS_GetObjectElement(pIsolate, pObj, L"cCc");
+    cCc = CJS_Value(pRuntime, pValue).ToCFXWideString(pIsolate);
 
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cBcc");
-    cBcc = CJS_Value(pRuntime, pValue).ToCFXWideString();
+    pValue = FXJS_GetObjectElement(pIsolate, pObj, L"cBcc");
+    cBcc = CJS_Value(pRuntime, pValue).ToCFXWideString(pIsolate);
 
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cSubject");
-    cSubject = CJS_Value(pRuntime, pValue).ToCFXWideString();
+    pValue = FXJS_GetObjectElement(pIsolate, pObj, L"cSubject");
+    cSubject = CJS_Value(pRuntime, pValue).ToCFXWideString(pIsolate);
 
-    pValue = FXJS_GetObjectElement(isolate, pObj, L"cMsg");
-    cMsg = CJS_Value(pRuntime, pValue).ToCFXWideString();
+    pValue = FXJS_GetObjectElement(pIsolate, pObj, L"cMsg");
+    cMsg = CJS_Value(pRuntime, pValue).ToCFXWideString(pIsolate);
   }
 
   pRuntime->BeginBlock();
@@ -1028,7 +1053,7 @@
                             const std::vector<CJS_Value>& params,
                             CJS_Value& vRet,
                             CFX_WideString& sError) {
-  vRet.SetNull();
+  vRet.SetNull(CJS_Runtime::FromContext(cc));
   return TRUE;
 }
 
@@ -1036,7 +1061,7 @@
                              const std::vector<CJS_Value>& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
-  vRet.SetNull();
+  vRet.SetNull(CJS_Runtime::FromContext(cc));
   return TRUE;
 }
 
@@ -1044,7 +1069,6 @@
                               const std::vector<CJS_Value>& params,
                               CJS_Value& vRet,
                               CFX_WideString& sError) {
-  vRet = CJS_Value::VT_undefined;
   return TRUE;
 }
 
@@ -1071,25 +1095,30 @@
                           const std::vector<CJS_Value>& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
   if (params.size() != 2) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
-  CFX_WideString swIconName = params[0].ToCFXWideString();
+
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+
+  CFX_WideString swIconName = params[0].ToCFXWideString(pIsolate);
 
   if (params[1].GetType() != CJS_Value::VT_object) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
     return FALSE;
   }
 
-  v8::Local<v8::Object> pJSIcon = params[1].ToV8Object();
+  v8::Local<v8::Object> pJSIcon = params[1].ToV8Object(pIsolate);
   if (FXJS_GetObjDefnID(pJSIcon) != CJS_Icon::g_nObjDefnID) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
     return FALSE;
   }
 
-  CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject()->GetEmbedObject();
+  CJS_EmbedObj* pEmbedObj = params[1].ToCJSObject(pIsolate)->GetEmbedObject();
   if (!pEmbedObj) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSTYPEERROR);
     return FALSE;
@@ -1103,18 +1132,18 @@
 FX_BOOL Document::icons(IJS_Context* cc,
                         CJS_PropValue& vp,
                         CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
   if (vp.IsSetting()) {
-    CJS_Context* pContext = static_cast<CJS_Context*>(cc);
     sError = JSGetStringFromID(pContext, IDS_STRING_JSREADONLY);
     return FALSE;
   }
 
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   if (m_IconList.empty()) {
-    vp.SetNull();
+    vp.GetJSValue()->SetNull(pRuntime);
     return TRUE;
   }
 
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_Array Icons;
 
   int i = 0;
@@ -1146,7 +1175,7 @@
                           const std::vector<CJS_Value>& params,
                           CJS_Value& vRet,
                           CFX_WideString& sError) {
-  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
   if (params.size() != 1) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
@@ -1155,8 +1184,10 @@
   if (m_IconList.empty())
     return FALSE;
 
-  CFX_WideString swIconName = params[0].ToCFXWideString();
   CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+
+  CFX_WideString swIconName = params[0].ToCFXWideString(pIsolate);
 
   for (const auto& pIconElement : m_IconList) {
     if (pIconElement->IconName == swIconName) {
@@ -1177,7 +1208,7 @@
 
       pIcon->SetIconName(swIconName);
       pIcon->SetStream(pRetIcon->GetStream());
-      vRet = pJS_Icon;
+      vRet = CJS_Value(pRuntime, pJS_Icon);
       return TRUE;
     }
   }
@@ -1231,18 +1262,24 @@
                                  const std::vector<CJS_Value>& params,
                                  CJS_Value& vRet,
                                  CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
+  // TODO(tsepez): check maximum allowable params.
+
   if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
     return FALSE;
 
-  int nPageNo = params.size() > 0 ? params[0].ToInt() : 0;
-  int nWordNo = params.size() > 1 ? params[1].ToInt() : 0;
-  bool bStrip = params.size() > 2 ? params[2].ToBool() : true;
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+
+  int nPageNo = params.size() > 0 ? params[0].ToInt(pIsolate) : 0;
+  int nWordNo = params.size() > 1 ? params[1].ToInt(pIsolate) : 0;
+  bool bStrip = params.size() > 2 ? params[2].ToBool(pIsolate) : true;
 
   CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
   if (!pDocument)
     return FALSE;
 
-  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
   if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
     return FALSE;
@@ -1274,7 +1311,7 @@
     swRet.TrimRight();
   }
 
-  vRet = swRet.c_str();
+  vRet = CJS_Value(pRuntime, swRet.c_str());
   return TRUE;
 }
 
@@ -1292,12 +1329,16 @@
                                   const std::vector<CJS_Value>& params,
                                   CJS_Value& vRet,
                                   CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+
   if (!m_pDocument->GetPermissions(FPDFPERM_EXTRACT_ACCESS))
     return FALSE;
 
-  int nPageNo = params.size() > 0 ? params[0].ToInt() : 0;
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  v8::Isolate* pIsolate = pRuntime->GetIsolate();
+
+  int nPageNo = params.size() > 0 ? params[0].ToInt(pIsolate) : 0;
   CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
-  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
   if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount()) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
     return FALSE;
@@ -1316,7 +1357,7 @@
       nWords += CountWords(pPageObj->AsText());
   }
 
-  vRet = nWords;
+  vRet = CJS_Value(pRuntime, nWords);
   return TRUE;
 }
 
@@ -1331,7 +1372,7 @@
 
   // Not implemented yet.
 
-  vRet = pRetObj;
+  vRet = CJS_Value(pRuntime, pRetObj);
   return TRUE;
 }
 
@@ -1474,18 +1515,20 @@
                                 CJS_Value& vRet,
                                 CFX_WideString& sError) {
   CJS_Context* context = (CJS_Context*)cc;
+
   if (params.size() != 1) {
     sError = JSGetStringFromID(context, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
+  CJS_Runtime* runtime = context->GetJSRuntime();
+  CFX_WideString wideName = params[0].ToCFXWideString(runtime->GetIsolate());
+  CFX_ByteString utf8Name = wideName.UTF8Encode();
+
   CPDF_Document* pDocument = m_pDocument->GetPDFDocument();
   if (!pDocument)
     return FALSE;
 
-  CFX_WideString wideName = params[0].ToCFXWideString();
-  CFX_ByteString utf8Name = wideName.UTF8Encode();
-
   CPDF_NameTree nameTree(pDocument, "Dests");
   CPDF_Array* destArray = nameTree.LookupNamedDest(pDocument, utf8Name);
   if (!destArray)
@@ -1505,7 +1548,6 @@
     scrollPositionArraySize = j;
   }
 
-  CJS_Runtime* runtime = context->GetJSRuntime();
   runtime->BeginBlock();
   CPDFDoc_Environment* pApp = m_pDocument->GetEnv();
   pApp->FFI_DoGoToAction(dest.GetPageIndex(pDocument), dest.GetZoomMode(),
diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp
index 34a2466..8528881 100644
--- a/fpdfsdk/javascript/Field.cpp
+++ b/fpdfsdk/javascript/Field.cpp
@@ -955,18 +955,18 @@
       return FALSE;
 
     std::vector<uint32_t> array;
-    if (vp.GetType() == CJS_Value::VT_number) {
+    if (vp.GetJSValue()->GetType() == CJS_Value::VT_number) {
       int iSelecting = 0;
       vp >> iSelecting;
       array.push_back(iSelecting);
-    } else if (vp.IsArrayObject()) {
+    } else if (vp.GetJSValue()->IsArrayObject()) {
       CJS_Array SelArray;
       CJS_Value SelValue(pRuntime);
       int iSelecting;
       vp >> SelArray;
       for (int i = 0, sz = SelArray.GetLength(); i < sz; i++) {
         SelArray.GetElement(pRuntime->GetIsolate(), i, SelValue);
-        iSelecting = SelValue.ToInt();
+        iSelecting = SelValue.ToInt(pRuntime->GetIsolate());
         array.push_back(iSelecting);
       }
     }
@@ -1375,7 +1375,7 @@
     if (!m_bCanSet)
       return FALSE;
 
-    if (!vp.IsArrayObject())
+    if (!vp.GetJSValue()->IsArrayObject())
       return FALSE;
   } else {
     CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
@@ -1444,7 +1444,7 @@
     if (!m_bCanSet)
       return FALSE;
 
-    if (!vp.IsArrayObject())
+    if (!vp.GetJSValue()->IsArrayObject())
       return FALSE;
 
     vp >> crArray;
@@ -2084,7 +2084,7 @@
   if (vp.IsSetting()) {
     if (!m_bCanSet)
       return FALSE;
-    if (!vp.IsArrayObject())
+    if (!vp.GetJSValue()->IsArrayObject())
       return FALSE;
 
     CJS_Array rcArray;
@@ -2095,10 +2095,14 @@
     rcArray.GetElement(pRuntime->GetIsolate(), 3, Lower_Righty);
 
     FX_FLOAT pArray[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-    pArray[0] = (FX_FLOAT)Upper_Leftx.ToInt();
-    pArray[1] = (FX_FLOAT)Lower_Righty.ToInt();
-    pArray[2] = (FX_FLOAT)Lower_Rightx.ToInt();
-    pArray[3] = (FX_FLOAT)Upper_Lefty.ToInt();
+    pArray[0] =
+        static_cast<FX_FLOAT>(Upper_Leftx.ToInt(pRuntime->GetIsolate()));
+    pArray[1] =
+        static_cast<FX_FLOAT>(Lower_Righty.ToInt(pRuntime->GetIsolate()));
+    pArray[2] =
+        static_cast<FX_FLOAT>(Lower_Rightx.ToInt(pRuntime->GetIsolate()));
+    pArray[3] =
+        static_cast<FX_FLOAT>(Upper_Lefty.ToInt(pRuntime->GetIsolate()));
 
     CFX_FloatRect crRect(pArray);
     if (m_bDelay) {
@@ -2119,10 +2123,10 @@
       return FALSE;
 
     CFX_FloatRect crRect = pWidget->GetRect();
-    Upper_Leftx = (int32_t)crRect.left;
-    Upper_Lefty = (int32_t)crRect.top;
-    Lower_Rightx = (int32_t)crRect.right;
-    Lower_Righty = (int32_t)crRect.bottom;
+    Upper_Leftx = CJS_Value(pRuntime, static_cast<int32_t>(crRect.left));
+    Upper_Lefty = CJS_Value(pRuntime, static_cast<int32_t>(crRect.top));
+    Lower_Rightx = CJS_Value(pRuntime, static_cast<int32_t>(crRect.right));
+    Lower_Righty = CJS_Value(pRuntime, static_cast<int32_t>(crRect.bottom));
 
     CJS_Array rcArray;
     rcArray.SetElement(pRuntime->GetIsolate(), 0, Upper_Leftx);
@@ -2309,7 +2313,7 @@
     if (!m_bCanSet)
       return FALSE;
 
-    if (!vp.IsArrayObject())
+    if (!vp.GetJSValue()->IsArrayObject())
       return FALSE;
 
     vp >> crArray;
@@ -2454,7 +2458,7 @@
     if (!m_bCanSet)
       return FALSE;
 
-    if (!vp.IsArrayObject())
+    if (!vp.GetJSValue()->IsArrayObject())
       return FALSE;
 
     vp >> crArray;
@@ -2698,13 +2702,14 @@
       return FALSE;
 
     std::vector<CFX_WideString> strArray;
-    if (vp.IsArrayObject()) {
+    if (vp.GetJSValue()->IsArrayObject()) {
       CJS_Array ValueArray;
-      vp.ConvertToArray(ValueArray);
+      vp.GetJSValue()->ConvertToArray(pRuntime->GetIsolate(), ValueArray);
       for (int i = 0, sz = ValueArray.GetLength(); i < sz; i++) {
         CJS_Value ElementValue(pRuntime);
         ValueArray.GetElement(pRuntime->GetIsolate(), i, ElementValue);
-        strArray.push_back(ElementValue.ToCFXWideString());
+        strArray.push_back(
+            ElementValue.ToCFXWideString(pRuntime->GetIsolate()));
       }
     } else {
       CFX_WideString swValue;
@@ -2737,9 +2742,14 @@
           int iIndex;
           for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
             iIndex = pFormField->GetSelectedIndex(i);
-            ElementValue = pFormField->GetOptionValue(iIndex).c_str();
-            if (FXSYS_wcslen(ElementValue.ToCFXWideString().c_str()) == 0)
-              ElementValue = pFormField->GetOptionLabel(iIndex).c_str();
+            ElementValue =
+                CJS_Value(pRuntime, pFormField->GetOptionValue(iIndex).c_str());
+            if (FXSYS_wcslen(
+                    ElementValue.ToCFXWideString(pRuntime->GetIsolate())
+                        .c_str()) == 0) {
+              ElementValue = CJS_Value(
+                  pRuntime, pFormField->GetOptionLabel(iIndex).c_str());
+            }
             ValueArray.SetElement(pRuntime->GetIsolate(), i, ElementValue);
           }
           vp << ValueArray;
@@ -2765,7 +2775,7 @@
         break;
     }
   }
-  vp.MaybeCoerceToNumber();
+  vp.GetJSValue()->MaybeCoerceToNumber(m_isolate);
   return TRUE;
 }
 
@@ -2891,10 +2901,12 @@
                                 const std::vector<CJS_Value>& params,
                                 CJS_Value& vRet,
                                 CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
   int nface = 0;
   int iSize = params.size();
   if (iSize >= 1)
-    nface = params[0].ToInt();
+    nface = params[0].ToInt(pRuntime->GetIsolate());
 
   std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
   if (FieldArray.empty())
@@ -2909,11 +2921,11 @@
     return FALSE;
 
   if (nface == 0)
-    vRet = pFormControl->GetNormalCaption().c_str();
+    vRet = CJS_Value(pRuntime, pFormControl->GetNormalCaption().c_str());
   else if (nface == 1)
-    vRet = pFormControl->GetDownCaption().c_str();
+    vRet = CJS_Value(pRuntime, pFormControl->GetDownCaption().c_str());
   else if (nface == 2)
-    vRet = pFormControl->GetRolloverCaption().c_str();
+    vRet = CJS_Value(pRuntime, pFormControl->GetRolloverCaption().c_str());
   else
     return FALSE;
 
@@ -2924,10 +2936,13 @@
                              const std::vector<CJS_Value>& params,
                              CJS_Value& vRet,
                              CFX_WideString& sError) {
+  CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+
   int nface = 0;
   int iSize = params.size();
   if (iSize >= 1)
-    nface = params[0].ToInt();
+    nface = params[0].ToInt(pRuntime->GetIsolate());
 
   std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
   if (FieldArray.empty())
@@ -2941,8 +2956,6 @@
   if (!pFormControl)
     return FALSE;
 
-  CJS_Context* pContext = (CJS_Context*)cc;
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
   v8::Local<v8::Object> pObj = FXJS_NewFxDynamicObj(
       pRuntime->GetIsolate(), pRuntime, CJS_Icon::g_nObjDefnID);
   ASSERT(pObj.IsEmpty() == FALSE);
@@ -2961,8 +2974,7 @@
     return FALSE;
 
   pIcon->SetStream(pIconStream);
-  vRet = pJS_Icon;
-
+  vRet = CJS_Value(pRuntime, pJS_Icon);
   return TRUE;
 }
 
@@ -2991,20 +3003,19 @@
                             const std::vector<CJS_Value>& params,
                             CJS_Value& vRet,
                             CFX_WideString& sError) {
-  ASSERT(m_pDocument);
-
-  if (!m_bCanSet)
-    return FALSE;
-
   int iSize = params.size();
   if (iSize < 1)
     return FALSE;
 
-  int nWidget = params[0].ToInt();
+  if (!m_bCanSet)
+    return FALSE;
+
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int nWidget = params[0].ToInt(pRuntime->GetIsolate());
 
   bool bCheckit = true;
   if (iSize >= 2)
-    bCheckit = params[1].ToBool();
+    bCheckit = params[1].ToBool(pRuntime->GetIsolate());
 
   std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
   if (FieldArray.empty())
@@ -3045,19 +3056,20 @@
   if (iSize < 1)
     return FALSE;
 
-  int nWidget = params[0].ToInt();
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int nWidget = params[0].ToInt(pRuntime->GetIsolate());
 
   std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
   if (FieldArray.empty())
     return FALSE;
 
   CPDF_FormField* pFormField = FieldArray[0];
-  if (nWidget < 0 || nWidget >= pFormField->CountControls()) {
-    vRet = FALSE;
+  if (nWidget < 0 || nWidget >= pFormField->CountControls())
     return FALSE;
-  }
-  vRet = pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
-         pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON;
+
+  vRet = CJS_Value(pRuntime,
+                   pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
+                       pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON);
 
   return TRUE;
 }
@@ -3102,10 +3114,8 @@
         static_cast<CJS_Field*>(FXJS_GetPrivate(pRuntime->GetIsolate(), pObj));
     Field* pField = static_cast<Field*>(pJSField->GetEmbedObject());
     pField->AttachField(m_pJSDoc, *pStr);
-
-    CJS_Value FormFieldValue(pRuntime);
-    FormFieldValue = pJSField;
-    FormFieldArray.SetElement(pRuntime->GetIsolate(), j++, FormFieldValue);
+    FormFieldArray.SetElement(pRuntime->GetIsolate(), j++,
+                              CJS_Value(pRuntime, pJSField));
   }
 
   vRet = CJS_Value(pRuntime, FormFieldArray);
@@ -3116,15 +3126,16 @@
                          const std::vector<CJS_Value>& params,
                          CJS_Value& vRet,
                          CFX_WideString& sError) {
-  int iSize = params.size();
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
 
+  int iSize = params.size();
   int nIdx = -1;
   if (iSize >= 1)
-    nIdx = params[0].ToInt();
+    nIdx = params[0].ToInt(pRuntime->GetIsolate());
 
   FX_BOOL bExport = TRUE;
   if (iSize >= 2)
-    bExport = params[1].ToBool();
+    bExport = params[1].ToBool(pRuntime->GetIsolate());
 
   std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
   if (FieldArray.empty())
@@ -3138,11 +3149,11 @@
     if (bExport) {
       CFX_WideString strval = pFormField->GetOptionValue(nIdx);
       if (strval.IsEmpty())
-        vRet = pFormField->GetOptionLabel(nIdx).c_str();
+        vRet = CJS_Value(pRuntime, pFormField->GetOptionLabel(nIdx).c_str());
       else
-        vRet = strval.c_str();
+        vRet = CJS_Value(pRuntime, strval.c_str());
     } else {
-      vRet = pFormField->GetOptionLabel(nIdx).c_str();
+      vRet = CJS_Value(pRuntime, pFormField->GetOptionLabel(nIdx).c_str());
     }
   } else {
     return FALSE;
@@ -3169,9 +3180,11 @@
                             const std::vector<CJS_Value>& params,
                             CJS_Value& vRet,
                             CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
   int nIndex = -1;
   if (params.size() >= 1)
-    nIndex = params[0].ToInt();
+    nIndex = params[0].ToInt(pRuntime->GetIsolate());
 
   std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
   if (FieldArray.empty())
@@ -3179,20 +3192,13 @@
 
   CPDF_FormField* pFormField = FieldArray[0];
   if (nIndex < 0 || nIndex >= pFormField->CountControls()) {
-    vRet = FALSE;
     return FALSE;
   }
 
-  if ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX) ||
-      (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON)) {
-    if (pFormField->GetControl(nIndex)->IsChecked() != 0)
-      vRet = TRUE;
-    else
-      vRet = FALSE;
-  } else {
-    vRet = FALSE;
-  }
-
+  vRet = CJS_Value(pRuntime,
+                   ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
+                     pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON) &&
+                    pFormField->GetControl(nIndex)->IsChecked() != 0));
   return TRUE;
 }
 
@@ -3200,29 +3206,24 @@
                                 const std::vector<CJS_Value>& params,
                                 CJS_Value& vRet,
                                 CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
   int nIndex = -1;
   if (params.size() >= 1)
-    nIndex = params[0].ToInt();
+    nIndex = params[0].ToInt(pRuntime->GetIsolate());
 
   std::vector<CPDF_FormField*> FieldArray = GetFormFields(m_FieldName);
   if (FieldArray.empty())
     return FALSE;
 
   CPDF_FormField* pFormField = FieldArray[0];
-  if (nIndex < 0 || nIndex >= pFormField->CountControls()) {
-    vRet = FALSE;
+  if (nIndex < 0 || nIndex >= pFormField->CountControls())
     return FALSE;
-  }
-  if ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX) ||
-      (pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON)) {
-    if (pFormField->GetControl(nIndex)->IsDefaultChecked() != 0)
-      vRet = TRUE;
-    else
-      vRet = FALSE;
-  } else {
-    vRet = FALSE;
-  }
 
+  vRet = CJS_Value(pRuntime,
+                   ((pFormField->GetFieldType() == FIELDTYPE_CHECKBOX ||
+                     pFormField->GetFieldType() == FIELDTYPE_RADIOBUTTON) &&
+                    pFormField->GetControl(nIndex)->IsDefaultChecked() != 0));
   return TRUE;
 }
 
diff --git a/fpdfsdk/javascript/JS_Define.h b/fpdfsdk/javascript/JS_Define.h
index e120758..4c24a4d 100644
--- a/fpdfsdk/javascript/JS_Define.h
+++ b/fpdfsdk/javascript/JS_Define.h
@@ -92,7 +92,7 @@
                                             sError));
     return;
   }
-  info.GetReturnValue().Set(value.ToV8Value());
+  info.GetReturnValue().Set(value.GetJSValue()->ToV8Value(isolate));
 }
 
 template <class C,
@@ -111,7 +111,7 @@
   CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
   C* pObj = reinterpret_cast<C*>(pJSObj->GetEmbedObject());
   CFX_WideString sError;
-  CJS_PropValue propValue(CJS_Value(pRuntime, value));
+  CJS_PropValue propValue(pRuntime, CJS_Value(pRuntime, value));
   propValue.StartSetting();
   if (!(pObj->*M)(pContext, propValue, sError)) {
     FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
@@ -160,7 +160,7 @@
                                             method_name_string, sError));
     return;
   }
-  info.GetReturnValue().Set(valueRes.ToV8Value());
+  info.GetReturnValue().Set(valueRes.ToV8Value(isolate));
 }
 
 #define JS_STATIC_METHOD(method_name, class_name)                             \
@@ -383,7 +383,7 @@
     FXJS_Error(isolate, JSFormatErrorString(class_name, "GetProperty", sError));
     return;
   }
-  info.GetReturnValue().Set(value.ToV8Value());
+  info.GetReturnValue().Set(value.GetJSValue()->ToV8Value(isolate));
 }
 
 template <class Alt>
@@ -404,7 +404,7 @@
   CFX_WideString propname = CFX_WideString::FromUTF8(
       CFX_ByteStringC(*utf8_value, utf8_value.length()));
   CFX_WideString sError;
-  CJS_PropValue PropValue(CJS_Value(pRuntime, value));
+  CJS_PropValue PropValue(pRuntime, CJS_Value(pRuntime, value));
   PropValue.StartSetting();
   if (!pObj->DoProperty(pContext, propname.c_str(), PropValue, sError)) {
     FXJS_Error(isolate, JSFormatErrorString(class_name, "PutProperty", sError));
@@ -456,7 +456,7 @@
                JSFormatErrorString(func_name_string, nullptr, sError));
     return;
   }
-  info.GetReturnValue().Set(valueRes.ToV8Value());
+  info.GetReturnValue().Set(valueRes.ToV8Value(pRuntime->GetIsolate()));
 }
 
 #define JS_STATIC_GLOBAL_FUN(fun_name)                   \
diff --git a/fpdfsdk/javascript/JS_Object.cpp b/fpdfsdk/javascript/JS_Object.cpp
index d970297..d67ceeb 100644
--- a/fpdfsdk/javascript/JS_Object.cpp
+++ b/fpdfsdk/javascript/JS_Object.cpp
@@ -13,7 +13,6 @@
 CJS_EmbedObj::CJS_EmbedObj(CJS_Object* pJSObject) : m_pJSObject(pJSObject) {}
 
 CJS_EmbedObj::~CJS_EmbedObj() {
-  m_pJSObject = nullptr;
 }
 
 void FreeObject(const v8::WeakCallbackInfo<CJS_Object>& data) {
diff --git a/fpdfsdk/javascript/JS_Object.h b/fpdfsdk/javascript/JS_Object.h
index 5875861..3b24071 100644
--- a/fpdfsdk/javascript/JS_Object.h
+++ b/fpdfsdk/javascript/JS_Object.h
@@ -26,7 +26,7 @@
   CJS_Object* GetJSObject() const { return m_pJSObject; }
 
  protected:
-  CJS_Object* m_pJSObject;
+  CJS_Object* const m_pJSObject;
 };
 
 class CJS_Object {
diff --git a/fpdfsdk/javascript/JS_Value.cpp b/fpdfsdk/javascript/JS_Value.cpp
index df7bdf4..8f448a9 100644
--- a/fpdfsdk/javascript/JS_Value.cpp
+++ b/fpdfsdk/javascript/JS_Value.cpp
@@ -33,49 +33,40 @@
 
 }  // namespace
 
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime) {}
 
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue)
-    : m_pValue(pValue), m_pJSRuntime(pRuntime) {}
+    : m_pValue(pValue) {}
 
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
-    : m_pJSRuntime(pRuntime) {
-  operator=(iValue);
-}
+    : m_pValue(FXJS_NewNumber(pRuntime->GetIsolate(), iValue)) {}
 
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
-    : m_pJSRuntime(pRuntime) {
-  operator=(bValue);
-}
+    : m_pValue(FXJS_NewBoolean(pRuntime->GetIsolate(), bValue)) {}
 
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
-    : m_pJSRuntime(pRuntime) {
-  operator=(fValue);
-}
+    : m_pValue(FXJS_NewNumber(pRuntime->GetIsolate(), fValue)) {}
 
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const double& dValue)
-    : m_pJSRuntime(pRuntime) {
-  operator=(dValue);
-}
+    : m_pValue(FXJS_NewNumber(pRuntime->GetIsolate(), dValue)) {}
 
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pJsObj)
-    : m_pJSRuntime(pRuntime) {
-  operator=(pJsObj);
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pObj) {
+  if (pObj)
+    m_pValue = pObj->ToV8Object();
 }
 
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr)
-    : m_pJSRuntime(pRuntime) {
-  operator=(pWstr);
-}
+    : m_pValue(FXJS_NewString(pRuntime->GetIsolate(), (wchar_t*)pWstr)) {}
 
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr)
-    : m_pJSRuntime(pRuntime) {
-  operator=(pStr);
-}
+    : m_pValue(FXJS_NewString(pRuntime->GetIsolate(),
+                              CFX_WideString::FromLocal(pStr).c_str())) {}
 
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Array& array)
-    : m_pValue(array.ToV8Array(pRuntime->GetIsolate())),
-      m_pJSRuntime(pRuntime) {}
+    : m_pValue(array.ToV8Array(pRuntime->GetIsolate())) {}
+
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Date& date)
+    : m_pValue(date.ToV8Date(pRuntime->GetIsolate())) {}
 
 CJS_Value::~CJS_Value() {}
 
@@ -89,63 +80,65 @@
   m_pValue = v8::Local<v8::Value>();
 }
 
-int CJS_Value::ToInt() const {
-  return FXJS_ToInt32(m_pJSRuntime->GetIsolate(), m_pValue);
+int CJS_Value::ToInt(v8::Isolate* pIsolate) const {
+  return FXJS_ToInt32(pIsolate, m_pValue);
 }
 
-bool CJS_Value::ToBool() const {
-  return FXJS_ToBoolean(m_pJSRuntime->GetIsolate(), m_pValue);
+bool CJS_Value::ToBool(v8::Isolate* pIsolate) const {
+  return FXJS_ToBoolean(pIsolate, m_pValue);
 }
 
-double CJS_Value::ToDouble() const {
-  return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pValue);
+double CJS_Value::ToDouble(v8::Isolate* pIsolate) const {
+  return FXJS_ToNumber(pIsolate, m_pValue);
 }
 
-float CJS_Value::ToFloat() const {
-  return (float)ToDouble();
+float CJS_Value::ToFloat(v8::Isolate* pIsolate) const {
+  return (float)ToDouble(pIsolate);
 }
 
-CJS_Object* CJS_Value::ToCJSObject() const {
-  v8::Local<v8::Object> pObj =
-      FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
-  return (CJS_Object*)FXJS_GetPrivate(m_pJSRuntime->GetIsolate(), pObj);
+CJS_Object* CJS_Value::ToCJSObject(v8::Isolate* pIsolate) const {
+  v8::Local<v8::Object> pObj = FXJS_ToObject(pIsolate, m_pValue);
+  return (CJS_Object*)FXJS_GetPrivate(pIsolate, pObj);
 }
 
-v8::Local<v8::Object> CJS_Value::ToV8Object() const {
-  return FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
+v8::Local<v8::Object> CJS_Value::ToV8Object(v8::Isolate* pIsolate) const {
+  return FXJS_ToObject(pIsolate, m_pValue);
 }
 
-CFX_WideString CJS_Value::ToCFXWideString() const {
-  return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pValue);
+CFX_WideString CJS_Value::ToCFXWideString(v8::Isolate* pIsolate) const {
+  return FXJS_ToString(pIsolate, m_pValue);
 }
 
-CFX_ByteString CJS_Value::ToCFXByteString() const {
-  return CFX_ByteString::FromUnicode(ToCFXWideString());
+CFX_ByteString CJS_Value::ToCFXByteString(v8::Isolate* pIsolate) const {
+  return CFX_ByteString::FromUnicode(ToCFXWideString(pIsolate));
 }
 
-v8::Local<v8::Value> CJS_Value::ToV8Value() const {
+v8::Local<v8::Value> CJS_Value::ToV8Value(v8::Isolate* pIsolate) const {
   return m_pValue;
 }
 
-v8::Local<v8::Array> CJS_Value::ToV8Array() const {
+v8::Local<v8::Array> CJS_Value::ToV8Array(v8::Isolate* pIsolate) const {
   if (IsArrayObject())
-    return v8::Local<v8::Array>::Cast(
-        FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue));
+    return v8::Local<v8::Array>::Cast(FXJS_ToObject(pIsolate, m_pValue));
   return v8::Local<v8::Array>();
 }
 
-void CJS_Value::MaybeCoerceToNumber() {
+void CJS_Value::SetNull(CJS_Runtime* pRuntime) {
+  m_pValue = FXJS_NewNull(pRuntime->GetIsolate());
+}
+
+void CJS_Value::MaybeCoerceToNumber(v8::Isolate* pIsolate) {
   bool bAllowNaN = false;
   if (GetType() == VT_string) {
-    CFX_ByteString bstr = ToCFXByteString();
+    CFX_ByteString bstr = ToCFXByteString(pIsolate);
     if (bstr.GetLength() == 0)
       return;
     if (bstr == "NaN")
       bAllowNaN = true;
   }
-  v8::TryCatch try_catch(m_pJSRuntime->GetIsolate());
+  v8::TryCatch try_catch(pIsolate);
   v8::MaybeLocal<v8::Number> maybeNum =
-      m_pValue->ToNumber(m_pJSRuntime->GetIsolate()->GetCurrentContext());
+      m_pValue->ToNumber(pIsolate->GetCurrentContext());
   if (maybeNum.IsEmpty())
     return;
   v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
@@ -154,48 +147,6 @@
   m_pValue = num;
 }
 
-void CJS_Value::operator=(int iValue) {
-  m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), iValue);
-}
-
-void CJS_Value::operator=(bool bValue) {
-  m_pValue = FXJS_NewBoolean(m_pJSRuntime->GetIsolate(), bValue);
-}
-
-void CJS_Value::operator=(double dValue) {
-  m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), dValue);
-}
-
-void CJS_Value::operator=(float fValue) {
-  m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), fValue);
-}
-
-void CJS_Value::operator=(v8::Local<v8::Object> pObj) {
-  m_pValue = pObj;
-}
-
-void CJS_Value::operator=(CJS_Object* pObj) {
-  if (pObj)
-    operator=(pObj->ToV8Object());
-}
-
-void CJS_Value::operator=(const FX_WCHAR* pWstr) {
-  m_pValue = FXJS_NewString(m_pJSRuntime->GetIsolate(), (wchar_t*)pWstr);
-}
-
-void CJS_Value::SetNull() {
-  m_pValue = FXJS_NewNull(m_pJSRuntime->GetIsolate());
-}
-
-void CJS_Value::operator=(const FX_CHAR* pStr) {
-  operator=(CFX_WideString::FromLocal(pStr).c_str());
-}
-
-void CJS_Value::operator=(const CJS_Value& value) {
-  ASSERT(m_pJSRuntime == value.m_pJSRuntime);
-  m_pValue = value.ToV8Value();
-}
-
 // static
 CJS_Value::Type CJS_Value::GetValueType(v8::Local<v8::Value> value) {
   if (value.IsEmpty())
@@ -217,149 +168,142 @@
   return VT_unknown;
 }
 
-FX_BOOL CJS_Value::IsArrayObject() const {
-  if (m_pValue.IsEmpty())
-    return FALSE;
-  return m_pValue->IsArray();
+bool CJS_Value::IsArrayObject() const {
+  return !m_pValue.IsEmpty() && m_pValue->IsArray();
 }
 
-FX_BOOL CJS_Value::IsDateObject() const {
-  if (m_pValue.IsEmpty())
-    return FALSE;
-  return m_pValue->IsDate();
+bool CJS_Value::IsDateObject() const {
+  return !m_pValue.IsEmpty() && m_pValue->IsDate();
 }
 
-// CJS_Value::operator CJS_Array()
-FX_BOOL CJS_Value::ConvertToArray(CJS_Array& array) const {
-  if (IsArrayObject()) {
-    array.Attach(FXJS_ToArray(m_pJSRuntime->GetIsolate(), m_pValue));
-    return TRUE;
-  }
-
-  return FALSE;
+bool CJS_Value::ConvertToArray(v8::Isolate* pIsolate, CJS_Array& array) const {
+  if (!IsArrayObject())
+    return false;
+  array.Attach(FXJS_ToArray(pIsolate, m_pValue));
+  return true;
 }
 
-FX_BOOL CJS_Value::ConvertToDate(CJS_Date& date) const {
-  if (IsDateObject()) {
-    v8::Local<v8::Value> mutable_value = m_pValue;
-    date.Attach(mutable_value.As<v8::Date>());
-    return TRUE;
-  }
-
-  return FALSE;
+bool CJS_Value::ConvertToDate(v8::Isolate* pIsolate, CJS_Date& date) const {
+  if (!IsDateObject())
+    return false;
+  v8::Local<v8::Value> mutable_value = m_pValue;
+  date.Attach(mutable_value.As<v8::Date>());
+  return true;
 }
 
-CJS_PropValue::CJS_PropValue(const CJS_Value& value)
-    : CJS_Value(value), m_bIsSetting(0) {}
-
 CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
-    : CJS_Value(pRuntime), m_bIsSetting(0) {}
+    : m_bIsSetting(0), m_Value(pRuntime), m_pJSRuntime(pRuntime) {}
+
+CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime, const CJS_Value& value)
+    : m_bIsSetting(0), m_Value(value), m_pJSRuntime(pRuntime) {}
 
 CJS_PropValue::~CJS_PropValue() {}
 
 void CJS_PropValue::operator<<(int iValue) {
   ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(iValue);
+  m_Value = CJS_Value(m_pJSRuntime, iValue);
 }
 
 void CJS_PropValue::operator>>(int& iValue) const {
   ASSERT(m_bIsSetting);
-  iValue = CJS_Value::ToInt();
+  iValue = m_Value.ToInt(m_pJSRuntime->GetIsolate());
 }
 
 void CJS_PropValue::operator<<(bool bValue) {
   ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(bValue);
+  m_Value = CJS_Value(m_pJSRuntime, bValue);
 }
 
 void CJS_PropValue::operator>>(bool& bValue) const {
   ASSERT(m_bIsSetting);
-  bValue = CJS_Value::ToBool();
+  bValue = m_Value.ToBool(m_pJSRuntime->GetIsolate());
 }
 
 void CJS_PropValue::operator<<(double dValue) {
   ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(dValue);
+  m_Value = CJS_Value(m_pJSRuntime, dValue);
 }
 
 void CJS_PropValue::operator>>(double& dValue) const {
   ASSERT(m_bIsSetting);
-  dValue = CJS_Value::ToDouble();
+  dValue = m_Value.ToDouble(m_pJSRuntime->GetIsolate());
 }
 
 void CJS_PropValue::operator<<(CJS_Object* pObj) {
   ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(pObj);
+  m_Value = CJS_Value(m_pJSRuntime, pObj);
 }
 
 void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
   ASSERT(m_bIsSetting);
-  ppObj = CJS_Value::ToCJSObject();
+  ppObj = m_Value.ToCJSObject(m_pJSRuntime->GetIsolate());
 }
 
 void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
   ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(pJsDoc);
+  m_Value = CJS_Value(m_pJSRuntime, pJsDoc);
 }
 
 void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
   ASSERT(m_bIsSetting);
-  ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject());
+  ppJsDoc = static_cast<CJS_Document*>(
+      m_Value.ToCJSObject(m_pJSRuntime->GetIsolate()));
 }
 
 void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
   ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(pObj);
+  m_Value = CJS_Value(m_pJSRuntime, pObj);
 }
 
 void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
   ASSERT(m_bIsSetting);
-  ppObj = CJS_Value::ToV8Object();
+  ppObj = m_Value.ToV8Object(m_pJSRuntime->GetIsolate());
 }
 
 void CJS_PropValue::operator<<(CFX_ByteString str) {
   ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(str.c_str());
+  m_Value = CJS_Value(m_pJSRuntime, str.c_str());
 }
 
 void CJS_PropValue::operator>>(CFX_ByteString& str) const {
   ASSERT(m_bIsSetting);
-  str = CJS_Value::ToCFXByteString();
+  str = m_Value.ToCFXByteString(m_pJSRuntime->GetIsolate());
 }
 
-void CJS_PropValue::operator<<(const FX_WCHAR* c_string) {
+void CJS_PropValue::operator<<(const FX_WCHAR* str) {
   ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(c_string);
+  m_Value = CJS_Value(m_pJSRuntime, str);
 }
 
 void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
   ASSERT(m_bIsSetting);
-  wide_string = CJS_Value::ToCFXWideString();
+  wide_string = m_Value.ToCFXWideString(m_pJSRuntime->GetIsolate());
 }
 
 void CJS_PropValue::operator<<(CFX_WideString wide_string) {
   ASSERT(!m_bIsSetting);
-  CJS_Value::operator=(wide_string.c_str());
+  m_Value = CJS_Value(m_pJSRuntime, wide_string.c_str());
 }
 
 void CJS_PropValue::operator>>(CJS_Array& array) const {
   ASSERT(m_bIsSetting);
-  ConvertToArray(array);
+  m_Value.ConvertToArray(m_pJSRuntime->GetIsolate(), array);
 }
 
 void CJS_PropValue::operator<<(CJS_Array& array) {
   ASSERT(!m_bIsSetting);
-  m_pValue = array.ToV8Array(m_pJSRuntime->GetIsolate());
+  m_Value =
+      CJS_Value(m_pJSRuntime, array.ToV8Array(m_pJSRuntime->GetIsolate()));
 }
 
 void CJS_PropValue::operator>>(CJS_Date& date) const {
   ASSERT(m_bIsSetting);
-  ConvertToDate(date);
+  m_Value.ConvertToDate(m_pJSRuntime->GetIsolate(), date);
 }
 
 void CJS_PropValue::operator<<(CJS_Date& date) {
   ASSERT(!m_bIsSetting);
-  m_pValue = date.ToV8Date(m_pJSRuntime->GetIsolate());
+  m_Value = CJS_Value(m_pJSRuntime, date);
 }
 
 CJS_Array::CJS_Array() {}
@@ -385,7 +329,7 @@
   if (m_pArray.IsEmpty())
     m_pArray = FXJS_NewArray(pIsolate);
 
-  FXJS_PutArrayElement(pIsolate, m_pArray, index, value.ToV8Value());
+  FXJS_PutArrayElement(pIsolate, m_pArray, index, value.ToV8Value(pIsolate));
 }
 
 int CJS_Array::GetLength() const {
@@ -819,7 +763,7 @@
       originals[0].IsArrayObject()) {
     return result;
   }
-  v8::Local<v8::Object> pObj = originals[0].ToV8Object();
+  v8::Local<v8::Object> pObj = originals[0].ToV8Object(pRuntime->GetIsolate());
   result[0] = CJS_Value(pRuntime);  // Make unknown.
 
   va_list ap;
diff --git a/fpdfsdk/javascript/JS_Value.h b/fpdfsdk/javascript/JS_Value.h
index 4c0d8cc..5587ed0 100644
--- a/fpdfsdk/javascript/JS_Value.h
+++ b/fpdfsdk/javascript/JS_Value.h
@@ -42,63 +42,55 @@
   CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr);
   CJS_Value(CJS_Runtime* pRuntime, const CJS_Array& array);
   CJS_Value(CJS_Runtime* pRuntime, const CJS_Date& date);
+  CJS_Value(CJS_Runtime* pRuntime, const CJS_Object* object);
   CJS_Value(const CJS_Value& other);
 
   ~CJS_Value();
 
-  void SetNull();
+  void SetNull(CJS_Runtime* pRuntime);
+  void SetValue(const CJS_Value& other);
   void Attach(v8::Local<v8::Value> pValue);
   void Detach();
 
   static Type GetValueType(v8::Local<v8::Value> value);
   Type GetType() const { return GetValueType(m_pValue); }
-  int ToInt() const;
-  bool ToBool() const;
-  double ToDouble() const;
-  float ToFloat() const;
-  CJS_Object* ToCJSObject() const;
-  CFX_WideString ToCFXWideString() const;
-  CFX_ByteString ToCFXByteString() const;
-  v8::Local<v8::Object> ToV8Object() const;
-  v8::Local<v8::Array> ToV8Array() const;
-  v8::Local<v8::Value> ToV8Value() const;
+
+  int ToInt(v8::Isolate* pIsolate) const;
+  bool ToBool(v8::Isolate* pIsolate) const;
+  double ToDouble(v8::Isolate* pIsolate) const;
+  float ToFloat(v8::Isolate* pIsolate) const;
+  CJS_Object* ToCJSObject(v8::Isolate* pIsolate) const;
+  CFX_WideString ToCFXWideString(v8::Isolate* pIsolate) const;
+  CFX_ByteString ToCFXByteString(v8::Isolate* pIsolate) const;
+  v8::Local<v8::Object> ToV8Object(v8::Isolate* pIsolate) const;
+  v8::Local<v8::Array> ToV8Array(v8::Isolate* pIsolate) const;
+  v8::Local<v8::Value> ToV8Value(v8::Isolate* pIsolate) const;
 
   // Replace the current |m_pValue| with a v8::Number if possible
   // to make one from the current |m_pValue|.
-  void MaybeCoerceToNumber();
+  void MaybeCoerceToNumber(v8::Isolate* pIsolate);
 
-  void operator=(int iValue);
-  void operator=(bool bValue);
-  void operator=(double val);
-  void operator=(float val);
-  void operator=(CJS_Object* val);
-  void operator=(v8::Local<v8::Object> val);
-  void operator=(const CJS_Value& value);
-  void operator=(const FX_CHAR* pStr);
-  void operator=(const FX_WCHAR* pWstr);
-
-  FX_BOOL IsArrayObject() const;
-  FX_BOOL IsDateObject() const;
-  FX_BOOL ConvertToArray(CJS_Array&) const;
-  FX_BOOL ConvertToDate(CJS_Date&) const;
-
-  CJS_Runtime* GetJSRuntime() const { return m_pJSRuntime; }
+  bool IsArrayObject() const;
+  bool IsDateObject() const;
+  bool ConvertToArray(v8::Isolate* pIsolate, CJS_Array&) const;
+  bool ConvertToDate(v8::Isolate* pIsolate, CJS_Date&) const;
 
  protected:
   v8::Local<v8::Value> m_pValue;
-  CJS_Runtime* const m_pJSRuntime;
 };
 
-class CJS_PropValue : public CJS_Value {
+class CJS_PropValue {
  public:
   explicit CJS_PropValue(CJS_Runtime* pRuntime);
-  CJS_PropValue(const CJS_Value&);
+  CJS_PropValue(CJS_Runtime* pRuntime, const CJS_Value&);
   ~CJS_PropValue();
 
   void StartSetting() { m_bIsSetting = true; }
   void StartGetting() { m_bIsSetting = false; }
   bool IsSetting() const { return m_bIsSetting; }
   bool IsGetting() const { return !m_bIsSetting; }
+  CJS_Runtime* GetJSRuntime() const { return m_pJSRuntime; }
+  CJS_Value* GetJSValue() { return &m_Value; }
 
   void operator<<(int val);
   void operator>>(int&) const;
@@ -124,6 +116,8 @@
 
  private:
   bool m_bIsSetting;
+  CJS_Value m_Value;
+  CJS_Runtime* const m_pJSRuntime;
 };
 
 class CJS_Array {
diff --git a/fpdfsdk/javascript/PublicMethods.cpp b/fpdfsdk/javascript/PublicMethods.cpp
index aa0efb1..f1e23db 100644
--- a/fpdfsdk/javascript/PublicMethods.cpp
+++ b/fpdfsdk/javascript/PublicMethods.cpp
@@ -163,10 +163,10 @@
                                                   CJS_Value val) {
   CJS_Array StrArray;
   if (val.IsArrayObject()) {
-    val.ConvertToArray(StrArray);
+    val.ConvertToArray(pRuntime->GetIsolate(), StrArray);
     return StrArray;
   }
-  CFX_WideString wsStr = val.ToCFXWideString();
+  CFX_WideString wsStr = val.ToCFXWideString(pRuntime->GetIsolate());
   CFX_ByteString t = CFX_ByteString::FromUnicode(wsStr);
   const char* p = t.c_str();
 
@@ -743,12 +743,13 @@
   if (strValue.IsEmpty())
     return TRUE;
 
-  int iDec = params[0].ToInt();
-  int iSepStyle = params[1].ToInt();
-  int iNegStyle = params[2].ToInt();
+  int iDec = params[0].ToInt(pRuntime->GetIsolate());
+  int iSepStyle = params[1].ToInt(pRuntime->GetIsolate());
+  int iNegStyle = params[2].ToInt(pRuntime->GetIsolate());
   // params[3] is iCurrStyle, it's not used.
-  CFX_WideString wstrCurrency = params[4].ToCFXWideString();
-  FX_BOOL bCurrencyPrepend = params[5].ToBool();
+  CFX_WideString wstrCurrency =
+      params[4].ToCFXWideString(pRuntime->GetIsolate());
+  FX_BOOL bCurrencyPrepend = params[5].ToBool(pRuntime->GetIsolate());
 
   if (iDec < 0)
     iDec = -iDec;
@@ -837,11 +838,11 @@
       if (Field* fTarget = pEvent->Target_Field()) {
         CJS_Array arColor;
         CJS_Value vColElm(pRuntime);
-        vColElm = L"RGB";
+        vColElm = CJS_Value(pRuntime, L"RGB");
         arColor.SetElement(pRuntime->GetIsolate(), 0, vColElm);
-        vColElm = 1;
+        vColElm = CJS_Value(pRuntime, 1);
         arColor.SetElement(pRuntime->GetIsolate(), 1, vColElm);
-        vColElm = 0;
+        vColElm = CJS_Value(pRuntime, 0);
         arColor.SetElement(pRuntime->GetIsolate(), 2, vColElm);
         arColor.SetElement(pRuntime->GetIsolate(), 3, vColElm);
 
@@ -857,9 +858,9 @@
       if (Field* fTarget = pEvent->Target_Field()) {
         CJS_Array arColor;
         CJS_Value vColElm(pRuntime);
-        vColElm = L"RGB";
+        vColElm = CJS_Value(pRuntime, L"RGB");
         arColor.SetElement(pRuntime->GetIsolate(), 0, vColElm);
-        vColElm = 0;
+        vColElm = CJS_Value(pRuntime, 0);
         arColor.SetElement(pRuntime->GetIsolate(), 1, vColElm);
         arColor.SetElement(pRuntime->GetIsolate(), 2, vColElm);
         arColor.SetElement(pRuntime->GetIsolate(), 3, vColElm);
@@ -869,7 +870,7 @@
         fTarget->textColor(cc, vProp, sError);
 
         CJS_Array aProp;
-        vProp.ConvertToArray(aProp);
+        vProp.GetJSValue()->ConvertToArray(pRuntime->GetIsolate(), aProp);
 
         CPWL_Color crProp;
         CPWL_Color crColor;
@@ -940,7 +941,8 @@
     }
   }
 
-  int iSepStyle = params[1].ToInt();
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iSepStyle = params[1].ToInt(pRuntime->GetIsolate());
   if (iSepStyle < 0 || iSepStyle > 3)
     iSepStyle = 0;
   const FX_WCHAR cSep = iSepStyle < 2 ? L'.' : L',';
@@ -1000,6 +1002,7 @@
     CFX_WideString& sError) {
 #if _FX_OS_ != _FX_ANDROID_
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   if (params.size() != 2) {
@@ -1014,11 +1017,11 @@
   if (strValue.IsEmpty())
     return TRUE;
 
-  int iDec = params[0].ToInt();
+  int iDec = params[0].ToInt(pRuntime->GetIsolate());
   if (iDec < 0)
     iDec = -iDec;
 
-  int iSepStyle = params[1].ToInt();
+  int iSepStyle = params[1].ToInt(pRuntime->GetIsolate());
   if (iSepStyle < 0 || iSepStyle > 3)
     iSepStyle = 0;
 
@@ -1099,6 +1102,7 @@
                                            CJS_Value& vRet,
                                            CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   if (params.size() != 1) {
@@ -1113,7 +1117,7 @@
   if (strValue.IsEmpty())
     return TRUE;
 
-  CFX_WideString sFormat = params[0].ToCFXWideString();
+  CFX_WideString sFormat = params[0].ToCFXWideString(pRuntime->GetIsolate());
   double dDate = 0.0f;
 
   if (strValue.Find(L"GMT") != -1) {
@@ -1199,6 +1203,7 @@
     CJS_Value& vRet,
     CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   if (params.size() != 1) {
@@ -1213,7 +1218,7 @@
     if (strValue.IsEmpty())
       return TRUE;
 
-    CFX_WideString sFormat = params[0].ToCFXWideString();
+    CFX_WideString sFormat = params[0].ToCFXWideString(pRuntime->GetIsolate());
     bool bWrongFormat = FALSE;
     double dRet = MakeRegularDate(strValue, sFormat, &bWrongFormat);
     if (bWrongFormat || JS_PortIsNan(dRet)) {
@@ -1238,7 +1243,8 @@
     return FALSE;
   }
 
-  int iIndex = params[0].ToInt();
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iIndex = params[0].ToInt(pRuntime->GetIsolate());
   const FX_WCHAR* cFormats[] = {L"m/d",
                                 L"m/d/yy",
                                 L"mm/dd/yy",
@@ -1275,7 +1281,8 @@
     return FALSE;
   }
 
-  int iIndex = params[0].ToInt();
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iIndex = params[0].ToInt(pRuntime->GetIsolate());
   const FX_WCHAR* cFormats[] = {L"m/d",
                                 L"m/d/yy",
                                 L"mm/dd/yy",
@@ -1311,7 +1318,8 @@
     return FALSE;
   }
 
-  int iIndex = params[0].ToInt();
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iIndex = params[0].ToInt(pRuntime->GetIsolate());
   const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
                                 L"h:MM:ss tt"};
 
@@ -1335,7 +1343,8 @@
     return FALSE;
   }
 
-  int iIndex = params[0].ToInt();
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  int iIndex = params[0].ToInt(pRuntime->GetIsolate());
   const FX_WCHAR* cFormats[] = {L"HH:MM", L"h:MM tt", L"HH:MM:ss",
                                 L"h:MM:ss tt"};
 
@@ -1370,7 +1379,6 @@
     CJS_Value& vRet,
     CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
-
   if (params.size() != 1) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
@@ -1380,9 +1388,10 @@
   if (!pEvent->m_pValue)
     return FALSE;
 
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CFX_WideString wsSource = pEvent->Value();
   CFX_WideString wsFormat;
-  switch (params[0].ToInt()) {
+  switch (params[0].ToInt(pRuntime->GetIsolate())) {
     case 0:
       wsFormat = L"99999";
       break;
@@ -1411,6 +1420,7 @@
     CJS_Value& vRet,
     CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   if (params.size() < 1) {
@@ -1422,7 +1432,7 @@
     return FALSE;
   CFX_WideString& valEvent = pEvent->Value();
 
-  CFX_WideString wstrMask = params[0].ToCFXWideString();
+  CFX_WideString wstrMask = params[0].ToCFXWideString(pRuntime->GetIsolate());
   if (wstrMask.IsEmpty())
     return TRUE;
 
@@ -1509,7 +1519,8 @@
     return FALSE;
 
   const char* cFormat = "";
-  switch (params[0].ToInt()) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+  switch (params[0].ToInt(pRuntime->GetIsolate())) {
     case 0:
       cFormat = "99999";
       break;
@@ -1537,6 +1548,7 @@
                                          CJS_Value& vRet,
                                          CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_EventHandler* pEventHandler = pContext->GetEventHandler();
 
   if (params.size() != 1) {
@@ -1549,7 +1561,7 @@
     swValue = pEventHandler->Value();
 
   if (pEventHandler->WillCommit()) {
-    vRet = swValue.c_str();
+    vRet = CJS_Value(pRuntime, swValue.c_str());
     return TRUE;
   }
 
@@ -1567,8 +1579,8 @@
   else
     postfix = L"";
 
-  vRet = (prefix + pEventHandler->Change() + postfix).c_str();
-
+  vRet =
+      CJS_Value(pRuntime, (prefix + pEventHandler->Change() + postfix).c_str());
   return TRUE;
 }
 
@@ -1577,15 +1589,15 @@
                                          CJS_Value& vRet,
                                          CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
-  ASSERT(pContext);
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
 
   if (params.size() != 2) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  CFX_WideString sValue = params[0].ToCFXWideString();
-  CFX_WideString sFormat = params[1].ToCFXWideString();
+  CFX_WideString sValue = params[0].ToCFXWideString(pRuntime->GetIsolate());
+  CFX_WideString sFormat = params[1].ToCFXWideString(pRuntime->GetIsolate());
 
   double dDate = MakeRegularDate(sValue, sFormat, nullptr);
 
@@ -1597,7 +1609,7 @@
     return FALSE;
   }
 
-  vRet = dDate;
+  vRet = CJS_Value(pRuntime, dDate);
   return TRUE;
 }
 
@@ -1605,16 +1617,20 @@
                                     const std::vector<CJS_Value>& params,
                                     CJS_Value& vRet,
                                     CFX_WideString& sError) {
-  if (params.size() != 3) {
-    CJS_Context* pContext = (CJS_Context*)cc;
-    ASSERT(pContext);
+  CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
 
+  if (params.size() != 3) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  vRet = (double)AF_Simple(params[0].ToCFXWideString().c_str(),
-                           params[1].ToDouble(), params[2].ToDouble());
+  vRet = CJS_Value(
+      pRuntime, static_cast<double>(AF_Simple(
+                    params[0].ToCFXWideString(pRuntime->GetIsolate()).c_str(),
+                    params[1].ToDouble(pRuntime->GetIsolate()),
+                    params[2].ToDouble(pRuntime->GetIsolate()))));
+
   return TRUE;
 }
 
@@ -1623,16 +1639,19 @@
                                         CJS_Value& vRet,
                                         CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
   if (params.size() != 1) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
-  CFX_WideString ws = params[0].ToCFXWideString();
+
+  CFX_WideString ws = params[0].ToCFXWideString(pRuntime->GetIsolate());
   ws.Replace(L",", L".");
-  vRet = ws.c_str();
-  vRet.MaybeCoerceToNumber();
+  vRet = CJS_Value(pRuntime, ws.c_str());
+  vRet.MaybeCoerceToNumber(pRuntime->GetIsolate());
   if (vRet.GetType() != CJS_Value::VT_number)
-    vRet = 0;
+    vRet = CJS_Value(pRuntime, 0);
   return TRUE;
 }
 
@@ -1642,6 +1661,8 @@
     CJS_Value& vRet,
     CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
   if (params.size() != 2) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
@@ -1657,17 +1678,17 @@
   CPDFSDK_InterForm* pReaderInterForm = pReaderDoc->GetInterForm();
   CPDF_InterForm* pInterForm = pReaderInterForm->GetInterForm();
 
-  CFX_WideString sFunction = params[0].ToCFXWideString();
+  CFX_WideString sFunction = params[0].ToCFXWideString(pRuntime->GetIsolate());
   double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
 
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params1);
   int nFieldsCount = 0;
 
   for (int i = 0, isz = FieldNameArray.GetLength(); i < isz; i++) {
     CJS_Value jsValue(pRuntime);
     FieldNameArray.GetElement(pRuntime->GetIsolate(), i, jsValue);
-    CFX_WideString wsFieldName = jsValue.ToCFXWideString();
+    CFX_WideString wsFieldName =
+        jsValue.ToCFXWideString(pRuntime->GetIsolate());
 
     for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
       if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
@@ -1728,7 +1749,8 @@
            FXSYS_pow((double)10, (double)6);
   CJS_Value jsValue(pRuntime, dValue);
   if (pContext->GetEventHandler()->m_pValue)
-    pContext->GetEventHandler()->Value() = jsValue.ToCFXWideString();
+    pContext->GetEventHandler()->Value() =
+        jsValue.ToCFXWideString(pRuntime->GetIsolate());
 
   return TRUE;
 }
@@ -1742,6 +1764,7 @@
     CJS_Value& vRet,
     CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
 
   if (params.size() != 4) {
@@ -1755,25 +1778,25 @@
     return TRUE;
   double dEentValue =
       atof(CFX_ByteString::FromUnicode(pEvent->Value()).c_str());
-  FX_BOOL bGreaterThan = params[0].ToBool();
-  double dGreaterThan = params[1].ToDouble();
-  FX_BOOL bLessThan = params[2].ToBool();
-  double dLessThan = params[3].ToDouble();
+  FX_BOOL bGreaterThan = params[0].ToBool(pRuntime->GetIsolate());
+  double dGreaterThan = params[1].ToDouble(pRuntime->GetIsolate());
+  FX_BOOL bLessThan = params[2].ToBool(pRuntime->GetIsolate());
+  double dLessThan = params[3].ToDouble(pRuntime->GetIsolate());
   CFX_WideString swMsg;
 
   if (bGreaterThan && bLessThan) {
     if (dEentValue < dGreaterThan || dEentValue > dLessThan)
       swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE1).c_str(),
-                   params[1].ToCFXWideString().c_str(),
-                   params[3].ToCFXWideString().c_str());
+                   params[1].ToCFXWideString(pRuntime->GetIsolate()).c_str(),
+                   params[3].ToCFXWideString(pRuntime->GetIsolate()).c_str());
   } else if (bGreaterThan) {
     if (dEentValue < dGreaterThan)
       swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE2).c_str(),
-                   params[1].ToCFXWideString().c_str());
+                   params[1].ToCFXWideString(pRuntime->GetIsolate()).c_str());
   } else if (bLessThan) {
     if (dEentValue > dLessThan)
       swMsg.Format(JSGetStringFromID(pContext, IDS_STRING_JSRANGE3).c_str(),
-                   params[3].ToCFXWideString().c_str());
+                   params[3].ToCFXWideString(pRuntime->GetIsolate()).c_str());
   }
 
   if (!swMsg.IsEmpty()) {
@@ -1788,15 +1811,15 @@
                                          CJS_Value& vRet,
                                          CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
   if (params.size() != 1) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_Array nums;
-
-  CFX_WideString str = params[0].ToCFXWideString();
+  CFX_WideString str = params[0].ToCFXWideString(pRuntime->GetIsolate());
   CFX_WideString sPart;
 
   if (str.GetAt(0) == L'.' || str.GetAt(0) == L',')
@@ -1825,7 +1848,7 @@
   if (nums.GetLength() > 0)
     vRet = CJS_Value(pRuntime, nums);
   else
-    vRet.SetNull();
+    vRet.SetNull(pRuntime);
 
   return TRUE;
 }
diff --git a/fpdfsdk/javascript/app.cpp b/fpdfsdk/javascript/app.cpp
index 50afd9a..8d7420b 100644
--- a/fpdfsdk/javascript/app.cpp
+++ b/fpdfsdk/javascript/app.cpp
@@ -252,7 +252,7 @@
   if (aDocs.GetLength() > 0)
     vp << aDocs;
   else
-    vp.SetNull();
+    vp.GetJSValue()->SetNull(pRuntime);
 
   return TRUE;
 }
@@ -405,41 +405,41 @@
 
   CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
   if (!pApp) {
-    vRet = 0;
+    vRet = CJS_Value(pRuntime, 0);
     return TRUE;
   }
 
   CFX_WideString swMsg;
   if (newParams[0].GetType() == CJS_Value::VT_object) {
     CJS_Array carray;
-    if (newParams[0].ConvertToArray(carray)) {
+    if (newParams[0].ConvertToArray(pRuntime->GetIsolate(), carray)) {
       swMsg = L"[";
       CJS_Value element(pRuntime);
       for (int i = 0; i < carray.GetLength(); ++i) {
         if (i)
           swMsg += L", ";
         carray.GetElement(pRuntime->GetIsolate(), i, element);
-        swMsg += element.ToCFXWideString();
+        swMsg += element.ToCFXWideString(pRuntime->GetIsolate());
       }
       swMsg += L"]";
     } else {
-      swMsg = newParams[0].ToCFXWideString();
+      swMsg = newParams[0].ToCFXWideString(pRuntime->GetIsolate());
     }
   } else {
-    swMsg = newParams[0].ToCFXWideString();
+    swMsg = newParams[0].ToCFXWideString(pRuntime->GetIsolate());
   }
 
   int iIcon = 0;
   if (newParams[1].GetType() != CJS_Value::VT_unknown)
-    iIcon = newParams[1].ToInt();
+    iIcon = newParams[1].ToInt(pRuntime->GetIsolate());
 
   int iType = 0;
   if (newParams[2].GetType() != CJS_Value::VT_unknown)
-    iType = newParams[2].ToInt();
+    iType = newParams[2].ToInt(pRuntime->GetIsolate());
 
   CFX_WideString swTitle;
   if (newParams[3].GetType() != CJS_Value::VT_unknown)
-    swTitle = newParams[3].ToCFXWideString();
+    swTitle = newParams[3].ToCFXWideString(pRuntime->GetIsolate());
   else
     swTitle = JSGetStringFromID(pContext, IDS_STRING_JSALERT);
 
@@ -447,7 +447,8 @@
   if (CPDFSDK_Document* pDoc = pApp->GetSDKDocument())
     pDoc->KillFocusAnnot();
 
-  vRet = pApp->JS_appAlert(swMsg.c_str(), swTitle.c_str(), iType, iIcon);
+  vRet = CJS_Value(pRuntime, pApp->JS_appAlert(swMsg.c_str(), swTitle.c_str(),
+                                               iType, iIcon));
   pRuntime->EndBlock();
   return TRUE;
 }
@@ -460,7 +461,7 @@
     CJS_Context* pContext = (CJS_Context*)cc;
     CJS_Runtime* pRuntime = pContext->GetJSRuntime();
     CPDFDoc_Environment* pEnv = pRuntime->GetReaderApp();
-    pEnv->JS_appBeep(params[0].ToInt());
+    pEnv->JS_appBeep(params[0].ToInt(pRuntime->GetIsolate()));
     return TRUE;
   }
 
@@ -491,19 +492,23 @@
                          CJS_Value& vRet,
                          CFX_WideString& sError) {
   CJS_Context* pContext = (CJS_Context*)cc;
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
   if (params.size() > 2 || params.size() == 0) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  CFX_WideString script = params.size() > 0 ? params[0].ToCFXWideString() : L"";
+  CFX_WideString script =
+      params.size() > 0 ? params[0].ToCFXWideString(pRuntime->GetIsolate())
+                        : L"";
   if (script.IsEmpty()) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
     return TRUE;
   }
 
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
-  uint32_t dwInterval = params.size() > 1 ? params[1].ToInt() : 1000;
+  uint32_t dwInterval =
+      params.size() > 1 ? params[1].ToInt(pRuntime->GetIsolate()) : 1000;
   CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
   m_Timers.push_back(std::unique_ptr<GlobalTimer>(
       new GlobalTimer(this, pApp, pRuntime, 0, script, dwInterval, 0)));
@@ -515,7 +520,7 @@
   TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
   pTimerObj->SetTimer(m_Timers.back().get());
 
-  vRet = pRetObj;
+  vRet = CJS_Value(pRuntime, pRetObj);
   return TRUE;
 }
 
@@ -524,19 +529,21 @@
                         CJS_Value& vRet,
                         CFX_WideString& sError) {
   CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+
   if (params.size() > 2 || params.size() == 0) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  CFX_WideString script = params[0].ToCFXWideString();
+  CFX_WideString script = params[0].ToCFXWideString(pRuntime->GetIsolate());
   if (script.IsEmpty()) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSAFNUMBER_KEYSTROKE);
     return TRUE;
   }
 
-  uint32_t dwTimeOut = params.size() > 1 ? params[1].ToInt() : 1000;
-  CJS_Runtime* pRuntime = pContext->GetJSRuntime();
+  uint32_t dwTimeOut =
+      params.size() > 1 ? params[1].ToInt(pRuntime->GetIsolate()) : 1000;
   CPDFDoc_Environment* pApp = pRuntime->GetReaderApp();
   m_Timers.push_back(std::unique_ptr<GlobalTimer>(
       new GlobalTimer(this, pApp, pRuntime, 1, script, dwTimeOut, dwTimeOut)));
@@ -550,7 +557,7 @@
   TimerObj* pTimerObj = static_cast<TimerObj*>(pJS_TimerObj->GetEmbedObject());
   pTimerObj->SetTimer(m_Timers.back().get());
 
-  vRet = pRetObj;
+  vRet = CJS_Value(pRuntime, pRetObj);
   return TRUE;
 }
 
@@ -586,11 +593,11 @@
   if (param.GetType() != CJS_Value::VT_object)
     return;
 
-  v8::Local<v8::Object> pObj = param.ToV8Object();
+  v8::Local<v8::Object> pObj = param.ToV8Object(GetJSObject()->GetIsolate());
   if (FXJS_GetObjDefnID(pObj) != CJS_TimerObj::g_nObjDefnID)
     return;
 
-  CJS_Object* pJSObj = param.ToCJSObject();
+  CJS_Object* pJSObj = param.ToCJSObject(GetJSObject()->GetIsolate());
   if (!pJSObj)
     return;
 
@@ -664,11 +671,11 @@
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
-  bool bUI = newParams[0].ToBool();
+  bool bUI = newParams[0].ToBool(pRuntime->GetIsolate());
 
   CFX_WideString cTo;
   if (newParams[1].GetType() != CJS_Value::VT_unknown) {
-    cTo = newParams[1].ToCFXWideString();
+    cTo = newParams[1].ToCFXWideString(pRuntime->GetIsolate());
   } else {
     if (!bUI) {
       // cTo parameter required when UI not invoked.
@@ -679,19 +686,19 @@
 
   CFX_WideString cCc;
   if (newParams[2].GetType() != CJS_Value::VT_unknown)
-    cCc = newParams[2].ToCFXWideString();
+    cCc = newParams[2].ToCFXWideString(pRuntime->GetIsolate());
 
   CFX_WideString cBcc;
   if (newParams[3].GetType() != CJS_Value::VT_unknown)
-    cBcc = newParams[3].ToCFXWideString();
+    cBcc = newParams[3].ToCFXWideString(pRuntime->GetIsolate());
 
   CFX_WideString cSubject;
   if (newParams[4].GetType() != CJS_Value::VT_unknown)
-    cSubject = newParams[4].ToCFXWideString();
+    cSubject = newParams[4].ToCFXWideString(pRuntime->GetIsolate());
 
   CFX_WideString cMsg;
   if (newParams[5].GetType() != CJS_Value::VT_unknown)
-    cMsg = newParams[5].ToCFXWideString();
+    cMsg = newParams[5].ToCFXWideString(pRuntime->GetIsolate());
 
   pRuntime->BeginBlock();
   pContext->GetReaderApp()->JS_docmailForm(nullptr, 0, bUI, cTo.c_str(),
@@ -787,23 +794,24 @@
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
-  CFX_WideString swQuestion = newParams[0].ToCFXWideString();
+  CFX_WideString swQuestion =
+      newParams[0].ToCFXWideString(pRuntime->GetIsolate());
 
   CFX_WideString swTitle = L"PDF";
   if (newParams[1].GetType() != CJS_Value::VT_unknown)
-    swTitle = newParams[1].ToCFXWideString();
+    swTitle = newParams[1].ToCFXWideString(pRuntime->GetIsolate());
 
   CFX_WideString swDefault;
   if (newParams[2].GetType() != CJS_Value::VT_unknown)
-    swDefault = newParams[2].ToCFXWideString();
+    swDefault = newParams[2].ToCFXWideString(pRuntime->GetIsolate());
 
   bool bPassword = false;
   if (newParams[3].GetType() != CJS_Value::VT_unknown)
-    bPassword = newParams[3].ToBool();
+    bPassword = newParams[3].ToBool(pRuntime->GetIsolate());
 
   CFX_WideString swLabel;
   if (newParams[4].GetType() != CJS_Value::VT_unknown)
-    swLabel = newParams[4].ToCFXWideString();
+    swLabel = newParams[4].ToCFXWideString(pRuntime->GetIsolate());
 
   const int MAX_INPUT_BYTES = 2048;
   std::unique_ptr<char[]> pBuff(new char[MAX_INPUT_BYTES + 2]);
@@ -818,9 +826,11 @@
     return FALSE;
   }
 
-  vRet = CFX_WideString::FromUTF16LE(reinterpret_cast<uint16_t*>(pBuff.get()),
-                                     nLengthBytes / sizeof(uint16_t))
-             .c_str();
+  vRet = CJS_Value(pRuntime, CFX_WideString::FromUTF16LE(
+                                 reinterpret_cast<uint16_t*>(pBuff.get()),
+                                 nLengthBytes / sizeof(uint16_t))
+                                 .c_str());
+
   return TRUE;
 }
 
diff --git a/fpdfsdk/javascript/color.cpp b/fpdfsdk/javascript/color.cpp
index c0b6333..949c429 100644
--- a/fpdfsdk/javascript/color.cpp
+++ b/fpdfsdk/javascript/color.cpp
@@ -101,7 +101,7 @@
 
   CJS_Value value(pRuntime);
   array.GetElement(pRuntime->GetIsolate(), 0, value);
-  CFX_ByteString sSpace = value.ToCFXByteString();
+  CFX_ByteString sSpace = value.ToCFXByteString(pRuntime->GetIsolate());
 
   double d1 = 0;
   double d2 = 0;
@@ -110,22 +110,22 @@
 
   if (nArrayLen > 1) {
     array.GetElement(pRuntime->GetIsolate(), 1, value);
-    d1 = value.ToDouble();
+    d1 = value.ToDouble(pRuntime->GetIsolate());
   }
 
   if (nArrayLen > 2) {
     array.GetElement(pRuntime->GetIsolate(), 2, value);
-    d2 = value.ToDouble();
+    d2 = value.ToDouble(pRuntime->GetIsolate());
   }
 
   if (nArrayLen > 3) {
     array.GetElement(pRuntime->GetIsolate(), 3, value);
-    d3 = value.ToDouble();
+    d3 = value.ToDouble(pRuntime->GetIsolate());
   }
 
   if (nArrayLen > 4) {
     array.GetElement(pRuntime->GetIsolate(), 4, value);
-    d4 = value.ToDouble();
+    d4 = value.ToDouble(pRuntime->GetIsolate());
   }
 
   if (sSpace == "T") {
@@ -141,20 +141,20 @@
   }
 }
 
-#define JS_IMPLEMENT_COLORPROP(prop, var)                 \
-  FX_BOOL color::prop(IJS_Context* cc, CJS_PropValue& vp, \
-                      CFX_WideString& sError) {           \
-    CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc); \
-    CJS_Array array;                                      \
-    if (vp.IsGetting()) {                                 \
-      ConvertPWLColorToArray(pRuntime, var, &array);      \
-      vp << array;                                        \
-    } else {                                              \
-      if (!vp.ConvertToArray(array))                      \
-        return FALSE;                                     \
-      ConvertArrayToPWLColor(pRuntime, array, &var);      \
-    }                                                     \
-    return TRUE;                                          \
+#define JS_IMPLEMENT_COLORPROP(prop, var)                                  \
+  FX_BOOL color::prop(IJS_Context* cc, CJS_PropValue& vp,                  \
+                      CFX_WideString& sError) {                            \
+    CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);                  \
+    CJS_Array array;                                                       \
+    if (vp.IsGetting()) {                                                  \
+      ConvertPWLColorToArray(pRuntime, var, &array);                       \
+      vp << array;                                                         \
+    } else {                                                               \
+      if (!vp.GetJSValue()->ConvertToArray(pRuntime->GetIsolate(), array)) \
+        return FALSE;                                                      \
+      ConvertArrayToPWLColor(pRuntime, array, &var);                       \
+    }                                                                      \
+    return TRUE;                                                           \
   }
 
 JS_IMPLEMENT_COLORPROP(transparent, m_crTransparent)
@@ -180,13 +180,13 @@
 
   CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_Array aSource;
-  if (!params[0].ConvertToArray(aSource))
+  if (!params[0].ConvertToArray(pRuntime->GetIsolate(), aSource))
     return FALSE;
 
   CPWL_Color crSource;
   ConvertArrayToPWLColor(pRuntime, aSource, &crSource);
 
-  CFX_ByteString sDestSpace = params[1].ToCFXByteString();
+  CFX_ByteString sDestSpace = params[1].ToCFXByteString(pRuntime->GetIsolate());
   int nColorType = COLORTYPE_TRANSPARENT;
 
   if (sDestSpace == "T") {
@@ -218,9 +218,9 @@
   CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   CJS_Array array1;
   CJS_Array array2;
-  if (!params[0].ConvertToArray(array1))
+  if (!params[0].ConvertToArray(pRuntime->GetIsolate(), array1))
     return FALSE;
-  if (!params[1].ConvertToArray(array2))
+  if (!params[1].ConvertToArray(pRuntime->GetIsolate(), array2))
     return FALSE;
 
   CPWL_Color color1;
@@ -228,6 +228,6 @@
   ConvertArrayToPWLColor(pRuntime, array1, &color1);
   ConvertArrayToPWLColor(pRuntime, array2, &color2);
   color1.ConvertColorType(color2.nColorType);
-  vRet = color1 == color2;
+  vRet = CJS_Value(pRuntime, color1 == color2);
   return TRUE;
 }
diff --git a/fpdfsdk/javascript/event.cpp b/fpdfsdk/javascript/event.cpp
index 253a802..880247f 100644
--- a/fpdfsdk/javascript/event.cpp
+++ b/fpdfsdk/javascript/event.cpp
@@ -55,7 +55,7 @@
   CJS_EventHandler* pEvent = pContext->GetEventHandler();
   CFX_WideString& wChange = pEvent->Change();
   if (vp.IsSetting()) {
-    if (vp.GetType() == CJS_Value::VT_string)
+    if (vp.GetJSValue()->GetType() == CJS_Value::VT_string)
       vp >> wChange;
   } else {
     vp << wChange;
diff --git a/fpdfsdk/javascript/global.cpp b/fpdfsdk/javascript/global.cpp
index b305c41..10bab26 100644
--- a/fpdfsdk/javascript/global.cpp
+++ b/fpdfsdk/javascript/global.cpp
@@ -81,9 +81,10 @@
                                       const FX_WCHAR* propname,
                                       CJS_PropValue& vp,
                                       CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   if (vp.IsSetting()) {
     CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
-    switch (vp.GetType()) {
+    switch (vp.GetJSValue()->GetType()) {
       case CJS_Value::VT_number: {
         double dData;
         vp >> dData;
@@ -122,12 +123,12 @@
   } else {
     auto it = m_mapGlobal.find(CFX_ByteString::FromUnicode(propname));
     if (it == m_mapGlobal.end()) {
-      vp.SetNull();
+      vp.GetJSValue()->SetNull(pRuntime);
       return TRUE;
     }
     JSGlobalData* pData = it->second;
     if (pData->bDeleted) {
-      vp.SetNull();
+      vp.GetJSValue()->SetNull(pRuntime);
       return TRUE;
     }
     switch (pData->nType) {
@@ -147,7 +148,7 @@
         return TRUE;
       }
       case JS_GlobalDataType::NULLOBJ:
-        vp.SetNull();
+        vp.GetJSValue()->SetNull(pRuntime);
         return TRUE;
       default:
         break;
@@ -161,16 +162,17 @@
                                          CJS_Value& vRet,
                                          CFX_WideString& sError) {
   CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   if (params.size() != 2) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
 
-  auto it = m_mapGlobal.find(params[0].ToCFXByteString());
+  auto it = m_mapGlobal.find(params[0].ToCFXByteString(pRuntime->GetIsolate()));
   if (it != m_mapGlobal.end()) {
     JSGlobalData* pData = it->second;
     if (!pData->bDeleted) {
-      pData->bPersistent = params[1].ToBool();
+      pData->bPersistent = params[1].ToBool(pRuntime->GetIsolate());
       return TRUE;
     }
   }
@@ -271,7 +273,6 @@
                                       CJS_GlobalVariableArray& array) {
   v8::Isolate* isolate = pObj->GetIsolate();
   CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-
   v8::Local<v8::Array> pKeyList = FXJS_GetObjectElementNames(isolate, pObj);
   int nObjElements = pKeyList->Length();
   for (int i = 0; i < nObjElements; i++) {
@@ -295,7 +296,8 @@
         array.Add(pObjElement);
       } break;
       case CJS_Value::VT_string: {
-        CFX_ByteString sValue = CJS_Value(pRuntime, v).ToCFXByteString();
+        CFX_ByteString sValue =
+            CJS_Value(pRuntime, v).ToCFXByteString(pRuntime->GetIsolate());
         CJS_KeyValue* pObjElement = new CJS_KeyValue;
         pObjElement->nType = JS_GlobalDataType::STRING;
         pObjElement->sKey = sKey;
diff --git a/fpdfsdk/javascript/util.cpp b/fpdfsdk/javascript/util.cpp
index 82c85a0..a68d96c 100644
--- a/fpdfsdk/javascript/util.cpp
+++ b/fpdfsdk/javascript/util.cpp
@@ -118,10 +118,12 @@
                      const std::vector<CJS_Value>& params,
                      CJS_Value& vRet,
                      CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   int iSize = params.size();
   if (iSize < 1)
     return FALSE;
-  std::wstring c_ConvChar(params[0].ToCFXWideString().c_str());
+  std::wstring c_ConvChar(
+      params[0].ToCFXWideString(pRuntime->GetIsolate()).c_str());
   std::vector<std::wstring> c_strConvers;
   int iOffset = 0;
   int iOffend = 0;
@@ -154,14 +156,17 @@
 
     switch (ParseDataType(&c_strFormat)) {
       case UTIL_INT:
-        strSegment.Format(c_strFormat.c_str(), params[iIndex].ToInt());
+        strSegment.Format(c_strFormat.c_str(),
+                          params[iIndex].ToInt(pRuntime->GetIsolate()));
         break;
       case UTIL_DOUBLE:
-        strSegment.Format(c_strFormat.c_str(), params[iIndex].ToDouble());
+        strSegment.Format(c_strFormat.c_str(),
+                          params[iIndex].ToDouble(pRuntime->GetIsolate()));
         break;
       case UTIL_STRING:
-        strSegment.Format(c_strFormat.c_str(),
-                          params[iIndex].ToCFXWideString().c_str());
+        strSegment.Format(
+            c_strFormat.c_str(),
+            params[iIndex].ToCFXWideString(pRuntime->GetIsolate()).c_str());
         break;
       default:
         strSegment.Format(L"%S", c_strFormat.c_str());
@@ -171,7 +176,7 @@
   }
 
   c_strResult.erase(c_strResult.begin());
-  vRet = c_strResult.c_str();
+  vRet = CJS_Value(pRuntime, c_strResult.c_str());
   return TRUE;
 }
 
@@ -187,7 +192,7 @@
   CJS_Value p1 = params[0];
   CJS_Value p2 = params[1];
   CJS_Date jsDate;
-  if (!p2.ConvertToDate(jsDate)) {
+  if (!p2.ConvertToDate(pRuntime->GetIsolate(), jsDate)) {
     sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPRINT1);
     return FALSE;
   }
@@ -199,7 +204,7 @@
 
   if (p1.GetType() == CJS_Value::VT_number) {
     CFX_WideString swResult;
-    switch (p1.ToInt()) {
+    switch (p1.ToInt(pRuntime->GetIsolate())) {
       case 0:
         swResult.Format(L"D:%04d%02d%02d%02d%02d%02d",
                         jsDate.GetYear(pRuntime->GetIsolate()),
@@ -232,19 +237,20 @@
         return FALSE;
     }
 
-    vRet = swResult.c_str();
+    vRet = CJS_Value(pRuntime, swResult.c_str());
     return TRUE;
   }
 
   if (p1.GetType() == CJS_Value::VT_string) {
-    if (iSize > 2 && params[2].ToBool()) {
+    if (iSize > 2 && params[2].ToBool(pRuntime->GetIsolate())) {
       sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_NOTSUPPORT);
       return FALSE;  // currently, it doesn't support XFAPicture.
     }
 
     // Convert PDF-style format specifiers to wcsftime specifiers. Remove any
     // pre-existing %-directives before inserting our own.
-    std::basic_string<wchar_t> cFormat = p1.ToCFXWideString().c_str();
+    std::basic_string<wchar_t> cFormat =
+        p1.ToCFXWideString(pRuntime->GetIsolate()).c_str();
     cFormat.erase(std::remove(cFormat.begin(), cFormat.end(), '%'),
                   cFormat.end());
 
@@ -304,7 +310,7 @@
     wchar_t buf[64] = {};
     wcsftime(buf, 64, cFormat.c_str(), &time);
     cFormat = buf;
-    vRet = cFormat.c_str();
+    vRet = CJS_Value(pRuntime, cFormat.c_str());
     return TRUE;
   }
 
@@ -317,12 +323,18 @@
                      const std::vector<CJS_Value>& params,
                      CJS_Value& vRet,
                      CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
   if (params.size() < 2) {
     sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
-  vRet =
-      printx(params[0].ToCFXWideString(), params[1].ToCFXWideString()).c_str();
+
+  vRet = CJS_Value(pRuntime,
+                   printx(params[0].ToCFXWideString(pRuntime->GetIsolate()),
+                          params[1].ToCFXWideString(pRuntime->GetIsolate()))
+                       .c_str());
+
   return TRUE;
 }
 
@@ -431,23 +443,22 @@
                     const std::vector<CJS_Value>& params,
                     CJS_Value& vRet,
                     CFX_WideString& sError) {
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
   int iSize = params.size();
   if (iSize < 2)
     return FALSE;
 
-  CFX_WideString sFormat = params[0].ToCFXWideString();
-  CFX_WideString sDate = params[1].ToCFXWideString();
+  CFX_WideString sFormat = params[0].ToCFXWideString(pRuntime->GetIsolate());
+  CFX_WideString sDate = params[1].ToCFXWideString(pRuntime->GetIsolate());
   double dDate = JS_GetDateTime();
   if (sDate.GetLength() > 0) {
     dDate = CJS_PublicMethods::MakeRegularDate(sDate, sFormat, nullptr);
   }
 
   if (!JS_PortIsNan(dDate)) {
-    CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
-    vRet = CJS_Value(pRuntime, CJS_Date(pRuntime->GetIsolate(), dDate)
-                                   .ToV8Date(pRuntime->GetIsolate()));
+    vRet = CJS_Value(pRuntime, CJS_Date(pRuntime->GetIsolate(), dDate));
   } else {
-    vRet.SetNull();
+    vRet.SetNull(pRuntime);
   }
 
   return TRUE;
@@ -458,16 +469,20 @@
                          CJS_Value& vRet,
                          CFX_WideString& sError) {
   CJS_Context* pContext = static_cast<CJS_Context*>(cc);
+  CJS_Runtime* pRuntime = CJS_Runtime::FromContext(cc);
+
   if (params.size() < 1) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
     return FALSE;
   }
-  int arg = params[0].ToInt();
+
+  int arg = params[0].ToInt(pRuntime->GetIsolate());
   if (arg < 0 || arg > 255) {
     sError = JSGetStringFromID(pContext, IDS_STRING_JSVALUEERROR);
     return FALSE;
   }
+
   CFX_WideString wStr(static_cast<FX_WCHAR>(arg));
-  vRet = wStr.c_str();
+  vRet = CJS_Value(pRuntime, wStr.c_str());
   return TRUE;
 }