More small fxjs / v8 cleanup.

- use CFX_V8::ToStringHelper() in more places.
- layer new forms of CFXJSE_Engine::ToObject().

Change-Id: I58cde166dc494d2398d2110cae937aa9f1f5406d
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/67470
Reviewed-by: Tom Sepez <tsepez@chromium.org>
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 ec18cda..972f4f7 100644
--- a/fxjs/cfx_v8.cpp
+++ b/fxjs/cfx_v8.cpp
@@ -177,6 +177,12 @@
 }
 
 // static
+v8::Local<v8::String> CFX_V8::NewStringHelper(v8::Isolate* pIsolate,
+                                              WideStringView str) {
+  return NewStringHelper(pIsolate, FX_UTF8Encode(str).AsStringView());
+}
+
+// static
 int CFX_V8::ReentrantToInt32Helper(v8::Isolate* pIsolate,
                                    v8::Local<v8::Value> pValue) {
   if (pValue.IsEmpty())
diff --git a/fxjs/cfx_v8.h b/fxjs/cfx_v8.h
index cce64e3..2f01d4e 100644
--- a/fxjs/cfx_v8.h
+++ b/fxjs/cfx_v8.h
@@ -17,6 +17,8 @@
  public:
   static v8::Local<v8::String> NewStringHelper(v8::Isolate* pIsolate,
                                                ByteStringView str);
+  static v8::Local<v8::String> NewStringHelper(v8::Isolate* pIsolate,
+                                               WideStringView str);
 
   static int ReentrantToInt32Helper(v8::Isolate* pIsolate,
                                     v8::Local<v8::Value> pValue);
diff --git a/fxjs/cfxjs_engine.cpp b/fxjs/cfxjs_engine.cpp
index c4d46a2..c74f57c 100644
--- a/fxjs/cfxjs_engine.cpp
+++ b/fxjs/cfxjs_engine.cpp
@@ -142,33 +142,27 @@
         m_pIsolate(isolate) {
     v8::Isolate::Scope isolate_scope(isolate);
     v8::HandleScope handle_scope(isolate);
-    v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate);
-    fun->InstanceTemplate()->SetInternalFieldCount(2);
-    fun->SetCallHandler(CallHandler, v8::Number::New(isolate, eObjType));
+    v8::Local<v8::FunctionTemplate> fn = v8::FunctionTemplate::New(isolate);
+    fn->InstanceTemplate()->SetInternalFieldCount(2);
+    fn->SetCallHandler(CallHandler, v8::Number::New(isolate, eObjType));
     if (eObjType == FXJSOBJTYPE_GLOBAL) {
-      fun->InstanceTemplate()->Set(
-          v8::Symbol::GetToStringTag(isolate),
-          v8::String::NewFromUtf8(isolate, "global", v8::NewStringType::kNormal)
-              .ToLocalChecked());
+      fn->InstanceTemplate()->Set(v8::Symbol::GetToStringTag(isolate),
+                                  CFX_V8::NewStringHelper(isolate, "global"));
     }
-    m_FunctionTemplate.Reset(isolate, fun);
-    m_Signature.Reset(isolate, v8::Signature::New(isolate, fun));
+    m_FunctionTemplate.Reset(isolate, fn);
+    m_Signature.Reset(isolate, v8::Signature::New(isolate, fn));
   }
 
   static void CallHandler(const v8::FunctionCallbackInfo<v8::Value>& info) {
     v8::Isolate* isolate = info.GetIsolate();
     if (!info.IsConstructCall()) {
       isolate->ThrowException(
-          v8::String::NewFromUtf8(isolate, "illegal constructor",
-                                  v8::NewStringType::kNormal)
-              .ToLocalChecked());
+          CFX_V8::NewStringHelper(isolate, "illegal constructor"));
       return;
     }
     if (info.Data().As<v8::Int32>()->Value() != FXJSOBJTYPE_DYNAMIC) {
       isolate->ThrowException(
-          v8::String::NewFromUtf8(isolate, "not a dynamic object",
-                                  v8::NewStringType::kNormal)
-              .ToLocalChecked());
+          CFX_V8::NewStringHelper(isolate, "not a dynamic object"));
       return;
     }
     v8::Local<v8::Object> holder = info.Holder();
