Remove CJS_Array

This CL removes the CJS_Array wrapper and uses the v8 objects directly.

Change-Id: I904f76e59e27d65db4b4d0bbd503fddb3e8cfc6f
Reviewed-on: https://pdfium-review.googlesource.com/16830
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp
index e4903a5..0280af4 100644
--- a/fpdfsdk/javascript/Document.cpp
+++ b/fpdfsdk/javascript/Document.cpp
@@ -507,15 +507,18 @@
     return CJS_Return(true);
   }
 
-  CJS_Array aName;
-  if (params[0]->IsString())
-    aName.SetElement(pRuntime, 0, params[0]);
-  else
-    aName = CJS_Array(pRuntime->ToArray(params[0]));
+  v8::Local<v8::Array> array;
+  if (params[0]->IsString()) {
+    array = pRuntime->NewArray();
+    pRuntime->PutArrayElement(array, 0, params[0]);
+  } else {
+    array = pRuntime->ToArray(params[0]);
+  }
 
   std::vector<CPDF_FormField*> aFields;
-  for (int i = 0, isz = aName.GetLength(pRuntime); i < isz; ++i) {
-    WideString swVal = pRuntime->ToWideString(aName.GetElement(pRuntime, i));
+  for (size_t i = 0; i < pRuntime->GetArrayLength(array); ++i) {
+    WideString swVal =
+        pRuntime->ToWideString(pRuntime->GetArrayElement(array, i));
     for (int j = 0, jsz = pPDFForm->CountFields(swVal); j < jsz; ++j)
       aFields.push_back(pPDFForm->GetField(j, swVal));
   }
@@ -549,7 +552,7 @@
   if (!m_pFormFillEnv)
     return CJS_Return(JSGetStringFromID(IDS_STRING_JSBADOBJECT));
 
-  CJS_Array aFields;
+  v8::Local<v8::Array> aFields;
   WideString strURL;
   bool bFDF = true;
   bool bEmpty = false;
@@ -560,7 +563,7 @@
     if (nSize > 2)
       bEmpty = pRuntime->ToBoolean(params[2]);
     if (nSize > 3)
-      aFields = CJS_Array(pRuntime->ToArray(params[3]));
+      aFields = pRuntime->ToArray(params[3]);
   } else if (params[0]->IsObject()) {
     v8::Local<v8::Object> pObj = pRuntime->ToObject(params[0]);
     v8::Local<v8::Value> pValue = pRuntime->GetObjectProperty(pObj, L"cURL");
@@ -569,13 +572,13 @@
 
     bFDF = pRuntime->ToBoolean(pRuntime->GetObjectProperty(pObj, L"bFDF"));
     bEmpty = pRuntime->ToBoolean(pRuntime->GetObjectProperty(pObj, L"bEmpty"));
-    aFields = CJS_Array(
-        pRuntime->ToArray(pRuntime->GetObjectProperty(pObj, L"aFields")));
+    aFields = pRuntime->ToArray(pRuntime->GetObjectProperty(pObj, L"aFields"));
   }
 
   CPDFSDK_InterForm* pInterForm = m_pFormFillEnv->GetInterForm();
   CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
