Remove type info from CJS_Value, interrogate v8 instead

Review-Url: https://codereview.chromium.org/2154503002
diff --git a/fpdfsdk/javascript/Document.cpp b/fpdfsdk/javascript/Document.cpp
index 258dddb..caaeba8 100644
--- a/fpdfsdk/javascript/Document.cpp
+++ b/fpdfsdk/javascript/Document.cpp
@@ -411,22 +411,20 @@
 
   int nlength = params.size();
   if (nlength == 9) {
-    if (params[8].GetType() == CJS_Value::VT_fxobject) {
+    if (params[8].GetType() == CJS_Value::VT_object) {
       v8::Local<v8::Object> pObj = params[8].ToV8Object();
-      {
-        if (FXJS_GetObjDefnID(pObj) == CJS_PrintParamsObj::g_nObjDefnID) {
-          if (CJS_Object* pJSObj = params[8].ToCJSObject()) {
-            if (PrintParamsObj* pprintparamsObj =
-                    (PrintParamsObj*)pJSObj->GetEmbedObject()) {
-              bUI = pprintparamsObj->bUI;
-              nStart = pprintparamsObj->nStart;
-              nEnd = pprintparamsObj->nEnd;
-              bSilent = pprintparamsObj->bSilent;
-              bShrinkToFit = pprintparamsObj->bShrinkToFit;
-              bPrintAsImage = pprintparamsObj->bPrintAsImage;
-              bReverse = pprintparamsObj->bReverse;
-              bAnnotations = pprintparamsObj->bAnnotations;
-            }
+      if (FXJS_GetObjDefnID(pObj) == CJS_PrintParamsObj::g_nObjDefnID) {
+        if (CJS_Object* pJSObj = params[8].ToCJSObject()) {
+          if (PrintParamsObj* pprintparamsObj =
+                  static_cast<PrintParamsObj*>(pJSObj->GetEmbedObject())) {
+            bUI = pprintparamsObj->bUI;
+            nStart = pprintparamsObj->nStart;
+            nEnd = pprintparamsObj->nEnd;
+            bSilent = pprintparamsObj->bSilent;
+            bShrinkToFit = pprintparamsObj->bShrinkToFit;
+            bPrintAsImage = pprintparamsObj->bPrintAsImage;
+            bReverse = pprintparamsObj->bReverse;
+            bAnnotations = pprintparamsObj->bAnnotations;
           }
         }
       }
@@ -592,18 +590,16 @@
     v8::Local<v8::Object> pObj = params[0].ToV8Object();
     v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"cURL");
     if (!pValue.IsEmpty())
-      strURL =
-          CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
+      strURL = CJS_Value(pRuntime, pValue).ToCFXWideString();
 
     pValue = FXJS_GetObjectElement(isolate, pObj, L"bFDF");
-    bFDF = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();
+    bFDF = CJS_Value(pRuntime, pValue).ToBool();
 
     pValue = FXJS_GetObjectElement(isolate, pObj, L"bEmpty");
-    bEmpty = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToBool();
+    bEmpty = CJS_Value(pRuntime, pValue).ToBool();
 
     pValue = FXJS_GetObjectElement(isolate, pObj, L"aFields");
-    aFields.Attach(
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToV8Array());
+    aFields.Attach(CJS_Value(pRuntime, pValue).ToV8Array());
   }
 
   CPDFSDK_InterForm* pInterForm = m_pDocument->GetInterForm();
@@ -686,25 +682,22 @@
     v8::Local<v8::Object> pObj = params[0].ToV8Object();
 
     v8::Local<v8::Value> pValue = FXJS_GetObjectElement(isolate, pObj, L"bUI");
-    bUI = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToInt();
+    bUI = CJS_Value(pRuntime, pValue).ToInt();
 
     pValue = FXJS_GetObjectElement(isolate, pObj, L"cTo");
-    cTo = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
+    cTo = CJS_Value(pRuntime, pValue).ToCFXWideString();
 
     pValue = FXJS_GetObjectElement(isolate, pObj, L"cCc");
-    cCc = CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
+    cCc = CJS_Value(pRuntime, pValue).ToCFXWideString();
 
     pValue = FXJS_GetObjectElement(isolate, pObj, L"cBcc");
-    cBcc =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
+    cBcc = CJS_Value(pRuntime, pValue).ToCFXWideString();
 
     pValue = FXJS_GetObjectElement(isolate, pObj, L"cSubject");
-    cSubject =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
+    cSubject = CJS_Value(pRuntime, pValue).ToCFXWideString();
 
     pValue = FXJS_GetObjectElement(isolate, pObj, L"cMsg");
-    cMsg =
-        CJS_Value(pRuntime, pValue, GET_VALUE_TYPE(pValue)).ToCFXWideString();
+    cMsg = CJS_Value(pRuntime, pValue).ToCFXWideString();
   }
 
   pRuntime->BeginBlock();
diff --git a/fpdfsdk/javascript/JS_Define.h b/fpdfsdk/javascript/JS_Define.h
index ffef626..6aa1dec 100644
--- a/fpdfsdk/javascript/JS_Define.h
+++ b/fpdfsdk/javascript/JS_Define.h
@@ -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_Value::VT_unknown));
+  CJS_PropValue propValue(CJS_Value(pRuntime, value));
   propValue.StartSetting();
   if (!(pObj->*M)(pContext, propValue, sError)) {
     FXJS_Error(isolate, JSFormatErrorString(class_name_string, prop_name_string,
@@ -149,7 +149,7 @@
   IJS_Context* pContext = pRuntime->GetCurrentContext();
   std::vector<CJS_Value> parameters;
   for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
-    parameters.push_back(CJS_Value(pRuntime, info[i], CJS_Value::VT_unknown));
+    parameters.push_back(CJS_Value(pRuntime, info[i]));
   }
   CJS_Value valueRes(pRuntime);
   CJS_Object* pJSObj = (CJS_Object*)FXJS_GetPrivate(isolate, info.Holder());
@@ -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_Value::VT_unknown));
+  CJS_PropValue PropValue(CJS_Value(pRuntime, value));
   PropValue.StartSetting();
   if (!pObj->DoProperty(pContext, propname.c_str(), PropValue, sError)) {
     FXJS_Error(isolate, JSFormatErrorString(class_name, "PutProperty", sError));
@@ -447,7 +447,7 @@
   IJS_Context* pContext = pRuntime->GetCurrentContext();
   std::vector<CJS_Value> parameters;
   for (unsigned int i = 0; i < (unsigned int)info.Length(); i++) {
-    parameters.push_back(CJS_Value(pRuntime, info[i], CJS_Value::VT_unknown));
+    parameters.push_back(CJS_Value(pRuntime, info[i]));
   }
   CJS_Value valueRes(pRuntime);
   CFX_WideString sError;
@@ -485,6 +485,4 @@
     }                                                                        \
   }
 