@@ -239,10 +233,8 @@
   if (!g_DefaultGlobalObjectTemplate) {
     v8::Local<v8::ObjectTemplate> hGlobalTemplate =
         v8::ObjectTemplate::New(pIsolate);
-    hGlobalTemplate->Set(
-        v8::Symbol::GetToStringTag(pIsolate),
-        v8::String::NewFromUtf8(pIsolate, "global", v8::NewStringType::kNormal)
-            .ToLocalChecked());
+    hGlobalTemplate->Set(v8::Symbol::GetToStringTag(pIsolate),
+                         CFX_V8::NewStringHelper(pIsolate, "global"));
     g_DefaultGlobalObjectTemplate =
         new v8::Global<v8::ObjectTemplate>(pIsolate, hGlobalTemplate);
   }
diff --git a/fxjs/cjs_globalconsts.cpp b/fxjs/cjs_globalconsts.cpp
index cb6bd33..bea5d54 100644
--- a/fxjs/cjs_globalconsts.cpp
+++ b/fxjs/cjs_globalconsts.cpp
@@ -6,14 +6,12 @@
 
 #include "fxjs/cjs_globalconsts.h"
 
-#define GLOBAL_STRING(rt, name, value)                                        \
-  (rt)->DefineGlobalConst(                                                    \
-      (name), [](const v8::FunctionCallbackInfo<v8::Value>& info) {           \
-        const char* pStr = (value);                                           \
-        info.GetReturnValue().Set(                                            \
-            v8::String::NewFromUtf8(info.GetIsolate(), pStr,                  \
-                                    v8::NewStringType::kNormal, strlen(pStr)) \
-                .ToLocalChecked());                                           \
+#define GLOBAL_STRING(rt, name, value)                              \
+  (rt)->DefineGlobalConst(                                          \
+      (name), [](const v8::FunctionCallbackInfo<v8::Value>& info) { \
+        const char* pStr = (value);                                 \
+        info.GetReturnValue().Set(                                  \
+            CFX_V8::NewStringHelper(info.GetIsolate(), pStr));      \
       })
 
 // static
diff --git a/fxjs/cjs_runtime.cpp b/fxjs/cjs_runtime.cpp
index 919d47a..efa2ba6 100644
--- a/fxjs/cjs_runtime.cpp
+++ b/fxjs/cjs_runtime.cpp
@@ -181,10 +181,7 @@
   v8::Isolate::Scope isolate_scope(GetIsolate());
   v8::Local<v8::Context> context = GetV8Context();
   v8::Context::Scope context_scope(context);
-  v8::Local<v8::String> str =
-      v8::String::NewFromUtf8(GetIsolate(), utf8Name.unterminated_c_str(),
-                              v8::NewStringType::kNormal, utf8Name.GetLength())
-          .ToLocalChecked();
+  v8::Local<v8::String> str = CFX_V8::NewStringHelper(GetIsolate(), utf8Name);
   v8::MaybeLocal<v8::Value> maybe_propvalue =
       context->Global()->Get(context, str);
   if (maybe_propvalue.IsEmpty())
@@ -203,10 +200,7 @@
   v8::Isolate::Scope isolate_scope(pIsolate);
   v8::Local<v8::Context> context = GetV8Context();
   v8::Context::Scope context_scope(context);
-  v8::Local<v8::String> str =
-      v8::String::NewFromUtf8(pIsolate, utf8Name.unterminated_c_str(),
-                              v8::NewStringType::kNormal, utf8Name.GetLength())
-          .ToLocalChecked();
+  v8::Local<v8::String> str = CFX_V8::NewStringHelper(pIsolate, utf8Name);
   v8::Maybe<bool> result = context->Global()->Set(context, str, pValue);
   return result.IsJust() && result.FromJust();
 }
diff --git a/fxjs/js_define.cpp b/fxjs/js_define.cpp
index 0c0c02c..fbb1e84 100644
--- a/fxjs/js_define.cpp
+++ b/fxjs/js_define.cpp
@@ -30,24 +30,17 @@
   // Use the built-in object method.
   v8::Local<v8::Value> v =
       context->Global()
-          ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
-                                                 v8::NewStringType::kNormal)
-                             .ToLocalChecked())
+          ->Get(context, CFX_V8::NewStringHelper(pIsolate, "Date"))
           .ToLocalChecked();
   if (v->IsObject()) {
     v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
-    v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
-                                                v8::NewStringType::kNormal)
-                            .ToLocalChecked())
+    v = o->Get(context, CFX_V8::NewStringHelper(pIsolate, "parse"))
             .ToLocalChecked();
     if (v->IsFunction()) {
       v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
       const int argc = 1;
-      v8::Local<v8::Value> timeStr =
-          v8::String::NewFromUtf8(pIsolate,
-                                  FX_UTF8Encode(str.AsStringView()).c_str(),
-                                  v8::NewStringType::kNormal)
-              .ToLocalChecked();
+      v8::Local<v8::String> timeStr =
+          CFX_V8::NewStringHelper(pIsolate, str.AsStringView());
       v8::Local<v8::Value> argv[argc] = {timeStr};
       v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
       if (v->IsNumber()) {
diff --git a/fxjs/xfa/cfxjse_class.cpp b/fxjs/xfa/cfxjse_class.cpp
index b4af07b..e4d83b6 100644
--- a/fxjs/xfa/cfxjse_class.cpp
+++ b/fxjs/xfa/cfxjse_class.cpp
@@ -9,6 +9,7 @@
 #include <memory>
 #include <utility>
 
+#include "fxjs/cfx_v8.h"
 #include "fxjs/cjs_result.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_context.h"
@@ -66,10 +67,7 @@
   if (info.This() == info.Holder() && lpClass->name) {
     ByteString szStringVal = ByteString::Format("[object %s]", lpClass->name);
     info.GetReturnValue().Set(
-        v8::String::NewFromUtf8(info.GetIsolate(), szStringVal.c_str(),
-                                v8::NewStringType::kNormal,
-                                szStringVal.GetLength())
-            .ToLocalChecked());
+        CFX_V8::NewStringHelper(info.GetIsolate(), szStringVal.AsStringView()));
     return;
   }
   v8::Local<v8::String> local_str =
@@ -106,9 +104,9 @@
   if (result.HasError()) {
     WideString err = JSFormatErrorString(pClassDescriptor->name, *szPropName,
                                          result.Error());
-    v8::MaybeLocal<v8::String> str = v8::String::NewFromUtf8(
-        info.GetIsolate(), err.ToDefANSI().c_str(), v8::NewStringType::kNormal);
-    info.GetIsolate()->ThrowException(str.ToLocalChecked());
+    v8::Local<v8::String> str =
+        CFX_V8::NewStringHelper(info.GetIsolate(), err.AsStringView());
+    info.GetIsolate()->ThrowException(str);
     return;
   }
 
@@ -142,10 +140,7 @@
       hCallBackInfo->SetAlignedPointerInInternalField(
           0, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClass));
       hCallBackInfo->SetInternalField(
-          1, v8::String::NewFromUtf8(
-                 pIsolate, reinterpret_cast<const char*>(szPropName.raw_str()),
-                 v8::NewStringType::kNormal, szPropName.GetLength())
-                 .ToLocalChecked());
+          1, CFX_V8::NewStringHelper(pIsolate, szPropName));
       pValue->ForceSetValue(
           v8::Function::New(pIsolate->GetCurrentContext(),
                             DynPropGetterAdapter_MethodCallback, hCallBackInfo,
@@ -288,9 +283,7 @@
       v8::External::New(
           pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)));
   hFunctionTemplate->SetClassName(
-      v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name,
-                              v8::NewStringType::kNormal)
-          .ToLocalChecked());
+      CFX_V8::NewStringHelper(pIsolate, lpClassDefinition->name));
   hFunctionTemplate->InstanceTemplate()->SetInternalFieldCount(2);
   v8::Local<v8::ObjectTemplate> hObjectTemplate =
       hFunctionTemplate->InstanceTemplate();
