Consolidate some tests in new fxv8:: functions.

Task #2 from the referenced bug.

Bug: pdfium:1610
Change-Id: I2422b3f8ffe4254388d7b705985b3d3667ecf9f8
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/75891
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cjs_color.cpp b/fxjs/cjs_color.cpp
index b9e415e..43fc1d0 100644
--- a/fxjs/cjs_color.cpp
+++ b/fxjs/cjs_color.cpp
@@ -14,6 +14,7 @@
 #include "fxjs/cjs_eventrecorder.h"
 #include "fxjs/cjs_object.h"
 #include "fxjs/cjs_runtime.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/js_define.h"
 
 const JSPropertySpec CJS_Color::PropertySpecs[] = {
@@ -273,7 +274,7 @@
   if (params.size() < 2)
     return CJS_Result::Failure(JSMessage::kParamError);
 
-  if (params[0].IsEmpty() || !params[0]->IsArray())
+  if (!fxv8::IsArray(params[0]))
     return CJS_Result::Failure(JSMessage::kTypeError);
 
   WideString sDestSpace = pRuntime->ToWideString(params[1]);
@@ -302,10 +303,8 @@
   if (params.size() < 2)
     return CJS_Result::Failure(JSMessage::kParamError);
 
-  if (params[0].IsEmpty() || !params[0]->IsArray() || params[1].IsEmpty() ||
-      !params[1]->IsArray()) {
+  if (!fxv8::IsArray(params[0]) || !fxv8::IsArray(params[1]))
     return CJS_Result::Failure(JSMessage::kTypeError);
-  }
 
   CFX_Color color1 =
       ConvertArrayToPWLColor(pRuntime, pRuntime->ToArray(params[0]));
diff --git a/fxjs/cjs_field.cpp b/fxjs/cjs_field.cpp
index fe762ff..806cd31 100644
--- a/fxjs/cjs_field.cpp
+++ b/fxjs/cjs_field.cpp
@@ -24,6 +24,7 @@
 #include "fxjs/cjs_delaydata.h"
 #include "fxjs/cjs_document.h"
 #include "fxjs/cjs_icon.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
 #include "third_party/base/notreached.h"
 
@@ -1027,7 +1028,7 @@
   std::vector<uint32_t> array;
   if (vp->IsNumber()) {
     array.push_back(pRuntime->ToInt32(vp));
-  } else if (!vp.IsEmpty() && vp->IsArray()) {
+  } else if (fxv8::IsArray(vp)) {
     v8::Local<v8::Array> SelArray = pRuntime->ToArray(vp);
     for (size_t i = 0; i < pRuntime->GetArrayLength(SelArray); i++) {
       array.push_back(
@@ -1253,7 +1254,7 @@
   if (!m_bCanSet)
     return CJS_Result::Failure(JSMessage::kReadOnlyError);
 
-  if (vp.IsEmpty() || !vp->IsArray())
+  if (!fxv8::IsArray(vp))
     return CJS_Result::Failure(JSMessage::kBadObjectError);
 
   return CJS_Result::Success();
@@ -1333,7 +1334,7 @@
     return CJS_Result::Failure(JSMessage::kBadObjectError);
   if (!m_bCanSet)
     return CJS_Result::Failure(JSMessage::kReadOnlyError);
-  if (vp.IsEmpty() || !vp->IsArray())
+  if (!fxv8::IsArray(vp))
     return CJS_Result::Failure(JSMessage::kBadObjectError);
   return CJS_Result::Success();
 }
@@ -1705,7 +1706,7 @@
 CJS_Result CJS_Field::set_rect(CJS_Runtime* pRuntime, v8::Local<v8::Value> vp) {
   if (!m_bCanSet)
     return CJS_Result::Failure(JSMessage::kReadOnlyError);
-  if (vp.IsEmpty() || !vp->IsArray())
+  if (!fxv8::IsArray(vp))
     return CJS_Result::Failure(JSMessage::kValueError);
 
   v8::Local<v8::Array> rcArray = pRuntime->ToArray(vp);
@@ -1857,7 +1858,7 @@
                                        v8::Local<v8::Value> vp) {
   if (!m_bCanSet)
     return CJS_Result::Failure(JSMessage::kReadOnlyError);
-  if (vp.IsEmpty() || !vp->IsArray())
+  if (!fxv8::IsArray(vp))
     return CJS_Result::Failure(JSMessage::kBadObjectError);
   return CJS_Result::Success();
 }
@@ -1958,7 +1959,7 @@
                                      v8::Local<v8::Value> vp) {
   if (!m_bCanSet)
     return CJS_Result::Failure(JSMessage::kReadOnlyError);
-  if (vp.IsEmpty() || !vp->IsArray())
+  if (!fxv8::IsArray(vp))
     return CJS_Result::Failure(JSMessage::kBadObjectError);
   return CJS_Result::Success();
 }
@@ -2139,7 +2140,7 @@
     return CJS_Result::Failure(JSMessage::kReadOnlyError);
 
   std::vector<WideString> strArray;
-  if (!vp.IsEmpty() && vp->IsArray()) {
+  if (fxv8::IsArray(vp)) {
     v8::Local<v8::Array> ValueArray = pRuntime->ToArray(vp);
     for (size_t i = 0; i < pRuntime->GetArrayLength(ValueArray); i++) {
       strArray.push_back(
diff --git a/fxjs/cjs_util.cpp b/fxjs/cjs_util.cpp
index f33ac83..9d11c7a 100644
--- a/fxjs/cjs_util.cpp
+++ b/fxjs/cjs_util.cpp
@@ -21,6 +21,7 @@
 #include "fxjs/cjs_publicmethods.h"
 #include "fxjs/cjs_runtime.h"
 #include "fxjs/fx_date_helpers.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/js_define.h"
 #include "fxjs/js_resources.h"
 #include "third_party/base/check_op.h"
@@ -165,7 +166,7 @@
   if (iSize < 2)
     return CJS_Result::Failure(JSMessage::kParamError);
 
-  if (params[1].IsEmpty() || !params[1]->IsDate())
+  if (!fxv8::IsDate(params[1]))
     return CJS_Result::Failure(JSMessage::kSecondParamNotDateError);
 
   v8::Local<v8::Date> v8_date = params[1].As<v8::Date>();
diff --git a/fxjs/fxv8.cpp b/fxjs/fxv8.cpp
index 4d5804c..614a122 100644
--- a/fxjs/fxv8.cpp
+++ b/fxjs/fxv8.cpp
@@ -8,6 +8,46 @@
 
 namespace fxv8 {
 
+bool IsUndefined(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsUndefined();
+}
+
+bool IsNull(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsNull();
+}
+
+bool IsBoolean(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsBoolean();
+}
+
+bool IsString(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsString();
+}
+
+bool IsNumber(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsNumber();
+}
+
+bool IsInteger(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsInt32();
+}
+
+bool IsObject(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsObject();
+}
+
+bool IsArray(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsArray();
+}
+
+bool IsDate(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsDate();
+}
+
+bool IsFunction(v8::Local<v8::Value> value) {
+  return !value.IsEmpty() && value->IsFunction();
+}
+
 v8::Local<v8::Value> NewNullHelper(v8::Isolate* pIsolate) {
   return v8::Null(pIsolate);
 }
@@ -113,7 +153,7 @@
 
 v8::Local<v8::Object> ReentrantToObjectHelper(v8::Isolate* pIsolate,
                                               v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty() || !pValue->IsObject())
+  if (!fxv8::IsObject(pValue))
     return v8::Local<v8::Object>();
 
   v8::TryCatch squash_exceptions(pIsolate);
@@ -123,7 +163,7 @@
 
 v8::Local<v8::Array> ReentrantToArrayHelper(v8::Isolate* pIsolate,
                                             v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty() || !pValue->IsArray())
+  if (!fxv8::IsArray(pValue))
     return v8::Local<v8::Array>();
 
   v8::TryCatch squash_exceptions(pIsolate);
diff --git a/fxjs/fxv8.h b/fxjs/fxv8.h
index f1f35ec..b3c2649 100644
--- a/fxjs/fxv8.h
+++ b/fxjs/fxv8.h
@@ -12,8 +12,22 @@
 #include "core/fxcrt/fx_string.h"
 #include "v8/include/v8.h"
 
+// The fxv8 functions soften up the interface to the V8 API.
+
 namespace fxv8 {
 
+// These first check for empty locals.
+bool IsUndefined(v8::Local<v8::Value> value);
+bool IsNull(v8::Local<v8::Value> value);
+bool IsBoolean(v8::Local<v8::Value> value);
+bool IsString(v8::Local<v8::Value> value);
+bool IsNumber(v8::Local<v8::Value> value);
+bool IsInteger(v8::Local<v8::Value> value);
+bool IsObject(v8::Local<v8::Value> value);
+bool IsArray(v8::Local<v8::Value> value);
+bool IsDate(v8::Local<v8::Value> value);
+bool IsFunction(v8::Local<v8::Value> value);
+
 v8::Local<v8::Value> NewNullHelper(v8::Isolate* pIsolate);
 v8::Local<v8::Value> NewUndefinedHelper(v8::Isolate* pIsolate);
 v8::Local<v8::Number> NewNumberHelper(v8::Isolate* pIsolate, int number);
diff --git a/fxjs/xfa/cfxjse_context.cpp b/fxjs/xfa/cfxjse_context.cpp
index 3ea9a18..ffca7d5 100644
--- a/fxjs/xfa/cfxjse_context.cpp
+++ b/fxjs/xfa/cfxjse_context.cpp
@@ -160,7 +160,7 @@
   if (hObject->InternalFieldCount() != 2 ||
       hObject->GetAlignedPointerFromInternalField(0) == kFXJSEProxyObjectTag) {
     v8::Local<v8::Value> hProtoObject = hObject->GetPrototype();
-    if (hProtoObject.IsEmpty() || !hProtoObject->IsObject())
+    if (!fxv8::IsObject(hProtoObject))
       return nullptr;
 
     hObject = hProtoObject.As<v8::Object>();
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index bd6f912..5833fb7 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -12,6 +12,7 @@
 #include "core/fxcrt/cfx_widetextbuf.h"
 #include "core/fxcrt/fx_extension.h"
 #include "fxjs/cjs_runtime.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/xfa/cfxjse_class.h"
 #include "fxjs/xfa/cfxjse_context.h"
 #include "fxjs/xfa/cfxjse_formcalc_context.h"
@@ -794,7 +795,7 @@
 }
 
 CXFA_Object* CFXJSE_Engine::ToXFAObject(v8::Local<v8::Value> obj) {
-  if (obj.IsEmpty() || !obj->IsObject())
+  if (!fxv8::IsObject(obj))
     return nullptr;
 
   CFXJSE_HostObject* pHostObj =
diff --git a/fxjs/xfa/cfxjse_value.cpp b/fxjs/xfa/cfxjse_value.cpp
index 66ea236..74a3a53 100644
--- a/fxjs/xfa/cfxjse_value.cpp
+++ b/fxjs/xfa/cfxjse_value.cpp
@@ -216,7 +216,7 @@
   v8::Local<v8::Value> rgArgs[2];
   v8::Local<v8::Value> hOldFunction =
       v8::Local<v8::Value>::New(GetIsolate(), lpOldFunction->DirectGetValue());
-  if (hOldFunction.IsEmpty() || !hOldFunction->IsFunction())
+  if (!fxv8::IsFunction(hOldFunction))
     return false;
 
   rgArgs[0] = hOldFunction;
@@ -240,7 +240,7 @@
   v8::Local<v8::Value> hBoundFunction =
       hBinderFunc->Call(hContext, hContext->Global(), 2, rgArgs)
           .ToLocalChecked();
-  if (hBoundFunction.IsEmpty() || !hBoundFunction->IsFunction())
+  if (!fxv8::IsFunction(hBoundFunction))
     return false;
 
   m_hValue.Reset(GetIsolate(), hBoundFunction);
diff --git a/fxjs/xfa/fxjse.cpp b/fxjs/xfa/fxjse.cpp
index 16a1a1b..45e893f 100644
--- a/fxjs/xfa/fxjse.cpp
+++ b/fxjs/xfa/fxjse.cpp
@@ -6,6 +6,7 @@
 
 #include "fxjs/xfa/fxjse.h"
 
+#include "fxjs/fxv8.h"
 #include "fxjs/xfa/cfxjse_context.h"
 
 namespace pdfium {
@@ -19,7 +20,7 @@
 
 // static
 CFXJSE_HostObject* CFXJSE_HostObject::FromV8(v8::Local<v8::Value> arg) {
-  if (arg.IsEmpty() || !arg->IsObject())
+  if (!fxv8::IsObject(arg))
     return nullptr;
 
   return FXJSE_RetrieveObjectBinding(arg.As<v8::Object>());