-CJS_Value::Type GET_VALUE_TYPE(v8::Local<v8::Value> p);
-
 #endif  // FPDFSDK_JAVASCRIPT_JS_DEFINE_H_
diff --git a/fpdfsdk/javascript/JS_Value.cpp b/fpdfsdk/javascript/JS_Value.cpp
index 6bc45c5..5c1ba2a 100644
--- a/fpdfsdk/javascript/JS_Value.cpp
+++ b/fpdfsdk/javascript/JS_Value.cpp
@@ -22,11 +22,10 @@
   return *(double*)g_nan;
 }
 
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime)
-    : m_eType(VT_unknown), m_pJSRuntime(pRuntime) {}
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
 
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue, Type t)
-    : m_eType(t), m_pValue(pValue), m_pJSRuntime(pRuntime) {}
+CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue)
+    : m_pValue(pValue), m_pJSRuntime(pRuntime) {}
 
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
     : m_pJSRuntime(pRuntime) {
@@ -48,23 +47,11 @@
   operator=(dValue);
 }
 
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Object> pJsObj)
-    : m_pJSRuntime(pRuntime) {
-  operator=(pJsObj);
-}
-
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pJsObj)
     : m_pJSRuntime(pRuntime) {
   operator=(pJsObj);
 }
 
-CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Document* pJsDoc)
-    : m_pJSRuntime(pRuntime) {
-  m_eType = VT_object;
-  if (pJsDoc)
-    m_pValue = pJsDoc->ToV8Object();
-}
-
 CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr)
     : m_pJSRuntime(pRuntime) {
   operator=(pWstr);
@@ -84,19 +71,17 @@
 
 CJS_Value::CJS_Value(const CJS_Value& other) = default;
 
-void CJS_Value::Attach(v8::Local<v8::Value> pValue, Type t) {
+void CJS_Value::Attach(v8::Local<v8::Value> pValue) {
   m_pValue = pValue;
-  m_eType = t;
 }
 
 void CJS_Value::Attach(CJS_Value* pValue) {
   if (pValue)
-    Attach(pValue->ToV8Value(), pValue->GetType());
+    Attach(pValue->ToV8Value());
 }
 
 void CJS_Value::Detach() {
   m_pValue = v8::Local<v8::Value>();
-  m_eType = VT_unknown;
 }
 
 int CJS_Value::ToInt() const {
@@ -146,7 +131,7 @@
 
 void CJS_Value::MaybeCoerceToNumber() {
   bool bAllowNaN = false;
-  if (m_eType == VT_string) {
+  if (GetType() == VT_string) {
     CFX_ByteString bstr = ToCFXByteString();
     if (bstr.GetLength() == 0)
       return;
@@ -162,32 +147,26 @@
   if (std::isnan(num->Value()) && !bAllowNaN)
     return;
   m_pValue = num;
-  m_eType = VT_number;
 }
 
 void CJS_Value::operator=(int iValue) {
   m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), iValue);
-  m_eType = VT_number;
 }
 
 void CJS_Value::operator=(bool bValue) {
   m_pValue = FXJS_NewBoolean(m_pJSRuntime->GetIsolate(), bValue);
-  m_eType = VT_boolean;
 }
 
 void CJS_Value::operator=(double dValue) {
   m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), dValue);
-  m_eType = VT_number;
 }
 
 void CJS_Value::operator=(float fValue) {
   m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), fValue);
-  m_eType = VT_number;
 }
 
 void CJS_Value::operator=(v8::Local<v8::Object> pObj) {
   m_pValue = pObj;
-  m_eType = VT_fxobject;
 }
 
 void CJS_Value::operator=(CJS_Object* pObj) {
@@ -195,21 +174,12 @@
     operator=(pObj->ToV8Object());
 }
 
-void CJS_Value::operator=(CJS_Document* pJsDoc) {
-  m_eType = VT_object;
-  if (pJsDoc) {
-    m_pValue = pJsDoc->ToV8Object();
-  }
-}
-
 void CJS_Value::operator=(const FX_WCHAR* pWstr) {
   m_pValue = FXJS_NewString(m_pJSRuntime->GetIsolate(), (wchar_t*)pWstr);
-  m_eType = VT_string;
 }
 
 void CJS_Value::SetNull() {
   m_pValue = FXJS_NewNull(m_pJSRuntime->GetIsolate());
-  m_eType = VT_null;
 }
 
 void CJS_Value::operator=(const FX_CHAR* pStr) {
@@ -218,36 +188,34 @@
 
 void CJS_Value::operator=(CJS_Array& array) {
   m_pValue = static_cast<v8::Local<v8::Array>>(array);
-  m_eType = VT_object;
 }
 
 void CJS_Value::operator=(CJS_Date& date) {
   m_pValue = FXJS_NewDate(m_pJSRuntime->GetIsolate(), (double)date);
-  m_eType = VT_date;
 }
 
 void CJS_Value::operator=(CJS_Value value) {
   m_pValue = value.ToV8Value();
-  m_eType = value.m_eType;
   m_pJSRuntime = value.m_pJSRuntime;
 }
 
-CJS_Value::Type CJS_Value::GetType() const {
-  if (m_pValue.IsEmpty())
+// static
+CJS_Value::Type CJS_Value::GetValueType(v8::Local<v8::Value> value) {
+  if (value.IsEmpty())
     return VT_unknown;
-  if (m_pValue->IsString())
+  if (value->IsString())
     return VT_string;
-  if (m_pValue->IsNumber())
+  if (value->IsNumber())
     return VT_number;
-  if (m_pValue->IsBoolean())
+  if (value->IsBoolean())
     return VT_boolean;
-  if (m_pValue->IsDate())
+  if (value->IsDate())
     return VT_date;
-  if (m_pValue->IsObject())
+  if (value->IsObject())
     return VT_object;
-  if (m_pValue->IsNull())
+  if (value->IsNull())
     return VT_null;
-  if (m_pValue->IsUndefined())
+  if (value->IsUndefined())
     return VT_undefined;
   return VT_unknown;
 }
@@ -426,7 +394,7 @@
     return;
   v8::Local<v8::Value> p =
       FXJS_GetArrayElement(m_pJSRuntime->GetIsolate(), m_pArray, index);
-  value.Attach(p, CJS_Value::VT_object);
+  value.Attach(p);
 }
 
 void CJS_Array::SetElement(unsigned index, CJS_Value value) {
@@ -898,7 +866,7 @@
     v8::Local<v8::Value> v8Value =
         FXJS_GetObjectElement(pRuntime->GetIsolate(), pObj, property);
     if (!v8Value->IsUndefined())
-      result[i] = CJS_Value(pRuntime, v8Value, CJS_Value::VT_unknown);
+      result[i] = CJS_Value(pRuntime, v8Value);
   }
   va_end(ap);
   return result;
diff --git a/fpdfsdk/javascript/JS_Value.h b/fpdfsdk/javascript/JS_Value.h
index e854450..8e79125 100644
--- a/fpdfsdk/javascript/JS_Value.h
+++ b/fpdfsdk/javascript/JS_Value.h
@@ -27,20 +27,17 @@
     VT_boolean,
     VT_date,
     VT_object,
-    VT_fxobject,
     VT_null,
     VT_undefined
   };
 
   CJS_Value(CJS_Runtime* pRuntime);