-  if (aFields.GetLength(pRuntime) == 0 && bEmpty) {
+
+  if (pRuntime->GetArrayLength(aFields) == 0 && bEmpty) {
     if (pPDFInterForm->CheckRequiredFields(nullptr, true)) {
       pRuntime->BeginBlock();
       pInterForm->SubmitForm(strURL, false);
@@ -585,8 +588,9 @@
   }
 
   std::vector<CPDF_FormField*> fieldObjects;
-  for (int i = 0, sz = aFields.GetLength(pRuntime); i < sz; ++i) {
-    WideString sName = pRuntime->ToWideString(aFields.GetElement(pRuntime, i));
+  for (size_t i = 0; i < pRuntime->GetArrayLength(aFields); ++i) {
+    WideString sName =
+        pRuntime->ToWideString(pRuntime->GetArrayElement(aFields, i));
     CPDF_InterForm* pPDFForm = pInterForm->GetInterForm();
     for (int j = 0, jsz = pPDFForm->CountFields(sName); j < jsz; ++j) {
       CPDF_FormField* pField = pPDFForm->GetField(j, sName);
@@ -1063,8 +1067,7 @@
   // the PDF spec.
 
   int nPageNo = m_pFormFillEnv->GetPageCount();
-  CJS_Array annots;
-
+  v8::Local<v8::Array> annots = pRuntime->NewArray();
   for (int i = 0; i < nPageNo; ++i) {
     CPDFSDK_PageView* pPageView = m_pFormFillEnv->GetPageView(i);
     if (!pPageView)
@@ -1084,15 +1087,13 @@
           static_cast<CJS_Annot*>(pRuntime->GetObjectPrivate(pObj));
       Annot* pAnnot = static_cast<Annot*>(pJS_Annot->GetEmbedObject());
       pAnnot->SetSDKAnnot(static_cast<CPDFSDK_BAAnnot*>(pSDKAnnotCur.Get()));
-      annots.SetElement(pRuntime, i,
-                        pJS_Annot
-                            ? v8::Local<v8::Value>(pJS_Annot->ToV8Object())
-                            : v8::Local<v8::Value>());
+      pRuntime->PutArrayElement(
+          annots, i,
+          pJS_Annot ? v8::Local<v8::Value>(pJS_Annot->ToV8Object())
+                    : v8::Local<v8::Value>());
     }
   }
-  if (annots.ToV8Value().IsEmpty())
-    return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(annots.ToV8Value());
+  return CJS_Return(annots);
 }
 
 CJS_Return Document::getAnnot3D(
@@ -1148,7 +1149,7 @@
   if (m_IconNames.empty())
     return CJS_Return(pRuntime->NewUndefined());
 
-  CJS_Array Icons;
+  v8::Local<v8::Array> Icons = pRuntime->NewArray();
   int i = 0;
   for (const auto& name : m_IconNames) {
     v8::Local<v8::Object> pObj =
@@ -1160,14 +1161,12 @@
         static_cast<CJS_Icon*>(pRuntime->GetObjectPrivate(pObj));
     Icon* pIcon = static_cast<Icon*>(pJS_Icon->GetEmbedObject());
     pIcon->SetIconName(name);
-    Icons.SetElement(pRuntime, i++,
-                     pJS_Icon ? v8::Local<v8::Value>(pJS_Icon->ToV8Object())
-                              : v8::Local<v8::Value>());
+    pRuntime->PutArrayElement(Icons, i++,
+                              pJS_Icon
+                                  ? v8::Local<v8::Value>(pJS_Icon->ToV8Object())
+                                  : v8::Local<v8::Value>());
   }
-
-  if (Icons.ToV8Value().IsEmpty())
-    return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(Icons.ToV8Value());
+  return CJS_Return(Icons);
 }
 
 CJS_Return Document::set_icons(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
diff --git a/fpdfsdk/javascript/Field.cpp b/fpdfsdk/javascript/Field.cpp
index 1778295..12791e7 100644
--- a/fpdfsdk/javascript/Field.cpp
+++ b/fpdfsdk/javascript/Field.cpp
@@ -792,14 +792,14 @@
   if (count == 1)
     return CJS_Return(pRuntime->NewNumber(pFormField->GetSelectedIndex(0)));
 
-  CJS_Array SelArray;
-  for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
-    SelArray.SetElement(pRuntime, i,
-                        pRuntime->NewNumber(pFormField->GetSelectedIndex(i)));
+  v8::Local<v8::Array> SelArray = pRuntime->NewArray();
+  for (int i = 0; i < count; i++) {
+    pRuntime->PutArrayElement(
+        SelArray, i, pRuntime->NewNumber(pFormField->GetSelectedIndex(i)));
   }
-  if (SelArray.ToV8Value().IsEmpty())
+  if (SelArray.IsEmpty())
     return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(SelArray.ToV8Value());
+  return CJS_Return(SelArray);
 }
 
 CJS_Return Field::set_current_value_indices(CJS_Runtime* pRuntime,
@@ -811,9 +811,11 @@
   if (vp->IsNumber()) {
     array.push_back(pRuntime->ToInt32(vp));
   } else if (!vp.IsEmpty() && vp->IsArray()) {
-    CJS_Array SelArray(pRuntime->ToArray(vp));
-    for (int i = 0, sz = SelArray.GetLength(pRuntime); i < sz; i++)
-      array.push_back(pRuntime->ToInt32(SelArray.GetElement(pRuntime, i)));
+    v8::Local<v8::Array> SelArray = pRuntime->ToArray(vp);
+    for (size_t i = 0; i < pRuntime->GetArrayLength(SelArray); i++) {
+      array.push_back(
+          pRuntime->ToInt32(pRuntime->GetArrayElement(SelArray, i)));
+    }
   }
 
   if (m_bDelay) {
@@ -1058,12 +1060,12 @@
     return CJS_Return(false);
   }
 
-  CJS_Array ExportValuesArray;
+  v8::Local<v8::Array> ExportValuesArray = pRuntime->NewArray();
   if (m_nFormControlIndex < 0) {
     for (int i = 0, sz = pFormField->CountControls(); i < sz; i++) {
       CPDF_FormControl* pFormControl = pFormField->GetControl(i);
-      ExportValuesArray.SetElement(
-          pRuntime, i,
+      pRuntime->PutArrayElement(
+          ExportValuesArray, i,
           pRuntime->NewString(pFormControl->GetExportValue().c_str()));
     }
   } else {
@@ -1075,14 +1077,11 @@
     if (!pFormControl)
       return CJS_Return(false);
 
-    ExportValuesArray.SetElement(
-        pRuntime, 0,
+    pRuntime->PutArrayElement(
+        ExportValuesArray, 0,
         pRuntime->NewString(pFormControl->GetExportValue().c_str()));
   }
-
-  if (ExportValuesArray.ToV8Value().IsEmpty())
-    return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(ExportValuesArray.ToV8Value());
+  return CJS_Return(ExportValuesArray);
 }
 
 CJS_Return Field::set_export_values(CJS_Runtime* pRuntime,
@@ -1160,10 +1159,10 @@
     return CJS_Return(false);
   }
 
-  CJS_Array array = color::ConvertPWLColorToArray(pRuntime, color);
-  if (array.ToV8Value().IsEmpty())
+  v8::Local<v8::Value> array = color::ConvertPWLColorToArray(pRuntime, color);
+  if (array.IsEmpty())
     return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(array.ToV8Value());
+  return CJS_Return(array);
 }
 
 CJS_Return Field::set_fill_color(CJS_Runtime* pRuntime,
@@ -1417,7 +1416,7 @@
   if (widgets.empty())
     return CJS_Return(pRuntime->NewNumber(-1));
 
-  CJS_Array PageArray;
+  v8::Local<v8::Array> PageArray = pRuntime->NewArray();
   int i = 0;
   for (const auto& pObserved : widgets) {
     if (!pObserved)
@@ -1428,15 +1427,12 @@
     if (!pPageView)
       return CJS_Return(false);
 
-    PageArray.SetElement(
-        pRuntime, i,
+    pRuntime->PutArrayElement(
+        PageArray, i,
         pRuntime->NewNumber(static_cast<int32_t>(pPageView->GetPageIndex())));
     ++i;
   }
-
-  if (PageArray.ToV8Value().IsEmpty())
-    return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(PageArray.ToV8Value());
+  return CJS_Return(PageArray);
 }
 
 CJS_Return Field::set_page(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
@@ -1587,19 +1583,17 @@
     return CJS_Return(false);
 
   CFX_FloatRect crRect = pWidget->GetRect();
-  CJS_Array rcArray;
-  rcArray.SetElement(pRuntime, 0,
-                     pRuntime->NewNumber(static_cast<int32_t>(crRect.left)));
-  rcArray.SetElement(pRuntime, 1,
-                     pRuntime->NewNumber(static_cast<int32_t>(crRect.top)));
-  rcArray.SetElement(pRuntime, 2,
-                     pRuntime->NewNumber(static_cast<int32_t>(crRect.right)));
-  rcArray.SetElement(pRuntime, 3,
-                     pRuntime->NewNumber(static_cast<int32_t>(crRect.bottom)));
+  v8::Local<v8::Array> rcArray = pRuntime->NewArray();
+  pRuntime->PutArrayElement(
+      rcArray, 0, pRuntime->NewNumber(static_cast<int32_t>(crRect.left)));
+  pRuntime->PutArrayElement(
+      rcArray, 1, pRuntime->NewNumber(static_cast<int32_t>(crRect.top)));
+  pRuntime->PutArrayElement(
+      rcArray, 2, pRuntime->NewNumber(static_cast<int32_t>(crRect.right)));
+  pRuntime->PutArrayElement(
+      rcArray, 3, pRuntime->NewNumber(static_cast<int32_t>(crRect.bottom)));
 
-  if (rcArray.ToV8Value().IsEmpty())
-    return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(rcArray.ToV8Value());
+  return CJS_Return(rcArray);
 }
 
 CJS_Return Field::set_rect(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
@@ -1608,16 +1602,19 @@
   if (vp.IsEmpty() || !vp->IsArray())
     return CJS_Return(false);
 
-  CJS_Array rcArray(pRuntime->ToArray(vp));
+  v8::Local<v8::Array> rcArray = pRuntime->ToArray(vp);
+  if (pRuntime->GetArrayLength(rcArray) < 4)
+    return CJS_Return(false);
+
   float pArray[4];
-  pArray[0] =
-      static_cast<float>(pRuntime->ToInt32(rcArray.GetElement(pRuntime, 0)));
-  pArray[1] =
-      static_cast<float>(pRuntime->ToInt32(rcArray.GetElement(pRuntime, 1)));
-  pArray[2] =
-      static_cast<float>(pRuntime->ToInt32(rcArray.GetElement(pRuntime, 2)));
-  pArray[3] =
-      static_cast<float>(pRuntime->ToInt32(rcArray.GetElement(pRuntime, 3)));
+  pArray[0] = static_cast<float>(
+      pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 0)));
+  pArray[1] = static_cast<float>(
+      pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 1)));
+  pArray[2] = static_cast<float>(
+      pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 2)));
+  pArray[3] = static_cast<float>(
+      pRuntime->ToInt32(pRuntime->GetArrayElement(rcArray, 3)));
 
   CFX_FloatRect crRect(pArray);
   if (m_bDelay) {
@@ -1791,10 +1788,10 @@
     return CJS_Return(false);
   }
 
