Consolidate some V8 type conversion code.

Change-Id: Iec3b9d29125fbb5b8dfd69fb12100962537ed5b0
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/67273
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cfx_v8.cpp b/fxjs/cfx_v8.cpp
index 72bf361..ad5d25e 100644
--- a/fxjs/cfx_v8.cpp
+++ b/fxjs/cfx_v8.cpp
@@ -137,51 +137,23 @@
 }
 
 int CFX_V8::ToInt32(v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return 0;
-  v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
-  v8::MaybeLocal<v8::Int32> maybe_int32 = pValue->ToInt32(context);
-  if (maybe_int32.IsEmpty())
-    return 0;
-  return maybe_int32.ToLocalChecked()->Value();
+  return ReentrantToInt32Helper(m_pIsolate.Get(), pValue);
 }
 
 bool CFX_V8::ToBoolean(v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return false;
-  return pValue->BooleanValue(m_pIsolate.Get());
+  return ReentrantToBooleanHelper(m_pIsolate.Get(), pValue);
 }
 
 double CFX_V8::ToDouble(v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return 0.0;
-  v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
-  v8::MaybeLocal<v8::Number> maybe_number = pValue->ToNumber(context);
-  if (maybe_number.IsEmpty())
-    return 0.0;
-  return maybe_number.ToLocalChecked()->Value();
+  return ReentrantToDoubleHelper(m_pIsolate.Get(), pValue);
 }
 
 WideString CFX_V8::ToWideString(v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return WideString();
-  v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
-  v8::MaybeLocal<v8::String> maybe_string = pValue->ToString(context);
-  if (maybe_string.IsEmpty())
-    return WideString();
-  v8::String::Utf8Value s(GetIsolate(), maybe_string.ToLocalChecked());
-  return WideString::FromUTF8(ByteStringView(*s, s.length()));
+  return ReentrantToWideStringHelper(m_pIsolate.Get(), pValue);
 }
 
 ByteString CFX_V8::ToByteString(v8::Local<v8::Value> pValue) {
-  if (pValue.IsEmpty())
-    return ByteString();
-  v8::Local<v8::Context> context = m_pIsolate->GetCurrentContext();
-  v8::MaybeLocal<v8::String> maybe_string = pValue->ToString(context);
-  if (maybe_string.IsEmpty())
-    return ByteString();
-  v8::String::Utf8Value s(GetIsolate(), maybe_string.ToLocalChecked());
-  return ByteString(*s);
+  return ReentrantToByteStringHelper(m_pIsolate.Get(), pValue);
 }
 
 v8::Local<v8::Object> CFX_V8::ToObject(v8::Local<v8::Value> pValue) {
@@ -198,6 +170,56 @@
   return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
 }
 