-  CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue, Type t);
+  CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue);
   CJS_Value(CJS_Runtime* pRuntime, const int& iValue);
   CJS_Value(CJS_Runtime* pRuntime, const double& dValue);
   CJS_Value(CJS_Runtime* pRuntime, const float& fValue);
   CJS_Value(CJS_Runtime* pRuntime, const bool& bValue);
-  CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Object>);
-  CJS_Value(CJS_Runtime* pRuntime, CJS_Object*);
-  CJS_Value(CJS_Runtime* pRuntime, CJS_Document*);
+  CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pObj);
   CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr);
   CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr);
   CJS_Value(CJS_Runtime* pRuntime, CJS_Array& array);
@@ -49,11 +46,12 @@
   CJS_Value(const CJS_Value& other);
 
   void SetNull();
-  void Attach(v8::Local<v8::Value> pValue, Type t);
+  void Attach(v8::Local<v8::Value> pValue);
   void Attach(CJS_Value* pValue);
   void Detach();
 
-  Type GetType() const;
+  static Type GetValueType(v8::Local<v8::Value> value);
+  Type GetType() const { return GetValueType(m_pValue); }
   int ToInt() const;
   bool ToBool() const;
   double ToDouble() const;
@@ -66,8 +64,7 @@
   v8::Local<v8::Value> ToV8Value() const;
 
   // Replace the current |m_pValue| with a v8::Number if possible
-  // to make one from the current |m_pValue|, updating |m_eType|
-  // as appropriate to indicate the result.
+  // to make one from the current |m_pValue|.
   void MaybeCoerceToNumber();
 
   void operator=(int iValue);
@@ -75,7 +72,6 @@
   void operator=(double val);
   void operator=(float val);
   void operator=(CJS_Object* val);
-  void operator=(CJS_Document* val);
   void operator=(v8::Local<v8::Object> val);
   void operator=(CJS_Array& val);
   void operator=(CJS_Date& val);
@@ -91,7 +87,6 @@
   CJS_Runtime* GetJSRuntime() const { return m_pJSRuntime; }
 
  protected:
-  Type m_eType;
   v8::Local<v8::Value> m_pValue;
   CJS_Runtime* m_pJSRuntime;
 };