-  CJS_Array array = color::ConvertPWLColorToArray(pRuntime, color);
-  if (array.ToV8Value().IsEmpty())
+  v8::Local<v8::Value> array = color::ConvertPWLColorToArray(pRuntime, color);
+  if (array.IsEmpty())
     return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(array.ToV8Value());
+  return CJS_Return(array);
 }
 
 CJS_Return Field::set_stroke_color(CJS_Runtime* pRuntime,
@@ -1891,10 +1888,10 @@
   if (iColorType == CFX_Color::kTransparent)
     crRet = CFX_Color(CFX_Color::kTransparent);
 
-  CJS_Array array = color::ConvertPWLColorToArray(pRuntime, crRet);
-  if (array.ToV8Value().IsEmpty())
+  v8::Local<v8::Value> array = color::ConvertPWLColorToArray(pRuntime, crRet);
+  if (array.IsEmpty())
     return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(array.ToV8Value());
+  return CJS_Return(array);
 }
 
 CJS_Return Field::set_text_color(CJS_Runtime* pRuntime,
@@ -2033,7 +2030,7 @@
       break;
     case FIELDTYPE_LISTBOX: {
       if (pFormField->CountSelectedItems() > 1) {
-        CJS_Array ValueArray;
+        v8::Local<v8::Array> ValueArray = pRuntime->NewArray();
         v8::Local<v8::Value> ElementValue;
         int iIndex;
         for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
@@ -2044,13 +2041,9 @@
             ElementValue =
                 pRuntime->NewString(pFormField->GetOptionLabel(iIndex).c_str());
           }
-          ValueArray.SetElement(pRuntime, i, ElementValue);
+          pRuntime->PutArrayElement(ValueArray, i, ElementValue);
         }
-
-        if (ValueArray.ToV8Value().IsEmpty())
-          ret = pRuntime->NewArray();
-        else
-          ret = ValueArray.ToV8Value();
+        ret = ValueArray;
       } else {
         ret = pRuntime->NewString(pFormField->GetValue().c_str());
       }