+// static
+int CFX_V8::ReentrantToInt32Helper(v8::Isolate* pIsolate,
+                                   v8::Local<v8::Value> pValue) {
+  if (pValue.IsEmpty())
+    return 0;
+  return pValue->Int32Value(pIsolate->GetCurrentContext()).FromMaybe(0);
+}
+
+// static
+bool CFX_V8::ReentrantToBooleanHelper(v8::Isolate* pIsolate,
+                                      v8::Local<v8::Value> pValue) {
+  if (pValue.IsEmpty())
+    return false;
+  return pValue->BooleanValue(pIsolate);
+}
+
+// static
+double CFX_V8::ReentrantToDoubleHelper(v8::Isolate* pIsolate,
+                                       v8::Local<v8::Value> pValue) {
+  if (pValue.IsEmpty())
+    return 0.0;
+  return pValue->NumberValue(pIsolate->GetCurrentContext()).FromMaybe(0.0);
+}
+
+// static
+WideString CFX_V8::ReentrantToWideStringHelper(v8::Isolate* pIsolate,
+                                               v8::Local<v8::Value> pValue) {
+  if (pValue.IsEmpty())
+    return WideString();
+  v8::MaybeLocal<v8::String> maybe_string =
+      pValue->ToString(pIsolate->GetCurrentContext());
+  if (maybe_string.IsEmpty())
+    return WideString();
+  v8::String::Utf8Value s(pIsolate, maybe_string.ToLocalChecked());
+  return WideString::FromUTF8(ByteStringView(*s, s.length()));
+}
+
+// static
+ByteString CFX_V8::ReentrantToByteStringHelper(v8::Isolate* pIsolate,
+                                               v8::Local<v8::Value> pValue) {
+  if (pValue.IsEmpty())
+    return ByteString();
+  v8::MaybeLocal<v8::String> maybe_string =
+      pValue->ToString(pIsolate->GetCurrentContext());
+  if (maybe_string.IsEmpty())
+    return ByteString();
+  v8::String::Utf8Value s(pIsolate, maybe_string.ToLocalChecked());
+  return ByteString(*s);
+}
+
 void* CFX_V8ArrayBufferAllocator::Allocate(size_t length) {
   if (length > kMaxAllowedBytes)
     return nullptr;
diff --git a/fxjs/cfx_v8.h b/fxjs/cfx_v8.h
index cb152ac..d46c368 100644
--- a/fxjs/cfx_v8.h
+++ b/fxjs/cfx_v8.h
@@ -61,6 +61,20 @@
   void DisposeIsolate();
 
  private:
+  friend class CFXJSE_Arguments;
+  friend class CFXJSE_Value;
+
+  static int ReentrantToInt32Helper(v8::Isolate* pIsolate,
+                                    v8::Local<v8::Value> pValue);
+  static bool ReentrantToBooleanHelper(v8::Isolate* pIsolate,
+                                       v8::Local<v8::Value> pValue);
+  static double ReentrantToDoubleHelper(v8::Isolate* pIsolate,
+                                        v8::Local<v8::Value> pValue);
+  static WideString ReentrantToWideStringHelper(v8::Isolate* pIsolate,
+                                                v8::Local<v8::Value> pValue);
+  static ByteString ReentrantToByteStringHelper(v8::Isolate* pIsolate,
+                                                v8::Local<v8::Value> pValue);
+
   UnownedPtr<v8::Isolate> m_pIsolate;
 };
 
diff --git a/fxjs/xfa/cfxjse_arguments.cpp b/fxjs/xfa/cfxjse_arguments.cpp
index 8bfc8e3..f878154 100644
--- a/fxjs/xfa/cfxjse_arguments.cpp
+++ b/fxjs/xfa/cfxjse_arguments.cpp
@@ -6,6 +6,7 @@
 
 #include "fxjs/xfa/cfxjse_arguments.h"
 
+#include "fxjs/cfx_v8.h"
 #include "fxjs/xfa/cfxjse_context.h"
 #include "fxjs/xfa/cfxjse_value.h"
 #include "third_party/base/ptr_util.h"