diff --git a/fpdfsdk/javascript/app.cpp b/fpdfsdk/javascript/app.cpp
index dd706eb..1077629 100644
--- a/fpdfsdk/javascript/app.cpp
+++ b/fpdfsdk/javascript/app.cpp
@@ -458,7 +458,7 @@
 }
 
 void app::ClearTimerCommon(const CJS_Value& param) {
-  if (param.GetType() != CJS_Value::VT_fxobject)
+  if (param.GetType() != CJS_Value::VT_object)
     return;
 
   v8::Local<v8::Object> pObj = param.ToV8Object();
diff --git a/fpdfsdk/javascript/global.cpp b/fpdfsdk/javascript/global.cpp
index c3fc548..45e2bd0 100644
--- a/fpdfsdk/javascript/global.cpp
+++ b/fpdfsdk/javascript/global.cpp
@@ -17,63 +17,6 @@
 #include "fpdfsdk/javascript/cjs_context.h"
 #include "fpdfsdk/javascript/resource.h"
 
-// Helper class for compile-time calculation of hash values in order to
-// avoid having global object initializers.
-template <unsigned ACC, wchar_t... Ns>
-struct CHash;
-
-// Only needed to hash single-character strings.
-template <wchar_t N>
-struct CHash<N> {
-  static const unsigned value = N;
-};
-
-template <unsigned ACC, wchar_t N>
-struct CHash<ACC, N> {
-  static const unsigned value = (ACC * 1313LLU + N) & 0xFFFFFFFF;
-};
-
-template <unsigned ACC, wchar_t N, wchar_t... Ns>
-struct CHash<ACC, N, Ns...> {
-  static const unsigned value = CHash<CHash<ACC, N>::value, Ns...>::value;
-};
-
-const unsigned int JSCONST_nStringHash =
-    CHash<'s', 't', 'r', 'i', 'n', 'g'>::value;
-const unsigned int JSCONST_nNumberHash =
-    CHash<'n', 'u', 'm', 'b', 'e', 'r'>::value;
-const unsigned int JSCONST_nBoolHash =
-    CHash<'b', 'o', 'o', 'l', 'e', 'a', 'n'>::value;
-const unsigned int JSCONST_nDateHash = CHash<'d', 'a', 't', 'e'>::value;
-const unsigned int JSCONST_nObjectHash =
-    CHash<'o', 'b', 'j', 'e', 'c', 't'>::value;
-const unsigned int JSCONST_nFXobjHash = CHash<'f', 'x', 'o', 'b', 'j'>::value;
-const unsigned int JSCONST_nNullHash = CHash<'n', 'u', 'l', 'l'>::value;
-const unsigned int JSCONST_nUndefHash =
-    CHash<'u', 'n', 'd', 'e', 'f', 'i', 'n', 'e', 'd'>::value;
-
-static unsigned JS_CalcHash(const wchar_t* main) {
-  return (unsigned)FX_HashCode_GetW(CFX_WideStringC(main), false);
-}
-
-#ifndef NDEBUG
-class HashVerify {
- public:
-  HashVerify();
-} g_hashVerify;
-
-HashVerify::HashVerify() {
-  ASSERT(JSCONST_nStringHash == JS_CalcHash(kFXJSValueNameString));
-  ASSERT(JSCONST_nNumberHash == JS_CalcHash(kFXJSValueNameNumber));
-  ASSERT(JSCONST_nBoolHash == JS_CalcHash(kFXJSValueNameBoolean));
-  ASSERT(JSCONST_nDateHash == JS_CalcHash(kFXJSValueNameDate));
-  ASSERT(JSCONST_nObjectHash == JS_CalcHash(kFXJSValueNameObject));
-  ASSERT(JSCONST_nFXobjHash == JS_CalcHash(kFXJSValueNameFxobj));
-  ASSERT(JSCONST_nNullHash == JS_CalcHash(kFXJSValueNameNull));
-  ASSERT(JSCONST_nUndefHash == JS_CalcHash(kFXJSValueNameUndefined));
-}
-#endif
-
 BEGIN_JS_STATIC_CONST(CJS_Global)
 END_JS_STATIC_CONST()
 
@@ -335,9 +278,8 @@
     CFX_WideString ws =
         FXJS_ToString(isolate, FXJS_GetArrayElement(isolate, pKeyList, i));
     CFX_ByteString sKey = ws.UTF8Encode();
-
     v8::Local<v8::Value> v = FXJS_GetObjectElement(isolate, pObj, ws);
-    switch (GET_VALUE_TYPE(v)) {
+    switch (CJS_Value::GetValueType(v)) {
       case CJS_Value::VT_number: {
         CJS_KeyValue* pObjElement = new CJS_KeyValue;
         pObjElement->nType = JS_GLOBALDATA_TYPE_NUMBER;
@@ -353,8 +295,7 @@
         array.Add(pObjElement);
       } break;
       case CJS_Value::VT_string: {
-        CFX_ByteString sValue =
-            CJS_Value(pRuntime, v, CJS_Value::VT_string).ToCFXByteString();
+        CFX_ByteString sValue = CJS_Value(pRuntime, v).ToCFXByteString();
         CJS_KeyValue* pObjElement = new CJS_KeyValue;
         pObjElement->nType = JS_GLOBALDATA_TYPE_STRING;
         pObjElement->sKey = sKey;
@@ -500,26 +441,3 @@
   m_mapGlobal[propname] = pNewData;
   return TRUE;
 }
-
-CJS_Value::Type GET_VALUE_TYPE(v8::Local<v8::Value> p) {
-  const unsigned int nHash = JS_CalcHash(FXJS_GetTypeof(p));
-
-  if (nHash == JSCONST_nUndefHash)
-    return CJS_Value::VT_undefined;
-  if (nHash == JSCONST_nNullHash)
-    return CJS_Value::VT_null;
-  if (nHash == JSCONST_nStringHash)
-    return CJS_Value::VT_string;
-  if (nHash == JSCONST_nNumberHash)
-    return CJS_Value::VT_number;
-  if (nHash == JSCONST_nBoolHash)
-    return CJS_Value::VT_boolean;
-  if (nHash == JSCONST_nDateHash)
-    return CJS_Value::VT_date;
-  if (nHash == JSCONST_nObjectHash)
-    return CJS_Value::VT_object;
-  if (nHash == JSCONST_nFXobjHash)
-    return CJS_Value::VT_fxobject;
-
-  return CJS_Value::VT_unknown;
-}
diff --git a/fxjs/fxjs_v8.cpp b/fxjs/fxjs_v8.cpp
index 8595ac8..6577885 100644
--- a/fxjs/fxjs_v8.cpp
+++ b/fxjs/fxjs_v8.cpp
@@ -10,15 +10,6 @@
 
 #include "core/fxcrt/include/fx_basic.h"
 
-const wchar_t kFXJSValueNameString[] = L"string";
-const wchar_t kFXJSValueNameNumber[] = L"number";
-const wchar_t kFXJSValueNameBoolean[] = L"boolean";
-const wchar_t kFXJSValueNameDate[] = L"date";
-const wchar_t kFXJSValueNameObject[] = L"object";
-const wchar_t kFXJSValueNameFxobj[] = L"fxobj";
-const wchar_t kFXJSValueNameNull[] = L"null";
-const wchar_t kFXJSValueNameUndefined[] = L"undefined";
-
 // Keep this consistent with the values defined in gin/public/context_holder.h
 // (without actually requiring a dependency on gin itself for the standalone
 // embedders of PDFIum). The value we want to use is:
@@ -551,26 +542,6 @@
                                .ToLocalChecked());
 }
 
-const wchar_t* FXJS_GetTypeof(v8::Local<v8::Value> pObj) {
-  if (pObj.IsEmpty())
-    return nullptr;
-  if (pObj->IsString())
-    return kFXJSValueNameString;
-  if (pObj->IsNumber())
-    return kFXJSValueNameNumber;
-  if (pObj->IsBoolean())
-    return kFXJSValueNameBoolean;
-  if (pObj->IsDate())
-    return kFXJSValueNameDate;
-  if (pObj->IsObject())
-    return kFXJSValueNameObject;
-  if (pObj->IsNull())
-    return kFXJSValueNameNull;
-  if (pObj->IsUndefined())
-    return kFXJSValueNameUndefined;
-  return nullptr;
-}
-
 void FXJS_SetPrivate(v8::Isolate* pIsolate,
                      v8::Local<v8::Object> pObj,
                      void* p) {
diff --git a/fxjs/include/fxjs_v8.h b/fxjs/include/fxjs_v8.h
index c8cd65b..f59f510 100644
--- a/fxjs/include/fxjs_v8.h
+++ b/fxjs/include/fxjs_v8.h
@@ -118,15 +118,6 @@
   FXJS_PerIsolateData();
 };
 
-extern const wchar_t kFXJSValueNameString[];
-extern const wchar_t kFXJSValueNameNumber[];
-extern const wchar_t kFXJSValueNameBoolean[];
-extern const wchar_t kFXJSValueNameDate[];
-extern const wchar_t kFXJSValueNameObject[];
-extern const wchar_t kFXJSValueNameFxobj[];
-extern const wchar_t kFXJSValueNameNull[];
-extern const wchar_t kFXJSValueNameUndefined[];
-
 class FXJS_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
   void* Allocate(size_t length) override;
   void* AllocateUninitialized(size_t length) override;
@@ -209,7 +200,6 @@
                                            bool bStatic = false);
 v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate);
 int FXJS_GetObjDefnID(v8::Local<v8::Object> pObj);
-const wchar_t* FXJS_GetTypeof(v8::Local<v8::Value> pObj);
 
 void FXJS_SetPrivate(v8::Isolate* pIsolate,
                      v8::Local<v8::Object> pObj,