@@ -304,24 +297,19 @@
                                           lpClassDefinition->methods + i)));
       fun->RemovePrototype();
       hObjectTemplate->Set(
-          v8::String::NewFromUtf8(pIsolate, lpClassDefinition->methods[i].name,
-                                  v8::NewStringType::kNormal)
-              .ToLocalChecked(),
+          CFX_V8::NewStringHelper(pIsolate, lpClassDefinition->methods[i].name),
           fun,
           static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
     }
   }
 
   if (bIsJSGlobal) {
-    v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(
+    v8::Local<v8::FunctionTemplate> fn = v8::FunctionTemplate::New(
         pIsolate, Context_GlobalObjToString,
         v8::External::New(
             pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)));
-    fun->RemovePrototype();
-    hObjectTemplate->Set(v8::String::NewFromUtf8(pIsolate, "toString",
-                                                 v8::NewStringType::kNormal)
-                             .ToLocalChecked(),
-                         fun);
+    fn->RemovePrototype();
+    hObjectTemplate->Set(CFX_V8::NewStringHelper(pIsolate, "toString"), fn);
   }
   pClass->m_hTemplate.Reset(lpContext->GetIsolate(), hFunctionTemplate);
   CFXJSE_Class* pResult = pClass.get();
diff --git a/fxjs/xfa/cfxjse_context.cpp b/fxjs/xfa/cfxjse_context.cpp
index 1ff1417..c5eafbe 100644
--- a/fxjs/xfa/cfxjse_context.cpp
+++ b/fxjs/xfa/cfxjse_context.cpp
@@ -68,23 +68,18 @@
   v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
   v8::Local<v8::Value> hException = trycatch->Exception();
   if (hException->IsObject()) {
-    v8::Local<v8::String> hNameStr =
-        v8::String::NewFromUtf8(pIsolate, "name", v8::NewStringType::kNormal)
-            .ToLocalChecked();
+    v8::Local<v8::String> hNameStr = CFX_V8::NewStringHelper(pIsolate, "name");
     v8::Local<v8::Value> hValue =
         hException.As<v8::Object>()->Get(context, hNameStr).ToLocalChecked();
     if (hValue->IsString() || hValue->IsStringObject()) {
       hReturnValue->Set(context, 0, hValue).FromJust();
     } else {
       v8::Local<v8::String> hErrorStr =
-          v8::String::NewFromUtf8(pIsolate, "Error", v8::NewStringType::kNormal)
-              .ToLocalChecked();
+          CFX_V8::NewStringHelper(pIsolate, "Error");
       hReturnValue->Set(context, 0, hErrorStr).FromJust();
     }
-
     v8::Local<v8::String> hMessageStr =
-        v8::String::NewFromUtf8(pIsolate, "message", v8::NewStringType::kNormal)
-            .ToLocalChecked();
+        CFX_V8::NewStringHelper(pIsolate, "message");
     hValue =
         hException.As<v8::Object>()->Get(context, hMessageStr).ToLocalChecked();
     if (hValue->IsString() || hValue->IsStringObject())
@@ -93,8 +88,7 @@
       hReturnValue->Set(context, 1, hMessage->Get()).FromJust();
   } else {
     v8::Local<v8::String> hErrorStr =
-        v8::String::NewFromUtf8(pIsolate, "Error", v8::NewStringType::kNormal)
-            .ToLocalChecked();
+        CFX_V8::NewStringHelper(pIsolate, "Error");
     hReturnValue->Set(context, 0, hErrorStr).FromJust();
     hReturnValue->Set(context, 1, hMessage->Get()).FromJust();
   }