@@ -28,30 +29,23 @@
 }
 
 bool CFXJSE_Arguments::GetBoolean(int32_t index) const {
-  return (*m_pInfo)[index]->BooleanValue(m_pInfo->GetIsolate());
+  return CFX_V8::ReentrantToBooleanHelper(m_pInfo->GetIsolate(),
+                                          (*m_pInfo)[index]);
 }
 
 int32_t CFXJSE_Arguments::GetInt32(int32_t index) const {
-  return static_cast<int32_t>(
-      (*m_pInfo)[index]
-          ->NumberValue(m_pInfo->GetIsolate()->GetCurrentContext())
-          .FromMaybe(0.0));
+  return CFX_V8::ReentrantToInt32Helper(m_pInfo->GetIsolate(),
+                                        (*m_pInfo)[index]);
 }
 
 float CFXJSE_Arguments::GetFloat(int32_t index) const {
-  return static_cast<float>(
-      (*m_pInfo)[index]
-          ->NumberValue(m_pInfo->GetIsolate()->GetCurrentContext())
-          .FromMaybe(0.0));
+  return static_cast<float>(CFX_V8::ReentrantToDoubleHelper(
+      m_pInfo->GetIsolate(), (*m_pInfo)[index]));
 }
 
 ByteString CFXJSE_Arguments::GetUTF8String(int32_t index) const {
-  v8::Isolate* isolate = m_pInfo->GetIsolate();
-  v8::Local<v8::Value> info = (*m_pInfo)[index];
-  v8::Local<v8::String> hString =
-      info->ToString(isolate->GetCurrentContext()).ToLocalChecked();
-  v8::String::Utf8Value szStringVal(isolate, hString);
-  return ByteString(*szStringVal);
+  return CFX_V8::ReentrantToByteStringHelper(m_pInfo->GetIsolate(),
+                                             (*m_pInfo)[index]);
 }
 
 CFXJSE_Value* CFXJSE_Arguments::GetReturnValue() const {
diff --git a/fxjs/xfa/cfxjse_value.cpp b/fxjs/xfa/cfxjse_value.cpp
index 1d4cec4..41e64c1 100644
--- a/fxjs/xfa/cfxjse_value.cpp
+++ b/fxjs/xfa/cfxjse_value.cpp
@@ -8,6 +8,7 @@
 
 #include <math.h>
 
+#include "fxjs/cfx_v8.h"
 #include "fxjs/xfa/cfxjse_class.h"
 #include "fxjs/xfa/cfxjse_context.h"
 #include "fxjs/xfa/cfxjse_isolatetracker.h"
@@ -388,46 +389,33 @@
 bool CFXJSE_Value::ToBoolean() const {
   ASSERT(!IsEmpty());
   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
-  v8::Local<v8::Value> hValue =
-      v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
-  return hValue->BooleanValue(GetIsolate());
+  return CFX_V8::ReentrantToBooleanHelper(
+      GetIsolate(), v8::Local<v8::Value>::New(GetIsolate(), m_hValue));
 }
 
 float CFXJSE_Value::ToFloat() const {
-  ASSERT(!IsEmpty());
-  CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
-  v8::Local<v8::Value> hValue =
-      v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
-  return static_cast<float>(
-      hValue->NumberValue(GetIsolate()->GetCurrentContext()).FromMaybe(0.0));
+  return static_cast<float>(ToDouble());
 }
 
 double CFXJSE_Value::ToDouble() const {
   ASSERT(!IsEmpty());
   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
-  v8::Local<v8::Value> hValue =
-      v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
-  return hValue->NumberValue(GetIsolate()->GetCurrentContext()).FromMaybe(0.0);
+  return CFX_V8::ReentrantToDoubleHelper(
+      GetIsolate(), v8::Local<v8::Value>::New(GetIsolate(), m_hValue));
 }
 
 int32_t CFXJSE_Value::ToInteger() const {
   ASSERT(!IsEmpty());
   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
-  v8::Local<v8::Value> hValue =
-      v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
-  return static_cast<int32_t>(
-      hValue->NumberValue(GetIsolate()->GetCurrentContext()).FromMaybe(0.0));
+  return CFX_V8::ReentrantToInt32Helper(
+      GetIsolate(), v8::Local<v8::Value>::New(GetIsolate(), m_hValue));
 }
 
 ByteString CFXJSE_Value::ToString() const {
   ASSERT(!IsEmpty());
   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
-  v8::Local<v8::Value> hValue =
-      v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
-  v8::Local<v8::String> hString =
-      hValue->ToString(GetIsolate()->GetCurrentContext()).ToLocalChecked();
-  v8::String::Utf8Value hStringVal(GetIsolate(), hString);
-  return ByteString(*hStringVal);
+  return CFX_V8::ReentrantToByteStringHelper(
+      GetIsolate(), v8::Local<v8::Value>::New(GetIsolate(), m_hValue));
 }
 
 void CFXJSE_Value::SetUndefined() {