@@ -2085,10 +2078,10 @@
 
   std::vector<WideString> strArray;
   if (!vp.IsEmpty() && vp->IsArray()) {
-    CJS_Array ValueArray(pRuntime->ToArray(vp));
-    for (int i = 0, sz = ValueArray.GetLength(pRuntime); i < sz; i++) {
+    v8::Local<v8::Array> ValueArray = pRuntime->ToArray(vp);
+    for (size_t i = 0; i < pRuntime->GetArrayLength(ValueArray); i++) {
       strArray.push_back(
-          pRuntime->ToWideString(ValueArray.GetElement(pRuntime, i)));
+          pRuntime->ToWideString(pRuntime->GetArrayElement(ValueArray, i)));
     }
   } else {
     strArray.push_back(pRuntime->ToWideString(vp));
@@ -2388,8 +2381,7 @@
             [](const std::unique_ptr<WideString>& p1,
                const std::unique_ptr<WideString>& p2) { return *p1 < *p2; });
 
-  CJS_Array FormFieldArray;
-
+  v8::Local<v8::Array> FormFieldArray = pRuntime->NewArray();
   int j = 0;
   for (const auto& pStr : swSort) {
     v8::Local<v8::Object> pObj =
@@ -2401,15 +2393,12 @@
         static_cast<CJS_Field*>(pRuntime->GetObjectPrivate(pObj));
     Field* pField = static_cast<Field*>(pJSField->GetEmbedObject());
     pField->AttachField(m_pJSDoc, *pStr);
-    FormFieldArray.SetElement(pRuntime, j++,
+    pRuntime->PutArrayElement(FormFieldArray, j++,
                               pJSField
                                   ? v8::Local<v8::Value>(pJSField->ToV8Object())
                                   : v8::Local<v8::Value>());
   }
-
-  if (FormFieldArray.ToV8Value().IsEmpty())
-    return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(FormFieldArray.ToV8Value());
+  return CJS_Return(FormFieldArray);
 }
 
 CJS_Return Field::getItemAt(CJS_Runtime* pRuntime,
diff --git a/fpdfsdk/javascript/JS_Value.cpp b/fpdfsdk/javascript/JS_Value.cpp
index dee06e6..fdc8b87 100644
--- a/fpdfsdk/javascript/JS_Value.cpp
+++ b/fpdfsdk/javascript/JS_Value.cpp
@@ -179,36 +179,6 @@
 
 CJS_Return::~CJS_Return() = default;
 
-CJS_Array::CJS_Array() {}
-
-CJS_Array::CJS_Array(v8::Local<v8::Array> pArray) : m_pArray(pArray) {}
-
-CJS_Array::CJS_Array(const CJS_Array& other) = default;
-
-CJS_Array::~CJS_Array() {}
-
-v8::Local<v8::Value> CJS_Array::GetElement(CJS_Runtime* pRuntime,
-                                           unsigned index) const {
-  if (!m_pArray.IsEmpty())
-    return {pRuntime->GetArrayElement(m_pArray, index)};
-  return {};
-}
-
-void CJS_Array::SetElement(CJS_Runtime* pRuntime,
-                           unsigned index,
-                           v8::Local<v8::Value> value) {
-  if (m_pArray.IsEmpty())
-    m_pArray = pRuntime->NewArray();
-
-  pRuntime->PutArrayElement(m_pArray, index, value);
-}
-
-int CJS_Array::GetLength(CJS_Runtime* pRuntime) const {
-  if (m_pArray.IsEmpty())
-    return 0;
-  return pRuntime->GetArrayLength(m_pArray);
-}
-
 double JS_GetDateTime() {
   if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
     return 0;
diff --git a/fpdfsdk/javascript/JS_Value.h b/fpdfsdk/javascript/JS_Value.h
index 2d5a390..046d959 100644
--- a/fpdfsdk/javascript/JS_Value.h
+++ b/fpdfsdk/javascript/JS_Value.h
@@ -11,8 +11,6 @@
 
 #include "fxjs/fxjs_v8.h"
 
-class CJS_Array;
-class CJS_Date;
 class CJS_Document;
 class CJS_Object;
 class CJS_Runtime;
@@ -39,27 +37,6 @@
   v8::Local<v8::Value> return_;
 };
 
-class CJS_Array {
- public:
-  CJS_Array();
-  explicit CJS_Array(v8::Local<v8::Array> pArray);
-  CJS_Array(const CJS_Array& other);
-  virtual ~CJS_Array();
-
-  int GetLength(CJS_Runtime* pRuntime) const;
-
-  // These two calls may re-enter JS (and hence invalidate objects).
-  v8::Local<v8::Value> GetElement(CJS_Runtime* pRuntime, unsigned index) const;
-  void SetElement(CJS_Runtime* pRuntime,
-                  unsigned index,
-                  v8::Local<v8::Value> value);
-
-  v8::Local<v8::Value> ToV8Value() const { return m_pArray; }
-
- private:
-  mutable v8::Local<v8::Array> m_pArray;
-};
-
 double JS_GetDateTime();
 int JS_GetYearFromTime(double dt);
 int JS_GetMonthFromTime(double dt);
diff --git a/fpdfsdk/javascript/PublicMethods.cpp b/fpdfsdk/javascript/PublicMethods.cpp
index ed74c53..08c8147 100644
--- a/fpdfsdk/javascript/PublicMethods.cpp
+++ b/fpdfsdk/javascript/PublicMethods.cpp
@@ -247,10 +247,11 @@
   return dValue1;
 }
 