@@ -183,7 +177,6 @@
     CFXJSE_HostObject* pGlobalObject) {
   CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
   auto pContext = pdfium::MakeUnique<CFXJSE_Context>(pIsolate);
-
   v8::Local<v8::ObjectTemplate> hObjectTemplate;
   if (pGlobalClass) {
     CFXJSE_Class* pGlobalClassObj =
@@ -197,14 +190,11 @@
     hObjectTemplate = v8::ObjectTemplate::New(pIsolate);
     hObjectTemplate->SetInternalFieldCount(2);
   }
-  hObjectTemplate->Set(
-      v8::Symbol::GetToStringTag(pIsolate),
-      v8::String::NewFromUtf8(pIsolate, "global", v8::NewStringType::kNormal)
-          .ToLocalChecked());
+  hObjectTemplate->Set(v8::Symbol::GetToStringTag(pIsolate),
+                       CFX_V8::NewStringHelper(pIsolate, "global"));
 
   v8::Local<v8::Context> hNewContext =
       v8::Context::New(pIsolate, nullptr, hObjectTemplate);
-
   v8::Local<v8::Object> pThisProxy = hNewContext->Global();
   FXJSE_UpdateProxyBinding(pThisProxy);
 
@@ -262,9 +252,7 @@
   v8::Local<v8::Context> hContext = GetIsolate()->GetCurrentContext();
   v8::TryCatch trycatch(GetIsolate());
   v8::Local<v8::String> hScriptString =
-      v8::String::NewFromUtf8(GetIsolate(), szScript,
-                              v8::NewStringType::kNormal)
-          .ToLocalChecked();
+      CFX_V8::NewStringHelper(GetIsolate(), szScript);
   if (!lpNewThisObject) {
     v8::Local<v8::Script> hScript;
     if (v8::Script::Compile(hContext, hScriptString).ToLocal(&hScript)) {
@@ -285,11 +273,8 @@
   v8::Local<v8::Value> hNewThis = v8::Local<v8::Value>::New(
       GetIsolate(), lpNewThisObject->DirectGetValue());
   ASSERT(!hNewThis.IsEmpty());
-  v8::Local<v8::String> hEval =
-      v8::String::NewFromUtf8(GetIsolate(),
-                              "(function () { return eval(arguments[0]); })",
-                              v8::NewStringType::kNormal)
-          .ToLocalChecked();
+  v8::Local<v8::String> hEval = CFX_V8::NewStringHelper(
+      GetIsolate(), "(function () { return eval(arguments[0]); })");
   v8::Local<v8::Script> hWrapper =
       v8::Script::Compile(hContext, hEval).ToLocalChecked();
   v8::Local<v8::Value> hWrapperValue;
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index 9be2498..ffcd55d 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -83,17 +83,24 @@
 // static
 CXFA_Object* CFXJSE_Engine::ToObject(
     const v8::FunctionCallbackInfo<v8::Value>& info) {
-  if (!info.Holder()->IsObject())
+  return ToObject(info.Holder());
+}
+
+// static
+CXFA_Object* CFXJSE_Engine::ToObject(v8::Local<v8::Value> value) {
+  if (!value->IsObject())
     return nullptr;
 
-  CFXJSE_HostObject* pHostObj =
-      FXJSE_RetrieveObjectBinding(info.Holder().As<v8::Object>());
-  return pHostObj ? pHostObj->AsCXFAObject() : nullptr;
+  return ToObject(FXJSE_RetrieveObjectBinding(value.As<v8::Object>()));
 }
 
 // static.
 CXFA_Object* CFXJSE_Engine::ToObject(CFXJSE_Value* pValue) {
-  CFXJSE_HostObject* pHostObj = pValue->ToHostObject();
+  return ToObject(pValue->ToHostObject());
+}
+
+// static
+CXFA_Object* CFXJSE_Engine::ToObject(CFXJSE_HostObject* pHostObj) {
   return pHostObj ? pHostObj->AsCXFAObject() : nullptr;
 }
 
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index addf0cc..39abe96 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -22,6 +22,7 @@
 class CFXJSE_Class;
 class CFXJSE_Context;
 class CFXJSE_FormCalcContext;
+class CFXJSE_HostObject;
 class CFXJSE_ResolveProcessor;
 class CJS_Runtime;
 class CXFA_List;
@@ -42,7 +43,9 @@
 class CFXJSE_Engine final : public CFX_V8 {
  public:
   static CXFA_Object* ToObject(const v8::FunctionCallbackInfo<v8::Value>& info);
+  static CXFA_Object* ToObject(v8::Local<v8::Value> value);
   static CXFA_Object* ToObject(CFXJSE_Value* pValue);
+  static CXFA_Object* ToObject(CFXJSE_HostObject* pHostObj);
   static void GlobalPropertyGetter(CFXJSE_Value* pObject,
                                    ByteStringView szPropName,
                                    CFXJSE_Value* pValue);
diff --git a/fxjs/xfa/cfxjse_runtimedata.cpp b/fxjs/xfa/cfxjse_runtimedata.cpp
index 0478e3e..2a7acbf 100644
--- a/fxjs/xfa/cfxjse_runtimedata.cpp
+++ b/fxjs/xfa/cfxjse_runtimedata.cpp
@@ -19,16 +19,13 @@
     v8::Isolate* pIsolate) {
   std::unique_ptr<CFXJSE_RuntimeData> pRuntimeData(new CFXJSE_RuntimeData());
   CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
-
   v8::Local<v8::FunctionTemplate> hFuncTemplate =
       v8::FunctionTemplate::New(pIsolate);
 
   v8::Local<v8::ObjectTemplate> hGlobalTemplate =
       hFuncTemplate->InstanceTemplate();
-  hGlobalTemplate->Set(
-      v8::Symbol::GetToStringTag(pIsolate),
-      v8::String::NewFromUtf8(pIsolate, "global", v8::NewStringType::kNormal)
-          .ToLocalChecked());
+  hGlobalTemplate->Set(v8::Symbol::GetToStringTag(pIsolate),
+                       CFX_V8::NewStringHelper(pIsolate, "global"));
 
   v8::Local<v8::Context> hContext =
       v8::Context::New(pIsolate, 0, hGlobalTemplate);
diff --git a/fxjs/xfa/cfxjse_value.cpp b/fxjs/xfa/cfxjse_value.cpp
index 1be3fc3..40b3d79 100644
--- a/fxjs/xfa/cfxjse_value.cpp
+++ b/fxjs/xfa/cfxjse_value.cpp
@@ -60,10 +60,7 @@
 
   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
   v8::Local<v8::String> hMessage =
-      v8::String::NewFromUtf8(pIsolate, utf8Message.unterminated_c_str(),
-                              v8::NewStringType::kNormal,
-                              utf8Message.GetLength())
-          .ToLocalChecked();
+      CFX_V8::NewStringHelper(pIsolate, utf8Message);
   v8::Local<v8::Value> hError = v8::Exception::Error(hMessage);
   pIsolate->ThrowException(hError);
 }
@@ -141,10 +138,7 @@
     return false;
 
   v8::Local<v8::String> hPropName =
-      v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
-                              v8::NewStringType::kNormal,
-                              szPropName.GetLength())
-          .ToLocalChecked();
+      CFX_V8::NewStringHelper(GetIsolate(), szPropName);
   v8::Local<v8::Value> hPropValue =
       v8::Local<v8::Value>::New(GetIsolate(), lpPropValue->DirectGetValue());
   v8::Maybe<bool> result = hObject.As<v8::Object>()->Set(
@@ -162,10 +156,7 @@
     return false;
 
   v8::Local<v8::String> hPropName =
-      v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
-                              v8::NewStringType::kNormal,
-                              szPropName.GetLength())
-          .ToLocalChecked();
+      CFX_V8::NewStringHelper(GetIsolate(), szPropName);
   v8::Local<v8::Value> hPropValue =
       hObject.As<v8::Object>()
           ->Get(GetIsolate()->GetCurrentContext(), hPropName)
@@ -194,17 +185,11 @@
   CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate());
   v8::Local<v8::Value> hObject =
       v8::Local<v8::Value>::New(GetIsolate(), m_hValue);
-  if (!hObject->IsObject())
-    return false;
-
-  v8::Local<v8::String> hPropName =
-      v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
-                              v8::NewStringType::kNormal,
-                              szPropName.GetLength())
-          .ToLocalChecked();
-  return hObject.As<v8::Object>()
-      ->Delete(GetIsolate()->GetCurrentContext(), hPropName)
-      .FromJust();
+  return hObject->IsObject() &&
+         hObject.As<v8::Object>()
+             ->Delete(GetIsolate()->GetCurrentContext(),
+                      CFX_V8::NewStringHelper(GetIsolate(), szPropName))
+             .FromJust();
 }
 
 bool CFXJSE_Value::HasObjectOwnProperty(ByteStringView szPropName,
@@ -216,10 +201,7 @@
     return false;
 
   v8::Local<v8::String> hKey =
-      v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
-                              v8::NewStringType::kNormal,
-                              szPropName.GetLength())
-          .ToLocalChecked();
+      CFX_V8::NewStringHelper(GetIsolate(), szPropName);
   return hObject.As<v8::Object>()
              ->HasRealNamedProperty(GetIsolate()->GetCurrentContext(), hKey)
              .FromJust() ||
@@ -239,10 +221,7 @@
     return false;
 
   v8::Local<v8::String> hPropName =
-      v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(),
-                              v8::NewStringType::kNormal,
-                              szPropName.GetLength())
-          .ToLocalChecked();
+      CFX_V8::NewStringHelper(GetIsolate(), szPropName);
   v8::Local<v8::Value> pValue =
       v8::Local<v8::Value>::New(GetIsolate(), lpPropValue->m_hValue);
   return hObject.As<v8::Object>()
@@ -270,11 +249,9 @@
 
   rgArgs[1] = hNewThis;
   v8::Local<v8::String> hBinderFuncSource =
-      v8::String::NewFromUtf8(GetIsolate(),
+      CFX_V8::NewStringHelper(GetIsolate(),
                               "(function (oldfunction, newthis) { return "
-                              "oldfunction.bind(newthis); })",
-                              v8::NewStringType::kNormal)
-          .ToLocalChecked();
+                              "oldfunction.bind(newthis); })");
   v8::Local<v8::Context> hContext = GetIsolate()->GetCurrentContext();
   v8::Local<v8::Function> hBinderFunc =
       v8::Script::Compile(hContext, hBinderFuncSource)
@@ -450,9 +427,6 @@
 
 void CFXJSE_Value::SetString(ByteStringView szString) {
   CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate());
-  v8::Local<v8::Value> hValue =
-      v8::String::NewFromUtf8(GetIsolate(), szString.unterminated_c_str(),
-                              v8::NewStringType::kNormal, szString.GetLength())
-          .ToLocalChecked();
+  v8::Local<v8::Value> hValue = CFX_V8::NewStringHelper(GetIsolate(), szString);
   m_hValue.Reset(GetIsolate(), hValue);
 }