-CJS_Array CJS_PublicMethods::AF_MakeArrayFromList(CJS_Runtime* pRuntime,
-                                                  v8::Local<v8::Value> val) {
+v8::Local<v8::Array> CJS_PublicMethods::AF_MakeArrayFromList(
+    CJS_Runtime* pRuntime,
+    v8::Local<v8::Value> val) {
   if (!val.IsEmpty() && val->IsArray())
-    return CJS_Array(pRuntime->ToArray(val));
+    return pRuntime->ToArray(val);
 
   WideString wsStr = pRuntime->ToWideString(val);
   ByteString t = ByteString::FromUnicode(wsStr);
@@ -259,12 +260,13 @@
   int ch = ',';
   int nIndex = 0;
 
-  CJS_Array StrArray;
+  v8::Local<v8::Array> StrArray = pRuntime->NewArray();
   while (*p) {
     const char* pTemp = strchr(p, ch);
     if (!pTemp) {
-      StrArray.SetElement(pRuntime, nIndex,
-                          pRuntime->NewString(StrTrim(ByteString(p)).c_str()));
+      pRuntime->PutArrayElement(
+          StrArray, nIndex,
+          pRuntime->NewString(StrTrim(ByteString(p)).c_str()));
       break;
     }
 
@@ -272,8 +274,9 @@
     strncpy(pSub, p, pTemp - p);
     *(pSub + (pTemp - p)) = '\0';
 
-    StrArray.SetElement(pRuntime, nIndex,
-                        pRuntime->NewString(StrTrim(ByteString(pSub)).c_str()));
+    pRuntime->PutArrayElement(
+        StrArray, nIndex,
+        pRuntime->NewString(StrTrim(ByteString(pSub)).c_str()));
     delete[] pSub;
 
     nIndex++;
@@ -893,29 +896,29 @@
       Value = L"(" + Value + L")";
     if (iNegStyle == 1 || iNegStyle == 3) {
       if (Field* fTarget = pEvent->Target_Field()) {
-        CJS_Array arColor;
-        arColor.SetElement(pRuntime, 0, pRuntime->NewString(L"RGB"));
-        arColor.SetElement(pRuntime, 1, pRuntime->NewNumber(1));
-        arColor.SetElement(pRuntime, 2, pRuntime->NewNumber(0));
-        arColor.SetElement(pRuntime, 3, pRuntime->NewNumber(0));
-        fTarget->set_text_color(pRuntime, arColor.ToV8Value());
+        v8::Local<v8::Array> arColor = pRuntime->NewArray();
+        pRuntime->PutArrayElement(arColor, 0, pRuntime->NewString(L"RGB"));
+        pRuntime->PutArrayElement(arColor, 1, pRuntime->NewNumber(1));
+        pRuntime->PutArrayElement(arColor, 2, pRuntime->NewNumber(0));
+        pRuntime->PutArrayElement(arColor, 3, pRuntime->NewNumber(0));
+        fTarget->set_text_color(pRuntime, arColor);
       }
     }
   } else {
     if (iNegStyle == 1 || iNegStyle == 3) {
       if (Field* fTarget = pEvent->Target_Field()) {
-        CJS_Array arColor;
-        arColor.SetElement(pRuntime, 0, pRuntime->NewString(L"RGB"));
-        arColor.SetElement(pRuntime, 1, pRuntime->NewNumber(0));
-        arColor.SetElement(pRuntime, 2, pRuntime->NewNumber(0));
-        arColor.SetElement(pRuntime, 3, pRuntime->NewNumber(0));
+        v8::Local<v8::Array> arColor = pRuntime->NewArray();
+        pRuntime->PutArrayElement(arColor, 0, pRuntime->NewString(L"RGB"));
+        pRuntime->PutArrayElement(arColor, 1, pRuntime->NewNumber(0));
+        pRuntime->PutArrayElement(arColor, 2, pRuntime->NewNumber(0));
+        pRuntime->PutArrayElement(arColor, 3, pRuntime->NewNumber(0));
 
         CJS_Return result = fTarget->get_text_color(pRuntime);
         CFX_Color crProp = color::ConvertArrayToPWLColor(
-            pRuntime, CJS_Array(pRuntime->ToArray(result.Return())));
+            pRuntime, pRuntime->ToArray(result.Return()));
         CFX_Color crColor = color::ConvertArrayToPWLColor(pRuntime, arColor);
         if (crColor != crProp)
-          fTarget->set_text_color(pRuntime, arColor.ToV8Value());
+          fTarget->set_text_color(pRuntime, arColor);
       }
     }
   }
@@ -1602,12 +1605,12 @@
   WideString sFunction = pRuntime->ToWideString(params[0]);
   double dValue = wcscmp(sFunction.c_str(), L"PRD") == 0 ? 1.0 : 0.0;
 
-  CJS_Array FieldNameArray = AF_MakeArrayFromList(pRuntime, params[0]);
+  v8::Local<v8::Array> FieldNameArray =
+      AF_MakeArrayFromList(pRuntime, params[0]);
   int nFieldsCount = 0;
-
-  for (int i = 0, isz = FieldNameArray.GetLength(pRuntime); i < isz; i++) {
+  for (size_t i = 0; i < pRuntime->GetArrayLength(FieldNameArray); i++) {
     WideString wsFieldName =
-        pRuntime->ToWideString(FieldNameArray.GetElement(pRuntime, i));
+        pRuntime->ToWideString(pRuntime->GetArrayElement(FieldNameArray, i));
 
     for (int j = 0, jsz = pInterForm->CountFields(wsFieldName); j < jsz; j++) {
       if (CPDF_FormField* pFormField = pInterForm->GetField(j, wsFieldName)) {
@@ -1735,24 +1738,22 @@
     str = L"0" + str;
 
   WideString sPart;
-  CJS_Array nums;
+  v8::Local<v8::Array> nums = pRuntime->NewArray();
   int nIndex = 0;
   for (const auto& wc : str) {
     if (std::iswdigit(wc)) {
       sPart += wc;
     } else if (sPart.GetLength() > 0) {
-      nums.SetElement(pRuntime, nIndex, pRuntime->NewString(sPart.c_str()));
+      pRuntime->PutArrayElement(nums, nIndex,
+                                pRuntime->NewString(sPart.c_str()));
       sPart = L"";
       nIndex++;
     }
   }
   if (sPart.GetLength() > 0)
-    nums.SetElement(pRuntime, nIndex, pRuntime->NewString(sPart.c_str()));
+    pRuntime->PutArrayElement(nums, nIndex, pRuntime->NewString(sPart.c_str()));
 
-  if (nums.GetLength(pRuntime) > 0) {
-    if (nums.ToV8Value().IsEmpty())
-      return CJS_Return(pRuntime->NewArray());
-    return CJS_Return(nums.ToV8Value());
-  }
+  if (pRuntime->GetArrayLength(nums) > 0)
+    return CJS_Return(nums);
   return CJS_Return(pRuntime->NewUndefined());
 }
diff --git a/fpdfsdk/javascript/PublicMethods.h b/fpdfsdk/javascript/PublicMethods.h
index 11fe342..12223b0 100644
--- a/fpdfsdk/javascript/PublicMethods.h
+++ b/fpdfsdk/javascript/PublicMethods.h
@@ -152,8 +152,8 @@
   static double AF_Simple(const wchar_t* sFuction,
                           double dValue1,
                           double dValue2);
-  static CJS_Array AF_MakeArrayFromList(CJS_Runtime* pRuntime,
-                                        v8::Local<v8::Value> val);
+  static v8::Local<v8::Array> AF_MakeArrayFromList(CJS_Runtime* pRuntime,
+                                                   v8::Local<v8::Value> val);
 };
 
 #endif  // FPDFSDK_JAVASCRIPT_PUBLICMETHODS_H_
diff --git a/fpdfsdk/javascript/app.cpp b/fpdfsdk/javascript/app.cpp
index e65ec2d..1d78c1d 100644
--- a/fpdfsdk/javascript/app.cpp
+++ b/fpdfsdk/javascript/app.cpp
@@ -224,15 +224,13 @@
   if (CFXJS_Engine::GetObjDefnID(pObj) == CJS_Document::g_nObjDefnID)
     pJSDocument = static_cast<CJS_Document*>(pRuntime->GetObjectPrivate(pObj));
 
-  CJS_Array aDocs;
-  aDocs.SetElement(pRuntime, 0,
-                   pJSDocument ? v8::Local<v8::Value>(pJSDocument->ToV8Object())
-                               : v8::Local<v8::Value>());
-  if (aDocs.GetLength(pRuntime) > 0) {
-    if (aDocs.ToV8Value().IsEmpty())
-      return CJS_Return(pRuntime->NewArray());
-    return CJS_Return(aDocs.ToV8Value());
-  }
+  v8::Local<v8::Array> aDocs = pRuntime->NewArray();
+  pRuntime->PutArrayElement(
+      aDocs, 0,
+      pJSDocument ? v8::Local<v8::Value>(pJSDocument->ToV8Object())
+                  : v8::Local<v8::Value>());
+  if (pRuntime->GetArrayLength(aDocs) > 0)
+    return CJS_Return(aDocs);
   return CJS_Return(pRuntime->NewUndefined());
 }
 
@@ -361,13 +359,13 @@
 
   WideString swMsg;
   if (newParams[0]->IsArray()) {
-    CJS_Array carray(pRuntime->ToArray(newParams[0]));
+    v8::Local<v8::Array> carray = pRuntime->ToArray(newParams[0]);
     swMsg = L"[";
-    for (int i = 0; i < carray.GetLength(pRuntime); ++i) {
+    for (size_t i = 0; i < pRuntime->GetArrayLength(carray); ++i) {
       if (i)
         swMsg += L", ";
 
-      swMsg += pRuntime->ToWideString(carray.GetElement(pRuntime, i));
+      swMsg += pRuntime->ToWideString(pRuntime->GetArrayElement(carray, i));
     }
     swMsg += L"]";
   } else {
diff --git a/fpdfsdk/javascript/color.cpp b/fpdfsdk/javascript/color.cpp
index 9ae4b18..ad5f8ac 100644
--- a/fpdfsdk/javascript/color.cpp
+++ b/fpdfsdk/javascript/color.cpp
@@ -39,29 +39,33 @@
 IMPLEMENT_JS_CLASS(CJS_Color, color, color)
 
 // static
-CJS_Array color::ConvertPWLColorToArray(CJS_Runtime* pRuntime,
-                                        const CFX_Color& color) {
-  CJS_Array array;
+v8::Local<v8::Array> color::ConvertPWLColorToArray(CJS_Runtime* pRuntime,
+                                                   const CFX_Color& color) {
+  v8::Local<v8::Array> array;
   switch (color.nColorType) {
     case CFX_Color::kTransparent:
-      array.SetElement(pRuntime, 0, pRuntime->NewString(L"T"));
+      array = pRuntime->NewArray();
+      pRuntime->PutArrayElement(array, 0, pRuntime->NewString(L"T"));
       break;
     case CFX_Color::kGray:
-      array.SetElement(pRuntime, 0, pRuntime->NewString(L"G"));
-      array.SetElement(pRuntime, 1, pRuntime->NewNumber(color.fColor1));
+      array = pRuntime->NewArray();
+      pRuntime->PutArrayElement(array, 0, pRuntime->NewString(L"G"));
+      pRuntime->PutArrayElement(array, 1, pRuntime->NewNumber(color.fColor1));
       break;
     case CFX_Color::kRGB:
-      array.SetElement(pRuntime, 0, pRuntime->NewString(L"RGB"));
-      array.SetElement(pRuntime, 1, pRuntime->NewNumber(color.fColor1));
-      array.SetElement(pRuntime, 2, pRuntime->NewNumber(color.fColor2));
-      array.SetElement(pRuntime, 3, pRuntime->NewNumber(color.fColor3));
+      array = pRuntime->NewArray();
+      pRuntime->PutArrayElement(array, 0, pRuntime->NewString(L"RGB"));
+      pRuntime->PutArrayElement(array, 1, pRuntime->NewNumber(color.fColor1));
+      pRuntime->PutArrayElement(array, 2, pRuntime->NewNumber(color.fColor2));
+      pRuntime->PutArrayElement(array, 3, pRuntime->NewNumber(color.fColor3));
       break;
     case CFX_Color::kCMYK:
-      array.SetElement(pRuntime, 0, pRuntime->NewString(L"CMYK"));
-      array.SetElement(pRuntime, 1, pRuntime->NewNumber(color.fColor1));
-      array.SetElement(pRuntime, 2, pRuntime->NewNumber(color.fColor2));
-      array.SetElement(pRuntime, 3, pRuntime->NewNumber(color.fColor3));
-      array.SetElement(pRuntime, 4, pRuntime->NewNumber(color.fColor4));
+      array = pRuntime->NewArray();
+      pRuntime->PutArrayElement(array, 0, pRuntime->NewString(L"CMYK"));
+      pRuntime->PutArrayElement(array, 1, pRuntime->NewNumber(color.fColor1));
+      pRuntime->PutArrayElement(array, 2, pRuntime->NewNumber(color.fColor2));
+      pRuntime->PutArrayElement(array, 3, pRuntime->NewNumber(color.fColor3));
+      pRuntime->PutArrayElement(array, 4, pRuntime->NewNumber(color.fColor4));
       break;
   }
   return array;
@@ -69,18 +73,20 @@
 
 // static
 CFX_Color color::ConvertArrayToPWLColor(CJS_Runtime* pRuntime,
-                                        const CJS_Array& array) {
-  int nArrayLen = array.GetLength(pRuntime);
+                                        v8::Local<v8::Array> array) {
+  int nArrayLen = pRuntime->GetArrayLength(array);
   if (nArrayLen < 1)
     return CFX_Color();
 
-  WideString sSpace = pRuntime->ToWideString(array.GetElement(pRuntime, 0));
+  WideString sSpace =
+      pRuntime->ToWideString(pRuntime->GetArrayElement(array, 0));
   if (sSpace == L"T")
     return CFX_Color(CFX_Color::kTransparent);
 
   float d1 = 0;
   if (nArrayLen > 1) {
-    d1 = static_cast<float>(pRuntime->ToDouble(array.GetElement(pRuntime, 1)));
+    d1 = static_cast<float>(
+        pRuntime->ToDouble(pRuntime->GetArrayElement(array, 1)));
   }
 
   if (sSpace == L"G")
@@ -88,17 +94,23 @@
 
   float d2 = 0;
   float d3 = 0;
-  if (nArrayLen > 2)
-    d2 = static_cast<float>(pRuntime->ToDouble(array.GetElement(pRuntime, 2)));
-  if (nArrayLen > 3)
-    d3 = static_cast<float>(pRuntime->ToDouble(array.GetElement(pRuntime, 3)));
+  if (nArrayLen > 2) {
+    d2 = static_cast<float>(
+        pRuntime->ToDouble(pRuntime->GetArrayElement(array, 2)));
+  }
+  if (nArrayLen > 3) {
+    d3 = static_cast<float>(
+        pRuntime->ToDouble(pRuntime->GetArrayElement(array, 3)));
+  }
 
   if (sSpace == L"RGB")
     return CFX_Color(CFX_Color::kRGB, d1, d2, d3);
 
   float d4 = 0;
-  if (nArrayLen > 4)
-    d4 = static_cast<float>(pRuntime->ToDouble(array.GetElement(pRuntime, 4)));
+  if (nArrayLen > 4) {
+    d4 = static_cast<float>(
+        pRuntime->ToDouble(pRuntime->GetArrayElement(array, 4)));
+  }
   if (sSpace == L"CMYK")
     return CFX_Color(CFX_Color::kCMYK, d1, d2, d3, d4);
 
@@ -222,10 +234,10 @@
 }
 
 CJS_Return color::GetPropertyHelper(CJS_Runtime* pRuntime, CFX_Color* var) {
-  CJS_Array array = ConvertPWLColorToArray(pRuntime, *var);
-  if (array.ToV8Value().IsEmpty())
+  v8::Local<v8::Value> array = ConvertPWLColorToArray(pRuntime, *var);
+  if (array.IsEmpty())
     return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(array.ToV8Value());
+  return CJS_Return(array);
 }
 
 CJS_Return color::SetPropertyHelper(CJS_Runtime* pRuntime,
@@ -234,7 +246,7 @@
   if (vp.IsEmpty() || !vp->IsArray())
     return CJS_Return(false);
 
-  *var = ConvertArrayToPWLColor(pRuntime, CJS_Array(pRuntime->ToArray(vp)));
+  *var = ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(vp));
   return CJS_Return(true);
 }
 
@@ -258,13 +270,13 @@
     nColorType = CFX_Color::kCMYK;
 
   CFX_Color color =
-      ConvertArrayToPWLColor(pRuntime, CJS_Array(pRuntime->ToArray(params[0])));
+      ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[0]));
 
-  CJS_Array array =
+  v8::Local<v8::Value> array =
       ConvertPWLColorToArray(pRuntime, color.ConvertColorType(nColorType));
-  if (array.ToV8Value().IsEmpty())
+  if (array.IsEmpty())
     return CJS_Return(pRuntime->NewArray());
-  return CJS_Return(array.ToV8Value());
+  return CJS_Return(array);
 }
 
 CJS_Return color::equal(CJS_Runtime* pRuntime,
@@ -277,9 +289,9 @@
   }
 
   CFX_Color color1 =
-      ConvertArrayToPWLColor(pRuntime, CJS_Array(pRuntime->ToArray(params[0])));
+      ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[0]));
   CFX_Color color2 =
-      ConvertArrayToPWLColor(pRuntime, CJS_Array(pRuntime->ToArray(params[1])));
+      ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[1]));
 
   color1 = color1.ConvertColorType(color2.nColorType);
   return CJS_Return(pRuntime->NewBoolean(color1 == color2));
diff --git a/fpdfsdk/javascript/color.h b/fpdfsdk/javascript/color.h
index 454de57..cbb759c 100644
--- a/fpdfsdk/javascript/color.h
+++ b/fpdfsdk/javascript/color.h
@@ -14,10 +14,10 @@
 
 class color : public CJS_EmbedObj {
  public:
-  static CJS_Array ConvertPWLColorToArray(CJS_Runtime* pRuntime,
-                                          const CFX_Color& color);
+  static v8::Local<v8::Array> ConvertPWLColorToArray(CJS_Runtime* pRuntime,
+                                                     const CFX_Color& color);
   static CFX_Color ConvertArrayToPWLColor(CJS_Runtime* pRuntime,
-                                          const CJS_Array& array);
+                                          v8::Local<v8::Array> array);
 
   explicit color(CJS_Object* pJSObject);
   ~color() override;