Kill majority of remaining CFXJSE_Value usage in fxjs/xfa

Bug: pdfium:1610
Change-Id: Ie61f397d186db28b1508a7913556cb48091a3dc5
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/76570
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
diff --git a/fxjs/xfa/cfxjse_class.cpp b/fxjs/xfa/cfxjse_class.cpp
index d2c1749..693636d 100644
--- a/fxjs/xfa/cfxjse_class.cpp
+++ b/fxjs/xfa/cfxjse_class.cpp
@@ -124,8 +124,10 @@
           ? FXJSE_ClassPropType_Property
           : lpClass->dynPropTypeGetter(pIsolate, pObject, szPropName, false);
   if (nPropType == FXJSE_ClassPropType_Property) {
-    if (lpClass->dynPropGetter)
-      lpClass->dynPropGetter(pIsolate, pObject, szPropName, pValue);
+    if (lpClass->dynPropGetter) {
+      pValue->ForceSetValue(
+          pIsolate, lpClass->dynPropGetter(pIsolate, pObject, szPropName));
+    }
   } else if (nPropType == FXJSE_ClassPropType_Method) {
     if (lpClass->dynMethodCall && pValue) {
       v8::HandleScope hscope(pIsolate);
@@ -160,8 +162,10 @@
           ? FXJSE_ClassPropType_Property
           : lpClass->dynPropTypeGetter(pIsolate, pObject, szPropName, false);
   if (nPropType != FXJSE_ClassPropType_Method) {
-    if (lpClass->dynPropSetter)
-      lpClass->dynPropSetter(pIsolate, pObject, szPropName, pValue);
+    if (lpClass->dynPropSetter) {
+      lpClass->dynPropSetter(pIsolate, pObject, szPropName,
+                             pValue->GetValue(pIsolate));
+    }
   }
 }
 
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index 4f32bba..54edb0d 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -180,7 +180,7 @@
 
 bool CFXJSE_Engine::QueryNodeByFlag(CXFA_Node* refNode,
                                     WideStringView propname,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     uint32_t dwFlag,
                                     bool bSetting) {
   if (!refNode)
@@ -192,9 +192,8 @@
     return false;
 
   if (maybeResult.value().type == ResolveResult::Type::kNodes) {
-    pValue->ForceSetValue(
-        GetIsolate(),
-        GetOrCreateJSBindingFromMap(maybeResult.value().objects.front().Get()));
+    *pValue =
+        GetOrCreateJSBindingFromMap(maybeResult.value().objects.front().Get());
     return true;
   }
   if (maybeResult.value().type == ResolveResult::Type::kAttribute &&
@@ -211,7 +210,7 @@
 void CFXJSE_Engine::GlobalPropertySetter(v8::Isolate* pIsolate,
                                          v8::Local<v8::Object> pObject,
                                          ByteStringView szPropName,
-                                         CFXJSE_Value* pValue) {
+                                         v8::Local<v8::Value> pValue) {
   CXFA_Object* lpOrginalNode = ToObject(pIsolate, pObject);
   CXFA_Document* pDoc = lpOrginalNode->GetDocument();
   CFXJSE_Engine* lpScriptContext = pDoc->GetScriptContext();
@@ -221,14 +220,14 @@
 
   WideString wsPropName = WideString::FromUTF8(szPropName);
   if (lpScriptContext->QueryNodeByFlag(
-          pRefNode, wsPropName.AsStringView(), pValue,
+          pRefNode, wsPropName.AsStringView(), &pValue,
           XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings |
               XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
               XFA_RESOLVENODE_Attributes,
           true)) {
     return;
   }
-  if (lpOrginalNode->IsThisProxy() && pValue && pValue->IsUndefined(pIsolate)) {
+  if (lpOrginalNode->IsThisProxy() && fxv8::IsUndefined(pValue)) {
     fxv8::ReentrantDeleteObjectPropertyHelper(lpScriptContext->GetIsolate(),
                                               pObject, szPropName);
     return;
@@ -242,39 +241,34 @@
   if (!pCJSRuntime)
     return;
 
-  v8::HandleScope handle_scope(lpScriptContext->GetIsolate());
   IJS_Runtime::ScopedEventContext pContext(pCJSRuntime);
-  pCJSRuntime->SetValueByNameInGlobalObject(
-      szPropName, v8::Local<v8::Value>::New(lpScriptContext->GetIsolate(),
-                                            pValue->DirectGetValue()));
+  pCJSRuntime->SetValueByNameInGlobalObject(szPropName, pValue);
 }
 
 // static
-void CFXJSE_Engine::GlobalPropertyGetter(v8::Isolate* pIsolate,
-                                         v8::Local<v8::Object> pObject,
-                                         ByteStringView szPropName,
-                                         CFXJSE_Value* pValue) {
+v8::Local<v8::Value> CFXJSE_Engine::GlobalPropertyGetter(
+    v8::Isolate* pIsolate,
+    v8::Local<v8::Object> pObject,
+    ByteStringView szPropName) {
   CXFA_Object* pOriginalObject = ToObject(pIsolate, pObject);
   CXFA_Document* pDoc = pOriginalObject->GetDocument();
   CFXJSE_Engine* lpScriptContext = pDoc->GetScriptContext();
   WideString wsPropName = WideString::FromUTF8(szPropName);
 
-  pValue->SetUndefined(pIsolate);  // Assume failure.
+  // Assume failure.
+  v8::Local<v8::Value> pValue = fxv8::NewUndefinedHelper(pIsolate);
+
   if (lpScriptContext->GetType() == CXFA_Script::Type::Formcalc) {
-    if (szPropName == kFormCalcRuntime) {
-      lpScriptContext->m_FM2JSContext->GlobalPropertyGetter(pValue);
-      return;
-    }
+    if (szPropName == kFormCalcRuntime)
+      return lpScriptContext->m_FM2JSContext->GlobalPropertyGetter();
+
     XFA_HashCode uHashCode = static_cast<XFA_HashCode>(
         FX_HashCode_GetW(wsPropName.AsStringView(), false));
     if (uHashCode != XFA_HASHCODE_Layout) {
       CXFA_Object* pObj =
           lpScriptContext->GetDocument()->GetXFAObject(uHashCode);
-      if (pObj) {
-        pValue->ForceSetValue(
-            pIsolate, lpScriptContext->GetOrCreateJSBindingFromMap(pObj));
-        return;
-      }
+      if (pObj)
+        return lpScriptContext->GetOrCreateJSBindingFromMap(pObj);
     }
   }
 
@@ -283,44 +277,41 @@
     pRefNode = ToNode(lpScriptContext->GetVariablesThis(pOriginalObject));
   }
   if (lpScriptContext->QueryNodeByFlag(
-          pRefNode, wsPropName.AsStringView(), pValue,
+          pRefNode, wsPropName.AsStringView(), &pValue,
           XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
               XFA_RESOLVENODE_Attributes,
           false)) {
-    return;
+    return pValue;
   }
   if (lpScriptContext->QueryNodeByFlag(
-          pRefNode, wsPropName.AsStringView(), pValue,
+          pRefNode, wsPropName.AsStringView(), &pValue,
           XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings, false)) {
-    return;
+    return pValue;
   }
 
   CXFA_Object* pScriptObject =
       lpScriptContext->GetVariablesScript(pOriginalObject);
-  if (pScriptObject && lpScriptContext->QueryVariableValue(
-                           pScriptObject->AsNode(), szPropName, pValue, true)) {
-    return;
+  if (pScriptObject &&
+      lpScriptContext->QueryVariableValue(pScriptObject->AsNode(), szPropName,
+                                          &pValue, true)) {
+    return pValue;
   }
 
   CXFA_FFNotify* pNotify = pDoc->GetNotify();
   if (!pNotify)
-    return;
+    return pValue;
 
   CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
   auto* pCJSRuntime = static_cast<CJS_Runtime*>(hDoc->GetIJSRuntime());
   if (!pCJSRuntime)
-    return;
+    return pValue;
 
-  v8::HandleScope handle_scope(lpScriptContext->GetIsolate());
-  IJS_Runtime::ScopedEventContext pContext(pCJSRuntime);
   v8::Local<v8::Value> temp_value;
+  IJS_Runtime::ScopedEventContext pContext(pCJSRuntime);
   if (!pCJSRuntime->GetValueByNameFromGlobalObject(szPropName, &temp_value))
-    return;
+    return pValue;
 
-  if (temp_value.IsEmpty())
-    return;
-
-  pValue->ForceSetValue(pIsolate, temp_value);
+  return !temp_value.IsEmpty() ? temp_value : pValue;
 }
 
 // static
@@ -342,89 +333,84 @@
 }
 
 // static
-void CFXJSE_Engine::NormalPropertyGetter(v8::Isolate* pIsolate,
-                                         v8::Local<v8::Object> pHolder,
-                                         ByteStringView szPropName,
-                                         CFXJSE_Value* pReturnValue) {
-  pReturnValue->SetUndefined(pIsolate);  // Assume failure.
+v8::Local<v8::Value> CFXJSE_Engine::NormalPropertyGetter(
+    v8::Isolate* pIsolate,
+    v8::Local<v8::Object> pHolder,
+    ByteStringView szPropName) {
   CXFA_Object* pOriginalObject = ToObject(pIsolate, pHolder);
   if (!pOriginalObject)
-    return;
+    return fxv8::NewUndefinedHelper(pIsolate);
 
-  WideString wsPropName = WideString::FromUTF8(szPropName);
   CFXJSE_Engine* lpScriptContext =
       pOriginalObject->GetDocument()->GetScriptContext();
-  CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOriginalObject);
+
+  WideString wsPropName = WideString::FromUTF8(szPropName);
   if (wsPropName.EqualsASCII("xfa")) {
-    pReturnValue->ForceSetValue(pIsolate,
-                                lpScriptContext->GetOrCreateJSBindingFromMap(
-                                    lpScriptContext->GetDocument()->GetRoot()));
-    return;
+    return lpScriptContext->GetOrCreateJSBindingFromMap(
+        lpScriptContext->GetDocument()->GetRoot());
   }
 
+  v8::Local<v8::Value> pReturnValue = fxv8::NewUndefinedHelper(pIsolate);
+  CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOriginalObject);
   bool bRet = lpScriptContext->QueryNodeByFlag(
-      ToNode(pObject), wsPropName.AsStringView(), pReturnValue,
+      ToNode(pObject), wsPropName.AsStringView(), &pReturnValue,
       XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties |
           XFA_RESOLVENODE_Attributes,
       false);
   if (bRet)
-    return;
+    return pReturnValue;
 
   if (pObject == lpScriptContext->GetThisObject() ||
       (lpScriptContext->GetType() == CXFA_Script::Type::Javascript &&
        !lpScriptContext->IsStrictScopeInJavaScript())) {
     bRet = lpScriptContext->QueryNodeByFlag(
-        ToNode(pObject), wsPropName.AsStringView(), pReturnValue,
+        ToNode(pObject), wsPropName.AsStringView(), &pReturnValue,
         XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings, false);
   }
   if (bRet)
-    return;
+    return pReturnValue;
 
   CXFA_Object* pScriptObject =
       lpScriptContext->GetVariablesScript(pOriginalObject);
   if (!pScriptObject)
-    return;
+    return pReturnValue;
 
   bRet = lpScriptContext->QueryVariableValue(ToNode(pScriptObject), szPropName,
-                                             pReturnValue, true);
+                                             &pReturnValue, true);
   if (bRet)
-    return;
+    return pReturnValue;
 
   Optional<XFA_SCRIPTATTRIBUTEINFO> info = XFA_GetScriptAttributeByName(
       pObject->GetElementType(), wsPropName.AsStringView());
   if (info.has_value()) {
     CJX_Object* jsObject = pObject->JSObject();
-    (*info.value().callback)(pIsolate, jsObject, pReturnValue, false,
+    (*info.value().callback)(pIsolate, jsObject, &pReturnValue, false,
                              info.value().attribute);
-    return;
+    return pReturnValue;
   }
 
   CXFA_FFNotify* pNotify = pObject->GetDocument()->GetNotify();
   if (!pNotify)
-    return;
+    return pReturnValue;
 
   CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
   auto* pCJSRuntime = static_cast<CJS_Runtime*>(hDoc->GetIJSRuntime());
   if (!pCJSRuntime)
-    return;
+    return pReturnValue;
 
-  v8::HandleScope handle_scope(lpScriptContext->GetIsolate());
   IJS_Runtime::ScopedEventContext pContext(pCJSRuntime);
   v8::Local<v8::Value> temp_local;
   if (!pCJSRuntime->GetValueByNameFromGlobalObject(szPropName, &temp_local))
-    return;
+    return pReturnValue;
 
-  if (temp_local.IsEmpty())
-    return;
-
-  pReturnValue->ForceSetValue(lpScriptContext->GetIsolate(), temp_local);
+  return !temp_local.IsEmpty() ? temp_local : pReturnValue;
 }
 
 // static
 void CFXJSE_Engine::NormalPropertySetter(v8::Isolate* pIsolate,
                                          v8::Local<v8::Object> pHolder,
                                          ByteStringView szPropName,
-                                         CFXJSE_Value* pReturnValue) {
+                                         v8::Local<v8::Value> pValue) {
   CXFA_Object* pOriginalObject = ToObject(pIsolate, pHolder);
   if (!pOriginalObject)
     return;
@@ -438,7 +424,7 @@
       XFA_GetScriptAttributeByName(pObject->GetElementType(), wsPropNameView);
   if (info.has_value()) {
     CJX_Object* jsObject = pObject->JSObject();
-    (*info.value().callback)(pIsolate, jsObject, pReturnValue, true,
+    (*info.value().callback)(pIsolate, jsObject, &pValue, true,
                              info.value().attribute);
     return;
   }
@@ -461,8 +447,8 @@
       info = XFA_GetScriptAttributeByName(pPropOrChild->GetElementType(),
                                           L"{default}");
       if (info.has_value()) {
-        pPropOrChild->JSObject()->ScriptSomDefaultValue(
-            pIsolate, pReturnValue, true, XFA_Attribute::Unknown);
+        pPropOrChild->JSObject()->ScriptSomDefaultValue(pIsolate, &pValue, true,
+                                                        XFA_Attribute::Unknown);
         return;
       }
     }
@@ -472,7 +458,7 @@
       lpScriptContext->GetVariablesScript(pOriginalObject);
   if (pScriptObject) {
     lpScriptContext->QueryVariableValue(ToNode(pScriptObject), szPropName,
-                                        pReturnValue, false);
+                                        &pValue, false);
   }
 }
 
@@ -587,7 +573,7 @@
 
 bool CFXJSE_Engine::QueryVariableValue(CXFA_Node* pScriptNode,
                                        ByteStringView szPropName,
-                                       CFXJSE_Value* pValue,
+                                       v8::Local<v8::Value>* pValue,
                                        bool bGetter) {
   if (!pScriptNode || pScriptNode->GetElementType() != XFA_Element::Script)
     return false;
@@ -606,7 +592,7 @@
   v8::Local<v8::Object> pObject = pVariableContext->GetGlobalObject();
   if (!bGetter) {
     fxv8::ReentrantSetObjectOwnPropertyHelper(GetIsolate(), pObject, szPropName,
-                                              pValue->GetValue(GetIsolate()));
+                                              *pValue);
     return true;
   }
 
@@ -618,10 +604,12 @@
   v8::Local<v8::Value> hVariableValue =
       fxv8::ReentrantGetObjectPropertyHelper(GetIsolate(), pObject, szPropName);
   if (fxv8::IsFunction(hVariableValue)) {
-    pValue->SetBoundFunction(GetIsolate(), hVariableValue.As<v8::Function>(),
-                             pObject);
+    v8::Local<v8::Function> maybeFunc = CFXJSE_Value::NewBoundFunction(
+        GetIsolate(), hVariableValue.As<v8::Function>(), pObject);
+    if (!maybeFunc.IsEmpty())
+      *pValue = maybeFunc;
   } else {
-    pValue->ForceSetValue(GetIsolate(), hVariableValue);
+    *pValue = hVariableValue;
   }
   return true;
 }
@@ -733,14 +721,13 @@
           rndFind.m_Result.script_attribute.callback &&
           nStart <
               pdfium::base::checked_cast<int32_t>(wsExpression.GetLength())) {
-        auto pValue = std::make_unique<CFXJSE_Value>();
+        v8::Local<v8::Value> pValue;
         CJX_Object* jsObject = rndFind.m_Result.objects.front()->JSObject();
         (*rndFind.m_Result.script_attribute.callback)(
-            GetIsolate(), jsObject, pValue.get(), false,
+            GetIsolate(), jsObject, &pValue, false,
             rndFind.m_Result.script_attribute.attribute);
-        if (!pValue->IsEmpty()) {
-          rndFind.m_Result.objects.front() =
-              ToObject(GetIsolate(), pValue.get());
+        if (!pValue.IsEmpty()) {
+          rndFind.m_Result.objects.front() = ToObject(GetIsolate(), pValue);
         }
       }
       if (!m_upObjectArray.empty())
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index f6253c8..b60c644 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -73,22 +73,22 @@
                                v8::Local<v8::Value> value);
   static CXFA_Object* ToObject(v8::Isolate* pIsolate, CFXJSE_Value* pValue);
   static CXFA_Object* ToObject(CFXJSE_HostObject* pHostObj);
-  static void GlobalPropertyGetter(v8::Isolate* pIsolate,
-                                   v8::Local<v8::Object> pObject,
-                                   ByteStringView szPropName,
-                                   CFXJSE_Value* pValue);
+  static v8::Local<v8::Value> GlobalPropertyGetter(
+      v8::Isolate* pIsolate,
+      v8::Local<v8::Object> pObject,
+      ByteStringView szPropName);
   static void GlobalPropertySetter(v8::Isolate* pIsolate,
                                    v8::Local<v8::Object> pObject,
                                    ByteStringView szPropName,
-                                   CFXJSE_Value* pValue);
-  static void NormalPropertyGetter(v8::Isolate* pIsolate,
-                                   v8::Local<v8::Object> pObject,
-                                   ByteStringView szPropName,
-                                   CFXJSE_Value* pValue);
+                                   v8::Local<v8::Value> pValue);
+  static v8::Local<v8::Value> NormalPropertyGetter(
+      v8::Isolate* pIsolate,
+      v8::Local<v8::Object> pObject,
+      ByteStringView szPropName);
   static void NormalPropertySetter(v8::Isolate* pIsolate,
                                    v8::Local<v8::Object> pObject,
                                    ByteStringView szPropName,
-                                   CFXJSE_Value* pValue);
+                                   v8::Local<v8::Value> pValue);
   static CJS_Result NormalMethodCall(
       const v8::FunctionCallbackInfo<v8::Value>& info,
       const WideString& functionName);
@@ -148,7 +148,7 @@
   void RemoveBuiltInObjs(CFXJSE_Context* pContext);
   bool QueryNodeByFlag(CXFA_Node* refNode,
                        WideStringView propname,
-                       CFXJSE_Value* pValue,
+                       v8::Local<v8::Value>* pValue,
                        uint32_t dwFlag,
                        bool bSetting);
   bool IsStrictScopeInJavaScript();
@@ -156,7 +156,7 @@
   CXFA_Object* GetVariablesScript(CXFA_Object* pObject);
   bool QueryVariableValue(CXFA_Node* pScriptNode,
                           ByteStringView szPropName,
-                          CFXJSE_Value* pValue,
+                          v8::Local<v8::Value>* pValue,
                           bool bGetter);
   bool RunVariablesScript(CXFA_Node* pScriptNode);
 
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index 258a1a8..dca2a66 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -1328,10 +1328,10 @@
   if (!pNode)
     return fxv8::NewNullHelper(pIsolate);
 
-  auto value = std::make_unique<CFXJSE_Value>();
-  pNode->JSObject()->ScriptSomDefaultValue(pIsolate, value.get(), false,
+  v8::Local<v8::Value> value;
+  pNode->JSObject()->ScriptSomDefaultValue(pIsolate, &value, false,
                                            XFA_Attribute::Unknown);
-  return value->GetValue(pIsolate);
+  return value;
 }
 
 bool SetObjectDefaultValue(v8::Isolate* pIsolate,
@@ -1341,8 +1341,7 @@
   if (!pNode)
     return false;
 
-  auto value = std::make_unique<CFXJSE_Value>(pIsolate, hNewValue);
-  pNode->JSObject()->ScriptSomDefaultValue(pIsolate, value.get(), true,
+  pNode->JSObject()->ScriptSomDefaultValue(pIsolate, &hNewValue, true,
                                            XFA_Attribute::Unknown);
   return true;
 }
@@ -1649,12 +1648,12 @@
   if (resolveNodeRS.script_attribute.callback &&
       resolveNodeRS.script_attribute.eValueType == XFA_ScriptType::Object) {
     for (auto& pObject : resolveNodeRS.objects) {
-      auto pValue = std::make_unique<CFXJSE_Value>();
+      v8::Local<v8::Value> pValue;
       CJX_Object* jsObject = pObject->JSObject();
       (*resolveNodeRS.script_attribute.callback)(
-          pIsolate, jsObject, pValue.get(), false,
+          pIsolate, jsObject, &pValue, false,
           resolveNodeRS.script_attribute.attribute);
-      resultValues.push_back(pValue->GetValue(pIsolate));
+      resultValues.push_back(pValue);
       *bAttribute = false;
     }
   }
@@ -5329,9 +5328,8 @@
   return this;
 }
 
-void CFXJSE_FormCalcContext::GlobalPropertyGetter(CFXJSE_Value* pValue) {
-  pValue->ForceSetValue(GetIsolate(),
-                        v8::Local<v8::Value>::New(m_pIsolate, m_Value));
+v8::Local<v8::Value> CFXJSE_FormCalcContext::GlobalPropertyGetter() {
+  return v8::Local<v8::Value>::New(m_pIsolate, m_Value);
 }
 
 // static
diff --git a/fxjs/xfa/cfxjse_formcalc_context.h b/fxjs/xfa/cfxjse_formcalc_context.h
index 06827d5..0adae0c 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.h
+++ b/fxjs/xfa/cfxjse_formcalc_context.h
@@ -272,7 +272,7 @@
   static Optional<CFX_WideTextBuf> Translate(cppgc::Heap* pHeap,
                                              WideStringView wsFormcalc);
 
-  void GlobalPropertyGetter(CFXJSE_Value* pValue);
+  v8::Local<v8::Value> GlobalPropertyGetter();
   v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); }
   CXFA_Document* GetDocument() const { return m_pDocument.Get(); }
 
diff --git a/fxjs/xfa/cfxjse_value.cpp b/fxjs/xfa/cfxjse_value.cpp
index 54ca810..d6c671d 100644
--- a/fxjs/xfa/cfxjse_value.cpp
+++ b/fxjs/xfa/cfxjse_value.cpp
@@ -193,20 +193,19 @@
       pIsolate, hObject.As<v8::Object>(), szPropName, pValue);
 }
 
-bool CFXJSE_Value::SetBoundFunction(v8::Isolate* pIsolate,
-                                    v8::Local<v8::Function> hOldFunction,
-                                    v8::Local<v8::Object> hNewThis) {
+v8::Local<v8::Function> CFXJSE_Value::NewBoundFunction(
+    v8::Isolate* pIsolate,
+    v8::Local<v8::Function> hOldFunction,
+    v8::Local<v8::Object> hNewThis) {
   ASSERT(!hOldFunction.IsEmpty());
   ASSERT(!hNewThis.IsEmpty());
 
-  CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+  CFXJSE_ScopeUtil_RootContext scope(pIsolate);
   v8::Local<v8::Value> rgArgs[2];
   rgArgs[0] = hOldFunction;
   rgArgs[1] = hNewThis;
-  v8::Local<v8::String> hBinderFuncSource =
-      fxv8::NewStringHelper(pIsolate,
-                            "(function (oldfunction, newthis) { return "
-                            "oldfunction.bind(newthis); })");
+  v8::Local<v8::String> hBinderFuncSource = fxv8::NewStringHelper(
+      pIsolate, "(function (fn, obj) { return fn.bind(obj); })");
   v8::Local<v8::Context> hContext = pIsolate->GetCurrentContext();
   v8::Local<v8::Function> hBinderFunc =
       v8::Script::Compile(hContext, hBinderFuncSource)
@@ -218,10 +217,9 @@
       hBinderFunc->Call(hContext, hContext->Global(), 2, rgArgs)
           .ToLocalChecked();
   if (!fxv8::IsFunction(hBoundFunction))
-    return false;
+    return v8::Local<v8::Function>();
 
-  m_hValue.Reset(pIsolate, hBoundFunction);
-  return true;
+  return hBoundFunction.As<v8::Function>();
 }
 
 v8::Local<v8::Value> CFXJSE_Value::GetValue(v8::Isolate* pIsolate) const {
diff --git a/fxjs/xfa/cfxjse_value.h b/fxjs/xfa/cfxjse_value.h
index 542b384..9bdc591 100644
--- a/fxjs/xfa/cfxjse_value.h
+++ b/fxjs/xfa/cfxjse_value.h
@@ -75,9 +75,12 @@
   bool SetObjectOwnProperty(v8::Isolate* pIsolate,
                             ByteStringView szPropName,
                             CFXJSE_Value* lpPropValue);
-  bool SetBoundFunction(v8::Isolate* pIsolate,
-                        v8::Local<v8::Function> hOldFunction,
-                        v8::Local<v8::Object> lpNewThis);
+
+  // Return empty local on error.
+  static v8::Local<v8::Function> NewBoundFunction(
+      v8::Isolate* pIsolate,
+      v8::Local<v8::Function> hOldFunction,
+      v8::Local<v8::Object> lpNewThis);
 
   v8::Local<v8::Value> GetValue(v8::Isolate* pIsolate) const;
   const v8::Global<v8::Value>& DirectGetValue() const { return m_hValue; }
diff --git a/fxjs/xfa/cjx_boolean.cpp b/fxjs/xfa/cjx_boolean.cpp
index 75797d8..7e77d25 100644
--- a/fxjs/xfa/cjx_boolean.cpp
+++ b/fxjs/xfa/cjx_boolean.cpp
@@ -6,6 +6,7 @@
 
 #include "fxjs/xfa/cjx_boolean.h"
 
+#include "fxjs/fxv8.h"
 #include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fxfa/parser/cxfa_boolean.h"
 
@@ -18,17 +19,18 @@
 }
 
 void CJX_Boolean::defaultValue(v8::Isolate* pIsolate,
-                               CFXJSE_Value* pValue,
+                               v8::Local<v8::Value>* pValue,
                                bool bSetting,
                                XFA_Attribute eAttribute) {
   if (!bSetting) {
-    pValue->SetBoolean(pIsolate, GetContent(true).EqualsASCII("1"));
+    *pValue =
+        fxv8::NewBooleanHelper(pIsolate, GetContent(true).EqualsASCII("1"));
     return;
   }
 
   ByteString newValue;
-  if (pValue && !(pValue->IsNull(pIsolate) || pValue->IsUndefined(pIsolate)))
-    newValue = pValue->ToString(pIsolate);
+  if (pValue && !(fxv8::IsNull(*pValue) || fxv8::IsUndefined(*pValue)))
+    newValue = fxv8::ReentrantToByteStringHelper(pIsolate, *pValue);
 
   int32_t iValue = FXSYS_atoi(newValue.c_str());
   WideString wsNewValue(iValue == 0 ? L"0" : L"1");
@@ -41,7 +43,7 @@
 }
 
 void CJX_Boolean::value(v8::Isolate* pIsolate,
-                        CFXJSE_Value* pValue,
+                        v8::Local<v8::Value>* pValue,
                         bool bSetting,
                         XFA_Attribute eAttribute) {
   defaultValue(pIsolate, pValue, bSetting, eAttribute);
diff --git a/fxjs/xfa/cjx_datawindow.cpp b/fxjs/xfa/cjx_datawindow.cpp
index 7e9ab42..f9eba2a 100644
--- a/fxjs/xfa/cjx_datawindow.cpp
+++ b/fxjs/xfa/cjx_datawindow.cpp
@@ -53,21 +53,21 @@
 }
 
 void CJX_DataWindow::recordsBefore(v8::Isolate* pIsolate,
-                                   CFXJSE_Value* pValue,
+                                   v8::Local<v8::Value>* pValue,
                                    bool bSetting,
                                    XFA_Attribute eAttribute) {}
 
 void CJX_DataWindow::currentRecordNumber(v8::Isolate* pIsolate,
-                                         CFXJSE_Value* pValue,
+                                         v8::Local<v8::Value>* pValue,
                                          bool bSetting,
                                          XFA_Attribute eAttribute) {}
 
 void CJX_DataWindow::recordsAfter(v8::Isolate* pIsolate,
-                                  CFXJSE_Value* pValue,
+                                  v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {}
 
 void CJX_DataWindow::isDefined(v8::Isolate* pIsolate,
-                               CFXJSE_Value* pValue,
+                               v8::Local<v8::Value>* pValue,
                                bool bSetting,
                                XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_delta.cpp b/fxjs/xfa/cjx_delta.cpp
index ede7e71..0acbafa 100644
--- a/fxjs/xfa/cjx_delta.cpp
+++ b/fxjs/xfa/cjx_delta.cpp
@@ -33,16 +33,16 @@
 }
 
 void CJX_Delta::currentValue(v8::Isolate* pIsolate,
-                             CFXJSE_Value* pValue,
+                             v8::Local<v8::Value>* pValue,
                              bool bSetting,
                              XFA_Attribute eAttribute) {}
 
 void CJX_Delta::savedValue(v8::Isolate* pIsolate,
-                           CFXJSE_Value* pValue,
+                           v8::Local<v8::Value>* pValue,
                            bool bSetting,
                            XFA_Attribute eAttribute) {}
 
 void CJX_Delta::target(v8::Isolate* pIsolate,
-                       CFXJSE_Value* pValue,
+                       v8::Local<v8::Value>* pValue,
                        bool bSetting,
                        XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_draw.cpp b/fxjs/xfa/cjx_draw.cpp
index 5705ecc..e8b956b 100644
--- a/fxjs/xfa/cjx_draw.cpp
+++ b/fxjs/xfa/cjx_draw.cpp
@@ -6,6 +6,7 @@
 
 #include "fxjs/xfa/cjx_draw.h"
 
+#include "fxjs/fxv8.h"
 #include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fxfa/parser/cxfa_draw.h"
 
@@ -18,32 +19,32 @@
 }
 
 void CJX_Draw::rawValue(v8::Isolate* pIsolate,
-                        CFXJSE_Value* pValue,
+                        v8::Local<v8::Value>* pValue,
                         bool bSetting,
                         XFA_Attribute eAttribute) {
   defaultValue(pIsolate, pValue, bSetting, eAttribute);
 }
 
 void CJX_Draw::defaultValue(v8::Isolate* pIsolate,
-                            CFXJSE_Value* pValue,
+                            v8::Local<v8::Value>* pValue,
                             bool bSetting,
                             XFA_Attribute eAttribute) {
   if (!bSetting) {
-    WideString content = GetContent(true);
-    if (content.IsEmpty())
-      pValue->SetNull(pIsolate);
-    else
-      pValue->SetString(pIsolate, content.ToUTF8().AsStringView());
+    ByteString content = GetContent(true).ToUTF8();
+    *pValue = content.IsEmpty()
+                  ? fxv8::NewNullHelper(pIsolate).As<v8::Value>()
+                  : fxv8::NewStringHelper(pIsolate, content.AsStringView())
+                        .As<v8::Value>();
     return;
   }
 
-  if (!pValue || !pValue->IsString(pIsolate))
+  if (!pValue || !fxv8::IsString(*pValue))
     return;
 
   ASSERT(GetXFANode()->IsWidgetReady());
   if (GetXFANode()->GetFFWidgetType() != XFA_FFWidgetType::kText)
     return;
 
-  WideString wsNewValue = pValue->ToWideString(pIsolate);
+  WideString wsNewValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
   SetContent(wsNewValue, wsNewValue, true, true, true);
 }
diff --git a/fxjs/xfa/cjx_encrypt.cpp b/fxjs/xfa/cjx_encrypt.cpp
index 8fa8f9f..258c638 100644
--- a/fxjs/xfa/cjx_encrypt.cpp
+++ b/fxjs/xfa/cjx_encrypt.cpp
@@ -17,6 +17,6 @@
 }
 
 void CJX_Encrypt::format(v8::Isolate* pIsolate,
-                         CFXJSE_Value* pValue,
+                         v8::Local<v8::Value>* pValue,
                          bool bSetting,
                          XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_eventpseudomodel.cpp b/fxjs/xfa/cjx_eventpseudomodel.cpp
index 37b01a2..780a4a9 100644
--- a/fxjs/xfa/cjx_eventpseudomodel.cpp
+++ b/fxjs/xfa/cjx_eventpseudomodel.cpp
@@ -9,8 +9,8 @@
 #include <algorithm>
 #include <vector>
 
+#include "fxjs/fxv8.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "third_party/base/notreached.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
@@ -20,36 +20,36 @@
 namespace {
 
 void StringProperty(v8::Isolate* pIsolate,
-                    CFXJSE_Value* pReturn,
+                    v8::Local<v8::Value>* pReturn,
                     WideString* wsValue,
                     bool bSetting) {
   if (bSetting) {
-    *wsValue = pReturn->ToWideString(pIsolate);
+    *wsValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pReturn);
     return;
   }
-  pReturn->SetString(pIsolate, wsValue->ToUTF8().AsStringView());
+  *pReturn = fxv8::NewStringHelper(pIsolate, wsValue->ToUTF8().AsStringView());
 }
 
 void IntegerProperty(v8::Isolate* pIsolate,
-                     CFXJSE_Value* pReturn,
+                     v8::Local<v8::Value>* pReturn,
                      int32_t* iValue,
                      bool bSetting) {
   if (bSetting) {
-    *iValue = pReturn->ToInteger(pIsolate);
+    *iValue = fxv8::ReentrantToInt32Helper(pIsolate, *pReturn);
     return;
   }
-  pReturn->SetInteger(pIsolate, *iValue);
+  *pReturn = fxv8::NewNumberHelper(pIsolate, *iValue);
 }
 
 void BooleanProperty(v8::Isolate* pIsolate,
-                     CFXJSE_Value* pReturn,
+                     v8::Local<v8::Value>* pReturn,
                      bool* bValue,
                      bool bSetting) {
   if (bSetting) {
-    *bValue = pReturn->ToBoolean(pIsolate);
+    *bValue = fxv8::ReentrantToBooleanHelper(pIsolate, *pReturn);
     return;
   }
-  pReturn->SetBoolean(pIsolate, *bValue);
+  *pReturn = fxv8::NewBooleanHelper(pIsolate, *bValue);
 }
 
 }  // namespace
@@ -70,56 +70,56 @@
 }
 
 void CJX_EventPseudoModel::cancelAction(v8::Isolate* pIsolate,
-                                        CFXJSE_Value* pValue,
+                                        v8::Local<v8::Value>* pValue,
                                         bool bSetting,
                                         XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::CancelAction, bSetting);
 }
 
 void CJX_EventPseudoModel::change(v8::Isolate* pIsolate,
-                                  CFXJSE_Value* pValue,
+                                  v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::Change, bSetting);
 }
 
 void CJX_EventPseudoModel::commitKey(v8::Isolate* pIsolate,
-                                     CFXJSE_Value* pValue,
+                                     v8::Local<v8::Value>* pValue,
                                      bool bSetting,
                                      XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::CommitKey, bSetting);
 }
 
 void CJX_EventPseudoModel::fullText(v8::Isolate* pIsolate,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     bool bSetting,
                                     XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::FullText, bSetting);
 }
 
 void CJX_EventPseudoModel::keyDown(v8::Isolate* pIsolate,
-                                   CFXJSE_Value* pValue,
+                                   v8::Local<v8::Value>* pValue,
                                    bool bSetting,
                                    XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::Keydown, bSetting);
 }
 
 void CJX_EventPseudoModel::modifier(v8::Isolate* pIsolate,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     bool bSetting,
                                     XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::Modifier, bSetting);
 }
 
 void CJX_EventPseudoModel::newContentType(v8::Isolate* pIsolate,
-                                          CFXJSE_Value* pValue,
+                                          v8::Local<v8::Value>* pValue,
                                           bool bSetting,
                                           XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::NewContentType, bSetting);
 }
 
 void CJX_EventPseudoModel::newText(v8::Isolate* pIsolate,
-                                   CFXJSE_Value* pValue,
+                                   v8::Local<v8::Value>* pValue,
                                    bool bSetting,
                                    XFA_Attribute eAttribute) {
   if (bSetting)
@@ -130,68 +130,68 @@
   if (!pEventParam)
     return;
 
-  pValue->SetString(pIsolate,
-                    pEventParam->GetNewText().ToUTF8().AsStringView());
+  *pValue = fxv8::NewStringHelper(
+      pIsolate, pEventParam->GetNewText().ToUTF8().AsStringView());
 }
 
 void CJX_EventPseudoModel::prevContentType(v8::Isolate* pIsolate,
-                                           CFXJSE_Value* pValue,
+                                           v8::Local<v8::Value>* pValue,
                                            bool bSetting,
                                            XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::PreviousContentType, bSetting);
 }
 
 void CJX_EventPseudoModel::prevText(v8::Isolate* pIsolate,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     bool bSetting,
                                     XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::PreviousText, bSetting);
 }
 
 void CJX_EventPseudoModel::reenter(v8::Isolate* pIsolate,
-                                   CFXJSE_Value* pValue,
+                                   v8::Local<v8::Value>* pValue,
                                    bool bSetting,
                                    XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::Reenter, bSetting);
 }
 
 void CJX_EventPseudoModel::selEnd(v8::Isolate* pIsolate,
-                                  CFXJSE_Value* pValue,
+                                  v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::SelectionEnd, bSetting);
 }
 
 void CJX_EventPseudoModel::selStart(v8::Isolate* pIsolate,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     bool bSetting,
                                     XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::SelectionStart, bSetting);
 }
 
 void CJX_EventPseudoModel::shift(v8::Isolate* pIsolate,
-                                 CFXJSE_Value* pValue,
+                                 v8::Local<v8::Value>* pValue,
                                  bool bSetting,
                                  XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::Shift, bSetting);
 }
 
 void CJX_EventPseudoModel::soapFaultCode(v8::Isolate* pIsolate,
-                                         CFXJSE_Value* pValue,
+                                         v8::Local<v8::Value>* pValue,
                                          bool bSetting,
                                          XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::SoapFaultCode, bSetting);
 }
 
 void CJX_EventPseudoModel::soapFaultString(v8::Isolate* pIsolate,
-                                           CFXJSE_Value* pValue,
+                                           v8::Local<v8::Value>* pValue,
                                            bool bSetting,
                                            XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::SoapFaultString, bSetting);
 }
 
 void CJX_EventPseudoModel::target(v8::Isolate* pIsolate,
-                                  CFXJSE_Value* pValue,
+                                  v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
   Property(pIsolate, pValue, XFA_Event::Target, bSetting);
@@ -229,7 +229,7 @@
 }
 
 void CJX_EventPseudoModel::Property(v8::Isolate* pIsolate,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     XFA_Event dwFlag,
                                     bool bSetting) {
   // Only the cancelAction, selStart, selEnd and change properties are writable.
diff --git a/fxjs/xfa/cjx_eventpseudomodel.h b/fxjs/xfa/cjx_eventpseudomodel.h
index e4a698b..1f55c44 100644
--- a/fxjs/xfa/cjx_eventpseudomodel.h
+++ b/fxjs/xfa/cjx_eventpseudomodel.h
@@ -72,7 +72,7 @@
   static const CJX_MethodSpec MethodSpecs[];
 
   void Property(v8::Isolate* pIsolate,
-                CFXJSE_Value* pValue,
+                v8::Local<v8::Value>* pValue,
                 XFA_Event dwFlag,
                 bool bSetting);
 };
diff --git a/fxjs/xfa/cjx_exclgroup.cpp b/fxjs/xfa/cjx_exclgroup.cpp
index 77fbd32..e374c3a 100644
--- a/fxjs/xfa/cjx_exclgroup.cpp
+++ b/fxjs/xfa/cjx_exclgroup.cpp
@@ -8,9 +8,9 @@
 
 #include <vector>
 
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/fxfa.h"
@@ -113,7 +113,7 @@
 }
 
 void CJX_ExclGroup::defaultValue(v8::Isolate* pIsolate,
-                                 CFXJSE_Value* pValue,
+                                 v8::Local<v8::Value>* pValue,
                                  bool bSetting,
                                  XFA_Attribute eAttribute) {
   CXFA_Node* node = GetXFANode();
@@ -122,33 +122,34 @@
 
   if (bSetting) {
     node->SetSelectedMemberByValue(
-        pValue->ToWideString(pIsolate).AsStringView(), true, true, true);
+        fxv8::ReentrantToWideStringHelper(pIsolate, *pValue).AsStringView(),
+        true, true, true);
     return;
   }
 
   WideString wsValue = GetContent(true);
   XFA_VERSION curVersion = GetDocument()->GetCurVersionMode();
   if (wsValue.IsEmpty() && curVersion >= XFA_VERSION_300) {
-    pValue->SetNull(pIsolate);
+    *pValue = fxv8::NewNullHelper(pIsolate);
     return;
   }
-  pValue->SetString(pIsolate, wsValue.ToUTF8().AsStringView());
+  *pValue = fxv8::NewStringHelper(pIsolate, wsValue.ToUTF8().AsStringView());
 }
 
 void CJX_ExclGroup::rawValue(v8::Isolate* pIsolate,
-                             CFXJSE_Value* pValue,
+                             v8::Local<v8::Value>* pValue,
                              bool bSetting,
                              XFA_Attribute eAttribute) {
   defaultValue(pIsolate, pValue, bSetting, eAttribute);
 }
 
 void CJX_ExclGroup::transient(v8::Isolate* pIsolate,
-                              CFXJSE_Value* pValue,
+                              v8::Local<v8::Value>* pValue,
                               bool bSetting,
                               XFA_Attribute eAttribute) {}
 
 void CJX_ExclGroup::errorText(v8::Isolate* pIsolate,
-                              CFXJSE_Value* pValue,
+                              v8::Local<v8::Value>* pValue,
                               bool bSetting,
                               XFA_Attribute eAttribute) {
   if (bSetting)
diff --git a/fxjs/xfa/cjx_extras.cpp b/fxjs/xfa/cjx_extras.cpp
index def230c..198fff2 100644
--- a/fxjs/xfa/cjx_extras.cpp
+++ b/fxjs/xfa/cjx_extras.cpp
@@ -17,6 +17,6 @@
 }
 
 void CJX_Extras::type(v8::Isolate* pIsolate,
-                      CFXJSE_Value* pValue,
+                      v8::Local<v8::Value>* pValue,
                       bool bSetting,
                       XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_field.cpp b/fxjs/xfa/cjx_field.cpp
index 60f534e..a521d2e 100644
--- a/fxjs/xfa/cjx_field.cpp
+++ b/fxjs/xfa/cjx_field.cpp
@@ -9,8 +9,8 @@
 #include <vector>
 
 #include "fxjs/cfx_v8.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fgas/crt/cfgas_decimal.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
@@ -243,7 +243,7 @@
 }
 
 void CJX_Field::defaultValue(v8::Isolate* pIsolate,
-                             CFXJSE_Value* pValue,
+                             v8::Local<v8::Value>* pValue,
                              bool bSetting,
                              XFA_Attribute eAttribute) {
   CXFA_Node* xfaNode = GetXFANode();
@@ -253,12 +253,12 @@
   if (bSetting) {
     if (pValue) {
       xfaNode->SetPreNull(xfaNode->IsNull());
-      xfaNode->SetIsNull(pValue->IsNull(pIsolate));
+      xfaNode->SetIsNull(fxv8::IsNull(*pValue));
     }
 
     WideString wsNewText;
-    if (pValue && !(pValue->IsNull(pIsolate) || pValue->IsUndefined(pIsolate)))
-      wsNewText = pValue->ToWideString(pIsolate);
+    if (pValue && !(fxv8::IsNull(*pValue) || fxv8::IsUndefined(*pValue)))
+      wsNewText = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
     if (xfaNode->GetUIChildNode()->GetElementType() == XFA_Element::NumericEdit)
       wsNewText = xfaNode->NumericLimit(wsNewText);
 
@@ -273,7 +273,7 @@
 
   WideString content = GetContent(true);
   if (content.IsEmpty()) {
-    pValue->SetNull(pIsolate);
+    *pValue = fxv8::NewNullHelper(pIsolate);
     return;
   }
 
@@ -283,25 +283,27 @@
     if (xfaNode->GetUIChildNode()->GetElementType() ==
             XFA_Element::NumericEdit &&
         (pNode->JSObject()->GetInteger(XFA_Attribute::FracDigits) == -1)) {
-      pValue->SetString(pIsolate, content.ToUTF8().AsStringView());
+      *pValue =
+          fxv8::NewStringHelper(pIsolate, content.ToUTF8().AsStringView());
     } else {
       CFGAS_Decimal decimal(content.AsStringView());
-      pValue->SetFloat(pIsolate, decimal.ToFloat());
+      *pValue = fxv8::NewNumberHelper(pIsolate, decimal.ToFloat());
     }
   } else if (pNode && pNode->GetElementType() == XFA_Element::Integer) {
-    pValue->SetInteger(pIsolate, FXSYS_wtoi(content.c_str()));
+    *pValue = fxv8::NewNumberHelper(pIsolate, FXSYS_wtoi(content.c_str()));
   } else if (pNode && pNode->GetElementType() == XFA_Element::Boolean) {
-    pValue->SetBoolean(pIsolate, FXSYS_wtoi(content.c_str()) != 0);
+    *pValue =
+        fxv8::NewBooleanHelper(pIsolate, FXSYS_wtoi(content.c_str()) != 0);
   } else if (pNode && pNode->GetElementType() == XFA_Element::Float) {
     CFGAS_Decimal decimal(content.AsStringView());
-    pValue->SetFloat(pIsolate, decimal.ToFloat());
+    *pValue = fxv8::NewNumberHelper(pIsolate, decimal.ToFloat());
   } else {
-    pValue->SetString(pIsolate, content.ToUTF8().AsStringView());
+    *pValue = fxv8::NewStringHelper(pIsolate, content.ToUTF8().AsStringView());
   }
 }
 
 void CJX_Field::editValue(v8::Isolate* pIsolate,
-                          CFXJSE_Value* pValue,
+                          v8::Local<v8::Value>* pValue,
                           bool bSetting,
                           XFA_Attribute eAttribute) {
   CXFA_Node* node = GetXFANode();
@@ -309,22 +311,23 @@
     return;
 
   if (bSetting) {
-    node->SetValue(XFA_VALUEPICTURE_Edit, pValue->ToWideString(pIsolate));
+    node->SetValue(XFA_VALUEPICTURE_Edit,
+                   fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
     return;
   }
-  pValue->SetString(
+  *pValue = fxv8::NewStringHelper(
       pIsolate, node->GetValue(XFA_VALUEPICTURE_Edit).ToUTF8().AsStringView());
 }
 
 void CJX_Field::formatMessage(v8::Isolate* pIsolate,
-                              CFXJSE_Value* pValue,
+                              v8::Local<v8::Value>* pValue,
                               bool bSetting,
                               XFA_Attribute eAttribute) {
   ScriptSomMessage(pIsolate, pValue, bSetting, XFA_SOM_FormatMessage);
 }
 
 void CJX_Field::formattedValue(v8::Isolate* pIsolate,
-                               CFXJSE_Value* pValue,
+                               v8::Local<v8::Value>* pValue,
                                bool bSetting,
                                XFA_Attribute eAttribute) {
   CXFA_Node* node = GetXFANode();
@@ -332,16 +335,17 @@
     return;
 
   if (bSetting) {
-    node->SetValue(XFA_VALUEPICTURE_Display, pValue->ToWideString(pIsolate));
+    node->SetValue(XFA_VALUEPICTURE_Display,
+                   fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
     return;
   }
-  pValue->SetString(
+  *pValue = fxv8::NewStringHelper(
       pIsolate,
       node->GetValue(XFA_VALUEPICTURE_Display).ToUTF8().AsStringView());
 }
 
 void CJX_Field::length(v8::Isolate* pIsolate,
-                       CFXJSE_Value* pValue,
+                       v8::Local<v8::Value>* pValue,
                        bool bSetting,
                        XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -350,26 +354,23 @@
   }
 
   CXFA_Node* node = GetXFANode();
-  if (!node->IsWidgetReady()) {
-    pValue->SetInteger(pIsolate, 0);
-    return;
-  }
-  pValue->SetInteger(pIsolate, node->CountChoiceListItems(true));
+  *pValue = fxv8::NewNumberHelper(
+      pIsolate, node->IsWidgetReady() ? node->CountChoiceListItems(true) : 0);
 }
 
 void CJX_Field::parentSubform(v8::Isolate* pIsolate,
-                              CFXJSE_Value* pValue,
+                              v8::Local<v8::Value>* pValue,
                               bool bSetting,
                               XFA_Attribute eAttribute) {
   if (bSetting) {
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->SetNull(pIsolate);
+  *pValue = fxv8::NewNullHelper(pIsolate);
 }
 
 void CJX_Field::selectedIndex(v8::Isolate* pIsolate,
-                              CFXJSE_Value* pValue,
+                              v8::Local<v8::Value>* pValue,
                               bool bSetting,
                               XFA_Attribute eAttribute) {
   CXFA_Node* node = GetXFANode();
@@ -377,11 +378,11 @@
     return;
 
   if (!bSetting) {
-    pValue->SetInteger(pIsolate, node->GetSelectedItem(0));
+    *pValue = fxv8::NewNumberHelper(pIsolate, node->GetSelectedItem(0));
     return;
   }
 
-  int32_t iIndex = pValue->ToInteger(pIsolate);
+  int32_t iIndex = fxv8::ReentrantToInt32Helper(pIsolate, *pValue);
   if (iIndex == -1) {
     node->ClearAllSelections();
     return;
@@ -391,7 +392,7 @@
 }
 
 void CJX_Field::rawValue(v8::Isolate* pIsolate,
-                         CFXJSE_Value* pValue,
+                         v8::Local<v8::Value>* pValue,
                          bool bSetting,
                          XFA_Attribute eAttribute) {
   defaultValue(pIsolate, pValue, bSetting, eAttribute);
diff --git a/fxjs/xfa/cjx_form.cpp b/fxjs/xfa/cjx_form.cpp
index 20f9542..4f33149 100644
--- a/fxjs/xfa/cjx_form.cpp
+++ b/fxjs/xfa/cjx_form.cpp
@@ -8,9 +8,9 @@
 
 #include <vector>
 
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "v8/include/cppgc/allocation.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
@@ -130,16 +130,18 @@
 }
 
 void CJX_Form::checksumS(v8::Isolate* pIsolate,
-                         CFXJSE_Value* pValue,
+                         v8::Local<v8::Value>* pValue,
                          bool bSetting,
                          XFA_Attribute eAttribute) {
   if (bSetting) {
-    SetAttributeByEnum(XFA_Attribute::Checksum, pValue->ToWideString(pIsolate),
+    SetAttributeByEnum(XFA_Attribute::Checksum,
+                       fxv8::ReentrantToWideStringHelper(pIsolate, *pValue),
                        false);
     return;
   }
 
   Optional<WideString> checksum = TryAttribute(XFA_Attribute::Checksum, false);
-  pValue->SetString(pIsolate,
-                    checksum ? checksum->ToUTF8().AsStringView() : "");
+  *pValue = fxv8::NewStringHelper(
+      pIsolate,
+      checksum.has_value() ? checksum.value().ToUTF8().AsStringView() : "");
 }
diff --git a/fxjs/xfa/cjx_handler.cpp b/fxjs/xfa/cjx_handler.cpp
index 5cdf5b5..cacbe0b 100644
--- a/fxjs/xfa/cjx_handler.cpp
+++ b/fxjs/xfa/cjx_handler.cpp
@@ -17,6 +17,6 @@
 }
 
 void CJX_Handler::version(v8::Isolate* pIsolate,
-                          CFXJSE_Value* pValue,
+                          v8::Local<v8::Value>* pValue,
                           bool bSetting,
                           XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_hostpseudomodel.cpp b/fxjs/xfa/cjx_hostpseudomodel.cpp
index bb52e67..d284839 100644
--- a/fxjs/xfa/cjx_hostpseudomodel.cpp
+++ b/fxjs/xfa/cjx_hostpseudomodel.cpp
@@ -9,9 +9,9 @@
 #include <memory>
 #include <vector>
 
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/parser/cscript_hostpseudomodel.h"
@@ -76,7 +76,7 @@
 }
 
 void CJX_HostPseudoModel::appType(v8::Isolate* pIsolate,
-                                  CFXJSE_Value* pValue,
+                                  v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -87,11 +87,11 @@
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->SetString(pIsolate, "Exchange");
+  *pValue = fxv8::NewStringHelper(pIsolate, "Exchange");
 }
 
 void CJX_HostPseudoModel::calculationsEnabled(v8::Isolate* pIsolate,
-                                              CFXJSE_Value* pValue,
+                                              v8::Local<v8::Value>* pValue,
                                               bool bSetting,
                                               XFA_Attribute eAttribute) {
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -100,14 +100,15 @@
 
   CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
   if (bSetting) {
-    hDoc->SetCalculationsEnabled(pValue->ToBoolean(pIsolate));
+    hDoc->SetCalculationsEnabled(
+        fxv8::ReentrantToBooleanHelper(pIsolate, *pValue));
     return;
   }
-  pValue->SetBoolean(pIsolate, hDoc->IsCalculationsEnabled());
+  *pValue = fxv8::NewBooleanHelper(pIsolate, hDoc->IsCalculationsEnabled());
 }
 
 void CJX_HostPseudoModel::currentPage(v8::Isolate* pIsolate,
-                                      CFXJSE_Value* pValue,
+                                      v8::Local<v8::Value>* pValue,
                                       bool bSetting,
                                       XFA_Attribute eAttribute) {
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -116,14 +117,14 @@
 
   CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
   if (bSetting) {
-    hDoc->SetCurrentPage(pValue->ToInteger(pIsolate));
+    hDoc->SetCurrentPage(fxv8::ReentrantToInt32Helper(pIsolate, *pValue));
     return;
   }
-  pValue->SetInteger(pIsolate, hDoc->GetCurrentPage());
+  *pValue = fxv8::NewNumberHelper(pIsolate, hDoc->GetCurrentPage());
 }
 
 void CJX_HostPseudoModel::language(v8::Isolate* pIsolate,
-                                   CFXJSE_Value* pValue,
+                                   v8::Local<v8::Value>* pValue,
                                    bool bSetting,
                                    XFA_Attribute eAttribute) {
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -134,13 +135,12 @@
     ThrowException(WideString::FromASCII("Unable to set language value."));
     return;
   }
-  pValue->SetString(
-      pIsolate,
-      pNotify->GetAppProvider()->GetLanguage().ToUTF8().AsStringView());
+  ByteString lang = pNotify->GetAppProvider()->GetLanguage().ToUTF8();
+  *pValue = fxv8::NewStringHelper(pIsolate, lang.AsStringView());
 }
 
 void CJX_HostPseudoModel::numPages(v8::Isolate* pIsolate,
-                                   CFXJSE_Value* pValue,
+                                   v8::Local<v8::Value>* pValue,
                                    bool bSetting,
                                    XFA_Attribute eAttribute) {
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -152,11 +152,11 @@
     ThrowException(WideString::FromASCII("Unable to set numPages value."));
     return;
   }
-  pValue->SetInteger(pIsolate, hDoc->CountPages());
+  *pValue = fxv8::NewNumberHelper(pIsolate, hDoc->CountPages());
 }
 
 void CJX_HostPseudoModel::platform(v8::Isolate* pIsolate,
-                                   CFXJSE_Value* pValue,
+                                   v8::Local<v8::Value>* pValue,
                                    bool bSetting,
                                    XFA_Attribute eAttribute) {
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -167,13 +167,12 @@
     ThrowException(WideString::FromASCII("Unable to set platform value."));
     return;
   }
-  pValue->SetString(
-      pIsolate,
-      pNotify->GetAppProvider()->GetPlatform().ToUTF8().AsStringView());
+  ByteString plat = pNotify->GetAppProvider()->GetPlatform().ToUTF8();
+  *pValue = fxv8::NewStringHelper(pIsolate, plat.AsStringView());
 }
 
 void CJX_HostPseudoModel::title(v8::Isolate* pIsolate,
-                                CFXJSE_Value* pValue,
+                                v8::Local<v8::Value>* pValue,
                                 bool bSetting,
                                 XFA_Attribute eAttribute) {
   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
@@ -185,16 +184,16 @@
 
   CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
   if (bSetting) {
-    hDoc->SetTitle(pValue->ToWideString(pIsolate));
+    hDoc->SetTitle(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
     return;
   }
 
-  WideString wsTitle = hDoc->GetTitle();
-  pValue->SetString(pIsolate, wsTitle.ToUTF8().AsStringView());
+  ByteString bsTitle = hDoc->GetTitle().ToUTF8();
+  *pValue = fxv8::NewStringHelper(pIsolate, bsTitle.AsStringView());
 }
 
 void CJX_HostPseudoModel::validationsEnabled(v8::Isolate* pIsolate,
-                                             CFXJSE_Value* pValue,
+                                             v8::Local<v8::Value>* pValue,
                                              bool bSetting,
                                              XFA_Attribute eAttribute) {
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -203,16 +202,16 @@
 
   CXFA_FFDoc* hDoc = pNotify->GetFFDoc();
   if (bSetting) {
-    hDoc->SetValidationsEnabled(pValue->ToBoolean(pIsolate));
+    hDoc->SetValidationsEnabled(
+        fxv8::ReentrantToBooleanHelper(pIsolate, *pValue));
     return;
   }
 
-  bool bEnabled = hDoc->IsValidationsEnabled();
-  pValue->SetBoolean(pIsolate, bEnabled);
+  *pValue = fxv8::NewBooleanHelper(pIsolate, hDoc->IsValidationsEnabled());
 }
 
 void CJX_HostPseudoModel::variation(v8::Isolate* pIsolate,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     bool bSetting,
                                     XFA_Attribute eAttribute) {
   if (!GetDocument()->GetScriptContext()->IsRunAtClient())
@@ -222,22 +221,22 @@
     ThrowException(WideString::FromASCII("Unable to set variation value."));
     return;
   }
-  pValue->SetString(pIsolate, "Full");
+  *pValue = fxv8::NewStringHelper(pIsolate, "Full");
 }
 
 void CJX_HostPseudoModel::version(v8::Isolate* pIsolate,
-                                  CFXJSE_Value* pValue,
+                                  v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
   if (bSetting) {
     ThrowException(WideString::FromASCII("Unable to set version value."));
     return;
   }
-  pValue->SetString(pIsolate, "11");
+  *pValue = fxv8::NewStringHelper(pIsolate, "11");
 }
 
 void CJX_HostPseudoModel::name(v8::Isolate* pIsolate,
-                               CFXJSE_Value* pValue,
+                               v8::Local<v8::Value>* pValue,
                                bool bSetting,
                                XFA_Attribute eAttribute) {
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -248,9 +247,8 @@
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->SetString(
-      pIsolate,
-      pNotify->GetAppProvider()->GetAppName().ToUTF8().AsStringView());
+  ByteString bsName = pNotify->GetAppProvider()->GetAppName().ToUTF8();
+  *pValue = fxv8::NewStringHelper(pIsolate, bsName.AsStringView());
 }
 
 CJS_Result CJX_HostPseudoModel::gotoURL(
diff --git a/fxjs/xfa/cjx_instancemanager.cpp b/fxjs/xfa/cjx_instancemanager.cpp
index 0188cbf..c724bf4 100644
--- a/fxjs/xfa/cjx_instancemanager.cpp
+++ b/fxjs/xfa/cjx_instancemanager.cpp
@@ -9,9 +9,9 @@
 #include <algorithm>
 #include <vector>
 
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "third_party/base/notreached.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
@@ -297,7 +297,7 @@
 }
 
 void CJX_InstanceManager::max(v8::Isolate* pIsolate,
-                              CFXJSE_Value* pValue,
+                              v8::Local<v8::Value>* pValue,
                               bool bSetting,
                               XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -305,12 +305,12 @@
     return;
   }
   CXFA_Occur* occur = GetXFANode()->GetOccurIfExists();
-  pValue->SetInteger(pIsolate,
-                     occur ? occur->GetMax() : CXFA_Occur::kDefaultMax);
+  *pValue = fxv8::NewNumberHelper(
+      pIsolate, occur ? occur->GetMax() : CXFA_Occur::kDefaultMax);
 }
 
 void CJX_InstanceManager::min(v8::Isolate* pIsolate,
-                              CFXJSE_Value* pValue,
+                              v8::Local<v8::Value>* pValue,
                               bool bSetting,
                               XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -318,17 +318,17 @@
     return;
   }
   CXFA_Occur* occur = GetXFANode()->GetOccurIfExists();
-  pValue->SetInteger(pIsolate,
-                     occur ? occur->GetMin() : CXFA_Occur::kDefaultMin);
+  *pValue = fxv8::NewNumberHelper(
+      pIsolate, occur ? occur->GetMin() : CXFA_Occur::kDefaultMin);
 }
 
 void CJX_InstanceManager::count(v8::Isolate* pIsolate,
-                                CFXJSE_Value* pValue,
+                                v8::Local<v8::Value>* pValue,
                                 bool bSetting,
                                 XFA_Attribute eAttribute) {
   if (bSetting) {
-    SetInstances(pValue->ToInteger(pIsolate));
+    SetInstances(fxv8::ReentrantToInt32Helper(pIsolate, *pValue));
     return;
   }
-  pValue->SetInteger(pIsolate, GetXFANode()->GetCount());
+  *pValue = fxv8::NewNumberHelper(pIsolate, GetXFANode()->GetCount());
 }
diff --git a/fxjs/xfa/cjx_layoutpseudomodel.cpp b/fxjs/xfa/cjx_layoutpseudomodel.cpp
index 89222fc..98276b4 100644
--- a/fxjs/xfa/cjx_layoutpseudomodel.cpp
+++ b/fxjs/xfa/cjx_layoutpseudomodel.cpp
@@ -10,10 +10,10 @@
 #include <utility>
 
 #include "core/fxcrt/fx_coordinates.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_class.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "third_party/base/stl_util.h"
 #include "v8/include/cppgc/allocation.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
@@ -63,7 +63,7 @@
 }
 
 void CJX_LayoutPseudoModel::ready(v8::Isolate* pIsolate,
-                                  CFXJSE_Value* pValue,
+                                  v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
   CXFA_FFNotify* pNotify = GetDocument()->GetNotify();
@@ -75,7 +75,7 @@
   }
 
   int32_t iStatus = pNotify->GetLayoutStatus();
-  pValue->SetBoolean(pIsolate, iStatus >= 2);
+  *pValue = fxv8::NewBooleanHelper(pIsolate, iStatus >= 2);
 }
 
 CJS_Result CJX_LayoutPseudoModel::HWXY(
diff --git a/fxjs/xfa/cjx_list.cpp b/fxjs/xfa/cjx_list.cpp
index bd66cb6..8e9d15c 100644
--- a/fxjs/xfa/cjx_list.cpp
+++ b/fxjs/xfa/cjx_list.cpp
@@ -8,10 +8,10 @@
 
 #include <vector>
 
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_class.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "third_party/base/numerics/safe_conversions.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 #include "xfa/fxfa/parser/cxfa_list.h"
@@ -98,13 +98,13 @@
 }
 
 void CJX_List::length(v8::Isolate* pIsolate,
-                      CFXJSE_Value* pValue,
+                      v8::Local<v8::Value>* pValue,
                       bool bSetting,
                       XFA_Attribute eAttribute) {
   if (bSetting) {
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->SetInteger(
+  *pValue = fxv8::NewNumberHelper(
       pIsolate, pdfium::base::checked_cast<int32_t>(GetXFAList()->GetLength()));
 }
diff --git a/fxjs/xfa/cjx_model.cpp b/fxjs/xfa/cjx_model.cpp
index 677a4da..421a70b 100644
--- a/fxjs/xfa/cjx_model.cpp
+++ b/fxjs/xfa/cjx_model.cpp
@@ -86,11 +86,11 @@
 }
 
 void CJX_Model::context(v8::Isolate* pIsolate,
-                        CFXJSE_Value* pValue,
+                        v8::Local<v8::Value>* pValue,
                         bool bSetting,
                         XFA_Attribute eAttribute) {}
 
 void CJX_Model::aliasNode(v8::Isolate* pIsolate,
-                          CFXJSE_Value* pValue,
+                          v8::Local<v8::Value>* pValue,
                           bool bSetting,
                           XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_node.cpp b/fxjs/xfa/cjx_node.cpp
index ede3457..f1a737d 100644
--- a/fxjs/xfa/cjx_node.cpp
+++ b/fxjs/xfa/cjx_node.cpp
@@ -16,9 +16,9 @@
 #include "core/fxcrt/xml/cfx_xmldocument.h"
 #include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "core/fxcrt/xml/cfx_xmlparser.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
@@ -401,43 +401,42 @@
 }
 
 void CJX_Node::ns(v8::Isolate* pIsolate,
-                  CFXJSE_Value* pValue,
+                  v8::Local<v8::Value>* pValue,
                   bool bSetting,
                   XFA_Attribute eAttribute) {
   if (bSetting) {
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->SetString(
+  *pValue = fxv8::NewStringHelper(
       pIsolate, TryNamespace().value_or(WideString()).ToUTF8().AsStringView());
 }
 
 void CJX_Node::model(v8::Isolate* pIsolate,
-                     CFXJSE_Value* pValue,
+                     v8::Local<v8::Value>* pValue,
                      bool bSetting,
                      XFA_Attribute eAttribute) {
   if (bSetting) {
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->ForceSetValue(
-      pIsolate, GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-                    GetXFANode()->GetModelNode()));
+  *pValue = GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+      GetXFANode()->GetModelNode());
 }
 
 void CJX_Node::isContainer(v8::Isolate* pIsolate,
-                           CFXJSE_Value* pValue,
+                           v8::Local<v8::Value>* pValue,
                            bool bSetting,
                            XFA_Attribute eAttribute) {
   if (bSetting) {
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->SetBoolean(pIsolate, GetXFANode()->IsContainerNode());
+  *pValue = fxv8::NewBooleanHelper(pIsolate, GetXFANode()->IsContainerNode());
 }
 
 void CJX_Node::isNull(v8::Isolate* pIsolate,
-                      CFXJSE_Value* pValue,
+                      v8::Local<v8::Value>* pValue,
                       bool bSetting,
                       XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -445,14 +444,14 @@
     return;
   }
   if (GetXFANode()->GetElementType() == XFA_Element::Subform) {
-    pValue->SetBoolean(pIsolate, false);
+    *pValue = fxv8::NewBooleanHelper(pIsolate, false);
     return;
   }
-  pValue->SetBoolean(pIsolate, GetContent(false).IsEmpty());
+  *pValue = fxv8::NewBooleanHelper(pIsolate, GetContent(false).IsEmpty());
 }
 
 void CJX_Node::oneOfChild(v8::Isolate* pIsolate,
-                          CFXJSE_Value* pValue,
+                          v8::Local<v8::Value>* pValue,
                           bool bSetting,
                           XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -463,10 +462,8 @@
   std::vector<CXFA_Node*> properties =
       GetXFANode()->GetNodeListWithFilter(XFA_NODEFILTER_OneOfProperty);
   if (!properties.empty()) {
-    pValue->ForceSetValue(
-        pIsolate,
-        GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-            properties.front()));
+    *pValue = GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+        properties.front());
   }
 }
 
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index 7426c19..4d4f13b 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -14,10 +14,10 @@
 #include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "core/fxcrt/xml/cfx_xmltext.h"
 #include "fxjs/cjs_result.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/gc/container_trace.h"
 #include "fxjs/xfa/cfxjse_engine.h"
 #include "fxjs/xfa/cfxjse_mapmodule.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "fxjs/xfa/cjx_boolean.h"
 #include "fxjs/xfa/cjx_draw.h"
 #include "fxjs/xfa/cjx_field.h"
@@ -126,14 +126,14 @@
 }
 
 void CJX_Object::className(v8::Isolate* pIsolate,
-                           CFXJSE_Value* pValue,
+                           v8::Local<v8::Value>* pValue,
                            bool bSetting,
                            XFA_Attribute eAttribute) {
   if (bSetting) {
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->SetString(pIsolate, GetXFAObject()->GetClassName());
+  *pValue = fxv8::NewStringHelper(pIsolate, GetXFAObject()->GetClassName());
 }
 
 int32_t CJX_Object::Subform_and_SubformSet_InstanceIndex() {
@@ -944,16 +944,16 @@
 }
 
 void CJX_Object::ScriptAttributeString(v8::Isolate* pIsolate,
-                                       CFXJSE_Value* pValue,
+                                       v8::Local<v8::Value>* pValue,
                                        bool bSetting,
                                        XFA_Attribute eAttribute) {
   if (!bSetting) {
-    pValue->SetString(pIsolate,
-                      GetAttributeByEnum(eAttribute).ToUTF8().AsStringView());
+    *pValue = fxv8::NewStringHelper(
+        pIsolate, GetAttributeByEnum(eAttribute).ToUTF8().AsStringView());
     return;
   }
 
-  WideString wsValue = pValue->ToWideString(pIsolate);
+  WideString wsValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
   SetAttributeByEnum(eAttribute, wsValue, true);
   if (eAttribute != XFA_Attribute::Use ||
       GetXFAObject()->GetElementType() != XFA_Element::Desc) {
@@ -1014,29 +1014,31 @@
 }
 
 void CJX_Object::ScriptAttributeBool(v8::Isolate* pIsolate,
-                                     CFXJSE_Value* pValue,
+                                     v8::Local<v8::Value>* pValue,
                                      bool bSetting,
                                      XFA_Attribute eAttribute) {
   if (bSetting) {
-    SetBoolean(eAttribute, pValue->ToBoolean(pIsolate), true);
+    SetBoolean(eAttribute, fxv8::ReentrantToBooleanHelper(pIsolate, *pValue),
+               true);
     return;
   }
-  pValue->SetString(pIsolate, GetBoolean(eAttribute) ? "1" : "0");
+  *pValue = fxv8::NewStringHelper(pIsolate, GetBoolean(eAttribute) ? "1" : "0");
 }
 
 void CJX_Object::ScriptAttributeInteger(v8::Isolate* pIsolate,
-                                        CFXJSE_Value* pValue,
+                                        v8::Local<v8::Value>* pValue,
                                         bool bSetting,
                                         XFA_Attribute eAttribute) {
   if (bSetting) {
-    SetInteger(eAttribute, pValue->ToInteger(pIsolate), true);
+    SetInteger(eAttribute, fxv8::ReentrantToInt32Helper(pIsolate, *pValue),
+               true);
     return;
   }
-  pValue->SetInteger(pIsolate, GetInteger(eAttribute));
+  *pValue = fxv8::NewNumberHelper(pIsolate, GetInteger(eAttribute));
 }
 
 void CJX_Object::ScriptSomFontColor(v8::Isolate* pIsolate,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     bool bSetting,
                                     XFA_Attribute eAttribute) {
   CXFA_Font* font = ToNode(object_.Get())->GetOrCreateFontIfPossible();
@@ -1047,7 +1049,8 @@
     int32_t r;
     int32_t g;
     int32_t b;
-    std::tie(r, g, b) = StrToRGB(pValue->ToWideString(pIsolate));
+    std::tie(r, g, b) =
+        StrToRGB(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
     FX_ARGB color = ArgbEncode(0xff, r, g, b);
     font->SetColor(color);
     return;
@@ -1058,12 +1061,12 @@
   int32_t g;
   int32_t b;
   std::tie(a, r, g, b) = ArgbDecode(font->GetColor());
-  pValue->SetString(pIsolate,
-                    ByteString::Format("%d,%d,%d", r, g, b).AsStringView());
+  *pValue = fxv8::NewStringHelper(
+      pIsolate, ByteString::Format("%d,%d,%d", r, g, b).AsStringView());
 }
 
 void CJX_Object::ScriptSomFillColor(v8::Isolate* pIsolate,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     bool bSetting,
                                     XFA_Attribute eAttribute) {
   CXFA_Border* border = ToNode(object_.Get())->GetOrCreateBorderIfPossible();
@@ -1075,7 +1078,8 @@
     int32_t r;
     int32_t g;
     int32_t b;
-    std::tie(r, g, b) = StrToRGB(pValue->ToWideString(pIsolate));
+    std::tie(r, g, b) =
+        StrToRGB(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
     FX_ARGB color = ArgbEncode(0xff, r, g, b);
     borderfill->SetColor(color);
     return;
@@ -1087,13 +1091,12 @@
   int32_t g;
   int32_t b;
   std::tie(a, r, g, b) = ArgbDecode(color);
-  pValue->SetString(
-      pIsolate,
-      WideString::Format(L"%d,%d,%d", r, g, b).ToUTF8().AsStringView());
+  *pValue = fxv8::NewStringHelper(
+      pIsolate, ByteString::Format("%d,%d,%d", r, g, b).AsStringView());
 }
 
 void CJX_Object::ScriptSomBorderColor(v8::Isolate* pIsolate,
-                                      CFXJSE_Value* pValue,
+                                      v8::Local<v8::Value>* pValue,
                                       bool bSetting,
                                       XFA_Attribute eAttribute) {
   CXFA_Border* border = ToNode(object_.Get())->GetOrCreateBorderIfPossible();
@@ -1102,7 +1105,8 @@
     int32_t r = 0;
     int32_t g = 0;
     int32_t b = 0;
-    std::tie(r, g, b) = StrToRGB(pValue->ToWideString(pIsolate));
+    std::tie(r, g, b) =
+        StrToRGB(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
     FX_ARGB rgb = ArgbEncode(100, r, g, b);
     for (int32_t i = 0; i < iSize; ++i) {
       CXFA_Edge* edge = border->GetEdgeIfExists(i);
@@ -1120,13 +1124,12 @@
   int32_t g;
   int32_t b;
   std::tie(a, r, g, b) = ArgbDecode(color);
-  pValue->SetString(
-      pIsolate,
-      WideString::Format(L"%d,%d,%d", r, g, b).ToUTF8().AsStringView());
+  *pValue = fxv8::NewStringHelper(
+      pIsolate, ByteString::Format("%d,%d,%d", r, g, b).AsStringView());
 }
 
 void CJX_Object::ScriptSomBorderWidth(v8::Isolate* pIsolate,
-                                      CFXJSE_Value* pValue,
+                                      v8::Local<v8::Value>* pValue,
                                       bool bSetting,
                                       XFA_Attribute eAttribute) {
   CXFA_Border* border = ToNode(object_.Get())->GetOrCreateBorderIfPossible();
@@ -1134,14 +1137,15 @@
     CXFA_Edge* edge = border->GetEdgeIfExists(0);
     CXFA_Measurement thickness =
         edge ? edge->GetMSThickness() : CXFA_Measurement(0.5, XFA_Unit::Pt);
-    pValue->SetString(pIsolate, thickness.ToString().ToUTF8().AsStringView());
+    *pValue = fxv8::NewStringHelper(
+        pIsolate, thickness.ToString().ToUTF8().AsStringView());
     return;
   }
 
   if (pValue->IsEmpty())
     return;
 
-  WideString wsThickness = pValue->ToWideString(pIsolate);
+  WideString wsThickness = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
   for (int32_t i = 0; i < border->CountEdges(); ++i) {
     CXFA_Edge* edge = border->GetEdgeIfExists(i);
     if (edge)
@@ -1150,7 +1154,7 @@
 }
 
 void CJX_Object::ScriptSomMessage(v8::Isolate* pIsolate,
-                                  CFXJSE_Value* pValue,
+                                  v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_SOM_MESSAGETYPE iMessageType) {
   bool bNew = false;
@@ -1164,13 +1168,16 @@
     if (validate) {
       switch (iMessageType) {
         case XFA_SOM_ValidationMessage:
-          validate->SetScriptMessageText(pValue->ToWideString(pIsolate));
+          validate->SetScriptMessageText(
+              fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
           break;
         case XFA_SOM_FormatMessage:
-          validate->SetFormatMessageText(pValue->ToWideString(pIsolate));
+          validate->SetFormatMessageText(
+              fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
           break;
         case XFA_SOM_MandatoryMessage:
-          validate->SetNullMessageText(pValue->ToWideString(pIsolate));
+          validate->SetNullMessageText(
+              fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
           break;
         default:
           break;
@@ -1207,25 +1214,25 @@
     default:
       break;
   }
-  pValue->SetString(pIsolate, wsMessage.ToUTF8().AsStringView());
+  *pValue = fxv8::NewStringHelper(pIsolate, wsMessage.ToUTF8().AsStringView());
 }
 
 void CJX_Object::ScriptSomValidationMessage(v8::Isolate* pIsolate,
-                                            CFXJSE_Value* pValue,
+                                            v8::Local<v8::Value>* pValue,
                                             bool bSetting,
                                             XFA_Attribute eAttribute) {
   ScriptSomMessage(pIsolate, pValue, bSetting, XFA_SOM_ValidationMessage);
 }
 
 void CJX_Object::ScriptSomMandatoryMessage(v8::Isolate* pIsolate,
-                                           CFXJSE_Value* pValue,
+                                           v8::Local<v8::Value>* pValue,
                                            bool bSetting,
                                            XFA_Attribute eAttribute) {
   ScriptSomMessage(pIsolate, pValue, bSetting, XFA_SOM_MandatoryMessage);
 }
 
 void CJX_Object::ScriptSomDefaultValue(v8::Isolate* pIsolate,
-                                       CFXJSE_Value* pValue,
+                                       v8::Local<v8::Value>* pValue,
                                        bool bSetting,
                                        XFA_Attribute /* unused */) {
   XFA_Element eType = GetXFANode()->GetElementType();
@@ -1251,12 +1258,12 @@
 
   if (bSetting) {
     WideString wsNewValue;
-    if (pValue && !(pValue->IsEmpty() || pValue->IsNull(pIsolate) ||
-                    pValue->IsUndefined(pIsolate))) {
-      wsNewValue = pValue->ToWideString(pIsolate);
+    if (pValue && !(pValue->IsEmpty() || fxv8::IsNull(*pValue) ||
+                    fxv8::IsUndefined(*pValue))) {
+      wsNewValue = fxv8::ReentrantToWideStringHelper(pIsolate, *pValue);
     }
 
-    WideString wsFormatValue(wsNewValue);
+    WideString wsFormatValue = wsNewValue;
     CXFA_Node* pContainerNode = nullptr;
     if (GetXFANode()->GetPacketType() == XFA_PacketType::Datasets) {
       WideString wsPicture;
@@ -1288,19 +1295,19 @@
   WideString content = GetContent(true);
   if (content.IsEmpty() && eType != XFA_Element::Text &&
       eType != XFA_Element::SubmitUrl) {
-    pValue->SetNull(pIsolate);
+    *pValue = fxv8::NewNullHelper(pIsolate);
   } else if (eType == XFA_Element::Integer) {
-    pValue->SetInteger(pIsolate, FXSYS_wtoi(content.c_str()));
+    *pValue = fxv8::NewNumberHelper(pIsolate, FXSYS_wtoi(content.c_str()));
   } else if (eType == XFA_Element::Float || eType == XFA_Element::Decimal) {
     CFGAS_Decimal decimal(content.AsStringView());
-    pValue->SetFloat(pIsolate, decimal.ToFloat());
+    *pValue = fxv8::NewNumberHelper(pIsolate, decimal.ToFloat());
   } else {
-    pValue->SetString(pIsolate, content.ToUTF8().AsStringView());
+    *pValue = fxv8::NewStringHelper(pIsolate, content.ToUTF8().AsStringView());
   }
 }
 
 void CJX_Object::ScriptSomDefaultValue_Read(v8::Isolate* pIsolate,
-                                            CFXJSE_Value* pValue,
+                                            v8::Local<v8::Value>* pValue,
                                             bool bSetting,
                                             XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -1310,14 +1317,14 @@
 
   WideString content = GetContent(true);
   if (content.IsEmpty()) {
-    pValue->SetNull(pIsolate);
+    *pValue = fxv8::NewNullHelper(pIsolate);
     return;
   }
-  pValue->SetString(pIsolate, content.ToUTF8().AsStringView());
+  *pValue = fxv8::NewStringHelper(pIsolate, content.ToUTF8().AsStringView());
 }
 
 void CJX_Object::ScriptSomDataNode(v8::Isolate* pIsolate,
-                                   CFXJSE_Value* pValue,
+                                   v8::Local<v8::Value>* pValue,
                                    bool bSetting,
                                    XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -1327,17 +1334,16 @@
 
   CXFA_Node* pDataNode = GetXFANode()->GetBindData();
   if (!pDataNode) {
-    pValue->SetNull(pIsolate);
+    *pValue = fxv8::NewNullHelper(pIsolate);
     return;
   }
 
-  pValue->ForceSetValue(
-      pIsolate, GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-                    pDataNode));
+  *pValue =
+      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pDataNode);
 }
 
 void CJX_Object::ScriptSomMandatory(v8::Isolate* pIsolate,
-                                    CFXJSE_Value* pValue,
+                                    v8::Local<v8::Value>* pValue,
                                     bool bSetting,
                                     XFA_Attribute eAttribute) {
   CXFA_Validate* validate =
@@ -1346,24 +1352,25 @@
     return;
 
   if (bSetting) {
-    validate->SetNullTest(pValue->ToWideString(pIsolate));
+    validate->SetNullTest(fxv8::ReentrantToWideStringHelper(pIsolate, *pValue));
     return;
   }
 
-  pValue->SetString(pIsolate,
-                    XFA_AttributeValueToName(validate->GetNullTest()));
+  *pValue = fxv8::NewStringHelper(
+      pIsolate, XFA_AttributeValueToName(validate->GetNullTest()));
 }
 
 void CJX_Object::ScriptSomInstanceIndex(v8::Isolate* pIsolate,
-                                        CFXJSE_Value* pValue,
+                                        v8::Local<v8::Value>* pValue,
                                         bool bSetting,
                                         XFA_Attribute eAttribute) {
   if (!bSetting) {
-    pValue->SetInteger(pIsolate, Subform_and_SubformSet_InstanceIndex());
+    *pValue =
+        fxv8::NewNumberHelper(pIsolate, Subform_and_SubformSet_InstanceIndex());
     return;
   }
 
-  int32_t iTo = pValue->ToInteger(pIsolate);
+  int32_t iTo = fxv8::ReentrantToInt32Helper(pIsolate, *pValue);
   int32_t iFrom = Subform_and_SubformSet_InstanceIndex();
   CXFA_Node* pManagerNode = nullptr;
   for (CXFA_Node* pNode = GetXFANode()->GetPrevSibling(); pNode;
@@ -1395,7 +1402,7 @@
 }
 
 void CJX_Object::ScriptSubmitFormatMode(v8::Isolate* pIsolate,
-                                        CFXJSE_Value* pValue,
+                                        v8::Local<v8::Value>* pValue,
                                         bool bSetting,
                                         XFA_Attribute eAttribute) {}
 
diff --git a/fxjs/xfa/cjx_object.h b/fxjs/xfa/cjx_object.h
index bae2419..d6e1872 100644
--- a/fxjs/xfa/cjx_object.h
+++ b/fxjs/xfa/cjx_object.h
@@ -181,7 +181,7 @@
   JSE_PROP(ScriptSubmitFormatMode);
 
   void ScriptSomMessage(v8::Isolate* pIsolate,
-                        CFXJSE_Value* pValue,
+                        v8::Local<v8::Value>* pValue,
                         bool bSetting,
                         XFA_SOM_MESSAGETYPE iMessageType);
 
diff --git a/fxjs/xfa/cjx_occur.cpp b/fxjs/xfa/cjx_occur.cpp
index c3aa678..701e947 100644
--- a/fxjs/xfa/cjx_occur.cpp
+++ b/fxjs/xfa/cjx_occur.cpp
@@ -6,6 +6,7 @@
 
 #include "fxjs/xfa/cjx_occur.h"
 
+#include "fxjs/fxv8.h"
 #include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fxfa/parser/cxfa_occur.h"
 
@@ -18,25 +19,25 @@
 }
 
 void CJX_Occur::max(v8::Isolate* pIsolate,
-                    CFXJSE_Value* pValue,
+                    v8::Local<v8::Value>* pValue,
                     bool bSetting,
                     XFA_Attribute eAttribute) {
   CXFA_Occur* occur = static_cast<CXFA_Occur*>(GetXFANode());
   if (!bSetting) {
-    pValue->SetInteger(pIsolate, occur->GetMax());
+    *pValue = fxv8::NewNumberHelper(pIsolate, occur->GetMax());
     return;
   }
-  occur->SetMax(pValue->ToInteger(pIsolate));
+  occur->SetMax(fxv8::ReentrantToInt32Helper(pIsolate, *pValue));
 }
 
 void CJX_Occur::min(v8::Isolate* pIsolate,
-                    CFXJSE_Value* pValue,
+                    v8::Local<v8::Value>* pValue,
                     bool bSetting,
                     XFA_Attribute eAttribute) {
   CXFA_Occur* occur = static_cast<CXFA_Occur*>(GetXFANode());
   if (!bSetting) {
-    pValue->SetInteger(pIsolate, occur->GetMin());
+    *pValue = fxv8::NewNumberHelper(pIsolate, occur->GetMin());
     return;
   }
-  occur->SetMin(pValue->ToInteger(pIsolate));
+  occur->SetMin(fxv8::ReentrantToInt32Helper(pIsolate, *pValue));
 }
diff --git a/fxjs/xfa/cjx_packet.cpp b/fxjs/xfa/cjx_packet.cpp
index 70c8609..a34a4ec 100644
--- a/fxjs/xfa/cjx_packet.cpp
+++ b/fxjs/xfa/cjx_packet.cpp
@@ -13,8 +13,8 @@
 #include "core/fxcrt/xml/cfx_xmlelement.h"
 #include "core/fxcrt/xml/cfx_xmltext.h"
 #include "fxjs/cfx_v8.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fxfa/cxfa_ffdoc.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/parser/cxfa_packet.h"
@@ -79,7 +79,7 @@
 }
 
 void CJX_Packet::content(v8::Isolate* pIsolate,
-                         CFXJSE_Value* pValue,
+                         v8::Local<v8::Value>* pValue,
                          bool bSetting,
                          XFA_Attribute eAttribute) {
   CFX_XMLElement* element = ToXMLElement(GetXFANode()->GetXMLMappingNode());
@@ -91,7 +91,8 @@
               ->GetNotify()
               ->GetFFDoc()
               ->GetXMLDocument()
-              ->CreateNode<CFX_XMLText>(pValue->ToWideString(pIsolate)));
+              ->CreateNode<CFX_XMLText>(
+                  fxv8::ReentrantToWideStringHelper(pIsolate, *pValue)));
     }
     return;
   }
@@ -100,5 +101,5 @@
   if (element)
     wsTextData = element->GetTextData();
 
-  pValue->SetString(pIsolate, wsTextData.ToUTF8().AsStringView());
+  *pValue = fxv8::NewStringHelper(pIsolate, wsTextData.ToUTF8().AsStringView());
 }
diff --git a/fxjs/xfa/cjx_script.cpp b/fxjs/xfa/cjx_script.cpp
index a2de5a7..913afc9 100644
--- a/fxjs/xfa/cjx_script.cpp
+++ b/fxjs/xfa/cjx_script.cpp
@@ -6,7 +6,7 @@
 
 #include "fxjs/xfa/cjx_script.h"
 
-#include "fxjs/xfa/cfxjse_value.h"
+#include "fxjs/fxv8.h"
 #include "xfa/fxfa/parser/cxfa_script.h"
 
 CJX_Script::CJX_Script(CXFA_Script* node) : CJX_Node(node) {}
@@ -18,12 +18,12 @@
 }
 
 void CJX_Script::stateless(v8::Isolate* pIsolate,
-                           CFXJSE_Value* pValue,
+                           v8::Local<v8::Value>* pValue,
                            bool bSetting,
                            XFA_Attribute eAttribute) {
   if (bSetting) {
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->SetString(pIsolate, "0");
+  *pValue = fxv8::NewStringHelper(pIsolate, "0");
 }
diff --git a/fxjs/xfa/cjx_source.cpp b/fxjs/xfa/cjx_source.cpp
index c793f29..4961b0a 100644
--- a/fxjs/xfa/cjx_source.cpp
+++ b/fxjs/xfa/cjx_source.cpp
@@ -184,6 +184,6 @@
 }
 
 void CJX_Source::db(v8::Isolate* pIsolate,
-                    CFXJSE_Value* pValue,
+                    v8::Local<v8::Value>* pValue,
                     bool bSetting,
                     XFA_Attribute eAttribute) {}
diff --git a/fxjs/xfa/cjx_subform.cpp b/fxjs/xfa/cjx_subform.cpp
index 4162b1d..e555012 100644
--- a/fxjs/xfa/cjx_subform.cpp
+++ b/fxjs/xfa/cjx_subform.cpp
@@ -9,9 +9,9 @@
 #include <vector>
 
 #include "fxjs/cfx_v8.h"
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fxfa/cxfa_eventparam.h"
 #include "xfa/fxfa/cxfa_ffnotify.h"
 #include "xfa/fxfa/fxfa.h"
@@ -88,21 +88,23 @@
 }
 
 void CJX_Subform::locale(v8::Isolate* pIsolate,
-                         CFXJSE_Value* pValue,
+                         v8::Local<v8::Value>* pValue,
                          bool bSetting,
                          XFA_Attribute eAttribute) {
   if (bSetting) {
-    SetCDataImpl(XFA_Attribute::Locale, pValue->ToWideString(pIsolate), true,
+    SetCDataImpl(XFA_Attribute::Locale,
+                 fxv8::ReentrantToWideStringHelper(pIsolate, *pValue), true,
                  true);
     return;
   }
 
   WideString wsLocaleName = GetXFANode()->GetLocaleName().value_or(L"");
-  pValue->SetString(pIsolate, wsLocaleName.ToUTF8().AsStringView());
+  *pValue =
+      fxv8::NewStringHelper(pIsolate, wsLocaleName.ToUTF8().AsStringView());
 }
 
 void CJX_Subform::instanceManager(v8::Isolate* pIsolate,
-                                  CFXJSE_Value* pValue,
+                                  v8::Local<v8::Value>* pValue,
                                   bool bSetting,
                                   XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -124,12 +126,9 @@
       break;
     }
   }
-  if (!pInstanceMgr) {
-    pValue->SetNull(pIsolate);
-    return;
-  }
-
-  pValue->ForceSetValue(
-      pIsolate, GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-                    pInstanceMgr));
+  *pValue = pInstanceMgr ? GetDocument()
+                               ->GetScriptContext()
+                               ->GetOrCreateJSBindingFromMap(pInstanceMgr)
+                               .As<v8::Value>()
+                         : fxv8::NewNullHelper(pIsolate).As<v8::Value>();
 }
diff --git a/fxjs/xfa/cjx_textnode.cpp b/fxjs/xfa/cjx_textnode.cpp
index 6e90fb3..b8afd77 100644
--- a/fxjs/xfa/cjx_textnode.cpp
+++ b/fxjs/xfa/cjx_textnode.cpp
@@ -18,14 +18,14 @@
 }
 
 void CJX_TextNode::defaultValue(v8::Isolate* pIsolate,
-                                CFXJSE_Value* pValue,
+                                v8::Local<v8::Value>* pValue,
                                 bool bSetting,
                                 XFA_Attribute attr) {
   ScriptSomDefaultValue(pIsolate, pValue, bSetting, attr);
 }
 
 void CJX_TextNode::value(v8::Isolate* pIsolate,
-                         CFXJSE_Value* pValue,
+                         v8::Local<v8::Value>* pValue,
                          bool bSetting,
                          XFA_Attribute attr) {
   ScriptSomDefaultValue(pIsolate, pValue, bSetting, attr);
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp
index ae49ea2..477374a 100644
--- a/fxjs/xfa/cjx_tree.cpp
+++ b/fxjs/xfa/cjx_tree.cpp
@@ -9,9 +9,10 @@
 #include <memory>
 #include <vector>
 
+#include "fxjs/fxv8.h"
 #include "fxjs/js_resources.h"
+#include "fxjs/xfa/cfxjse_class.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "third_party/base/numerics/safe_conversions.h"
 #include "v8/include/cppgc/allocation.h"
 #include "xfa/fxfa/parser/cxfa_arraynodelist.h"
@@ -67,13 +68,12 @@
     return CJS_Result::Success(runtime->NewNull());
   }
 
-  auto pValue = std::make_unique<CFXJSE_Value>();
+  v8::Local<v8::Value> pValue;
   CJX_Object* jsObject = maybeResult.value().objects.front()->JSObject();
   (*maybeResult.value().script_attribute.callback)(
-      runtime->GetIsolate(), jsObject, pValue.get(), false,
+      runtime->GetIsolate(), jsObject, &pValue, false,
       maybeResult.value().script_attribute.attribute);
-  return CJS_Result::Success(
-      pValue->DirectGetValue().Get(runtime->GetIsolate()));
+  return CJS_Result::Success(pValue);
 }
 
 CJS_Result CJX_Tree::resolveNodes(
@@ -87,19 +87,18 @@
     refNode = GetDocument()->GetScriptContext()->GetThisObject();
 
   CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
-  auto pValue = std::make_unique<CFXJSE_Value>();
-  ResolveNodeList(pScriptContext->GetIsolate(), pValue.get(),
+  v8::Local<v8::Value> pValue;
+  ResolveNodeList(pScriptContext->GetIsolate(), &pValue,
                   runtime->ToWideString(params[0]),
                   XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes |
                       XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent |
                       XFA_RESOLVENODE_Siblings,
                   ToNode(refNode));
-  return CJS_Result::Success(
-      pValue->DirectGetValue().Get(runtime->GetIsolate()));
+  return CJS_Result::Success(pValue);
 }
 
 void CJX_Tree::all(v8::Isolate* pIsolate,
-                   CFXJSE_Value* pValue,
+                   v8::Local<v8::Value>* pValue,
                    bool bSetting,
                    XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -113,7 +112,7 @@
 }
 
 void CJX_Tree::classAll(v8::Isolate* pIsolate,
-                        CFXJSE_Value* pValue,
+                        v8::Local<v8::Value>* pValue,
                         bool bSetting,
                         XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -128,7 +127,7 @@
 }
 
 void CJX_Tree::nodes(v8::Isolate* pIsolate,
-                     CFXJSE_Value* pValue,
+                     v8::Local<v8::Value>* pValue,
                      bool bSetting,
                      XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -143,12 +142,12 @@
   pDoc->GetNodeOwner()->PersistList(pNodeList);
 
   CFXJSE_Engine* pEngine = pDoc->GetScriptContext();
-  pValue->SetHostObject(pIsolate, pNodeList->JSObject(),
-                        pEngine->GetJseNormalClass());
+  *pValue = pNodeList->JSObject()->NewBoundV8Object(
+      pIsolate, pEngine->GetJseNormalClass()->GetTemplate(pIsolate));
 }
 
 void CJX_Tree::parent(v8::Isolate* pIsolate,
-                      CFXJSE_Value* pValue,
+                      v8::Local<v8::Value>* pValue,
                       bool bSetting,
                       XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -157,18 +156,15 @@
   }
 
   CXFA_Node* pParent = GetXFANode()->GetParent();
-  if (!pParent) {
-    pValue->SetNull(pIsolate);
-    return;
-  }
-
-  pValue->ForceSetValue(
-      pIsolate,
-      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pParent));
+  *pValue = pParent ? GetDocument()
+                          ->GetScriptContext()
+                          ->GetOrCreateJSBindingFromMap(pParent)
+                          .As<v8::Value>()
+                    : fxv8::NewNullHelper(pIsolate).As<v8::Value>();
 }
 
 void CJX_Tree::index(v8::Isolate* pIsolate,
-                     CFXJSE_Value* pValue,
+                     v8::Local<v8::Value>* pValue,
                      bool bSetting,
                      XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -178,11 +174,12 @@
 
   CXFA_Node* pNode = GetXFANode();
   size_t iIndex = pNode ? pNode->GetIndexByName() : 0;
-  pValue->SetInteger(pIsolate, pdfium::base::checked_cast<int32_t>(iIndex));
+  *pValue = fxv8::NewNumberHelper(pIsolate,
+                                  pdfium::base::checked_cast<int32_t>(iIndex));
 }
 
 void CJX_Tree::classIndex(v8::Isolate* pIsolate,
-                          CFXJSE_Value* pValue,
+                          v8::Local<v8::Value>* pValue,
                           bool bSetting,
                           XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -192,11 +189,12 @@
 
   CXFA_Node* pNode = GetXFANode();
   size_t iIndex = pNode ? pNode->GetIndexByClassName() : 0;
-  pValue->SetInteger(pIsolate, pdfium::base::checked_cast<int32_t>(iIndex));
+  *pValue = fxv8::NewNumberHelper(pIsolate,
+                                  pdfium::base::checked_cast<int32_t>(iIndex));
 }
 
 void CJX_Tree::somExpression(v8::Isolate* pIsolate,
-                             CFXJSE_Value* pValue,
+                             v8::Local<v8::Value>* pValue,
                              bool bSetting,
                              XFA_Attribute eAttribute) {
   if (bSetting) {
@@ -204,12 +202,12 @@
     return;
   }
 
-  WideString wsSOMExpression = GetXFAObject()->GetSOMExpression();
-  pValue->SetString(pIsolate, wsSOMExpression.ToUTF8().AsStringView());
+  ByteString bsSOMExpression = GetXFAObject()->GetSOMExpression().ToUTF8();
+  *pValue = fxv8::NewStringHelper(pIsolate, bsSOMExpression.AsStringView());
 }
 
 void CJX_Tree::ResolveNodeList(v8::Isolate* pIsolate,
-                               CFXJSE_Value* pValue,
+                               v8::Local<v8::Value>* pValue,
                                WideString wsExpression,
                                uint32_t dwFlag,
                                CXFA_Node* refNode) {
@@ -238,19 +236,19 @@
           maybeResult.value().script_attribute.eValueType ==
               XFA_ScriptType::Object) {
         for (auto& pObject : maybeResult.value().objects) {
-          auto innerValue = std::make_unique<CFXJSE_Value>();
+          v8::Local<v8::Value> innerValue;
           CJX_Object* jsObject = pObject->JSObject();
           (*maybeResult.value().script_attribute.callback)(
-              pIsolate, jsObject, innerValue.get(), false,
+              pIsolate, jsObject, &innerValue, false,
               maybeResult.value().script_attribute.attribute);
-          CXFA_Object* obj = CFXJSE_Engine::ToObject(
-              pScriptContext->GetIsolate(), innerValue.get());
+          CXFA_Object* obj =
+              CFXJSE_Engine::ToObject(pScriptContext->GetIsolate(), innerValue);
           if (obj->IsNode())
             pNodeList->Append(obj->AsNode());
         }
       }
     }
   }
-  pValue->SetHostObject(pIsolate, pNodeList->JSObject(),
-                        pScriptContext->GetJseNormalClass());
+  *pValue = pNodeList->JSObject()->NewBoundV8Object(
+      pIsolate, pScriptContext->GetJseNormalClass()->GetTemplate(pIsolate));
 }
diff --git a/fxjs/xfa/cjx_tree.h b/fxjs/xfa/cjx_tree.h
index ad117f3..d155cb7 100644
--- a/fxjs/xfa/cjx_tree.h
+++ b/fxjs/xfa/cjx_tree.h
@@ -44,7 +44,7 @@
   static const CJX_MethodSpec MethodSpecs[];
 
   void ResolveNodeList(v8::Isolate* pIsolate,
-                       CFXJSE_Value* pValue,
+                       v8::Local<v8::Value>* pValue,
                        WideString wsExpression,
                        uint32_t dwFlag,
                        CXFA_Node* refNode);
diff --git a/fxjs/xfa/cjx_xfa.cpp b/fxjs/xfa/cjx_xfa.cpp
index 88982dc..2d05241 100644
--- a/fxjs/xfa/cjx_xfa.cpp
+++ b/fxjs/xfa/cjx_xfa.cpp
@@ -6,8 +6,8 @@
 
 #include "fxjs/xfa/cjx_xfa.h"
 
+#include "fxjs/fxv8.h"
 #include "fxjs/xfa/cfxjse_engine.h"
-#include "fxjs/xfa/cfxjse_value.h"
 #include "xfa/fxfa/parser/cxfa_document.h"
 #include "xfa/fxfa/parser/cxfa_xfa.h"
 
@@ -20,7 +20,7 @@
 }
 
 void CJX_Xfa::thisValue(v8::Isolate* pIsolate,
-                        CFXJSE_Value* pValue,
+                        v8::Local<v8::Value>* pValue,
                         bool bSetting,
                         XFA_Attribute eAttribute) {
   if (bSetting)
@@ -28,10 +28,7 @@
 
   auto* pScriptContext = GetDocument()->GetScriptContext();
   CXFA_Object* pThis = pScriptContext->GetThisObject();
-  if (!pThis) {
-    pValue->SetNull(pIsolate);
-    return;
-  }
-  pValue->ForceSetValue(pIsolate,
-                        pScriptContext->GetOrCreateJSBindingFromMap(pThis));
+  *pValue =
+      pThis ? pScriptContext->GetOrCreateJSBindingFromMap(pThis).As<v8::Value>()
+            : fxv8::NewNullHelper(pIsolate);
 }
diff --git a/fxjs/xfa/fxjse.h b/fxjs/xfa/fxjse.h
index a1cb183..fd7ff18 100644
--- a/fxjs/xfa/fxjse.h
+++ b/fxjs/xfa/fxjse.h
@@ -50,10 +50,13 @@
 typedef void (*FXJSE_FuncCallback)(
     CFXJSE_HostObject* pThis,
     const v8::FunctionCallbackInfo<v8::Value>& info);
-typedef void (*FXJSE_PropAccessor)(v8::Isolate* pIsolate,
-                                   v8::Local<v8::Object> pObject,
-                                   ByteStringView szPropName,
-                                   CFXJSE_Value* pValue);
+typedef v8::Local<v8::Value> (*FXJSE_PropGetter)(v8::Isolate* pIsolate,
+                                                 v8::Local<v8::Object> pObject,
+                                                 ByteStringView szPropName);
+typedef void (*FXJSE_PropSetter)(v8::Isolate* pIsolate,
+                                 v8::Local<v8::Object> pObject,
+                                 ByteStringView szPropName,
+                                 v8::Local<v8::Value> pValue);
 typedef int32_t (*FXJSE_PropTypeGetter)(v8::Isolate* pIsolate,
                                         v8::Local<v8::Object> pObject,
                                         ByteStringView szPropName,
@@ -77,8 +80,8 @@
   const FXJSE_FUNCTION_DESCRIPTOR* methods;
   int32_t methNum;
   FXJSE_PropTypeGetter dynPropTypeGetter;
-  FXJSE_PropAccessor dynPropGetter;
-  FXJSE_PropAccessor dynPropSetter;
+  FXJSE_PropGetter dynPropGetter;
+  FXJSE_PropSetter dynPropSetter;
   FXJSE_MethodCallback dynMethodCall;
 };
 
diff --git a/fxjs/xfa/jse_define.h b/fxjs/xfa/jse_define.h
index 328e0a0..bb181b2 100644
--- a/fxjs/xfa/jse_define.h
+++ b/fxjs/xfa/jse_define.h
@@ -24,15 +24,15 @@
   CJS_Result method_name(CFX_V8* runtime,                            \
                          const std::vector<v8::Local<v8::Value>>& params)
 
-#define JSE_PROP(prop_name)                                                  \
-  static void prop_name##_static(v8::Isolate* pIsolate, CJX_Object* node,    \
-                                 CFXJSE_Value* value, bool setting,          \
-                                 XFA_Attribute attribute) {                  \
-    if (node->DynamicTypeIs(static_type__))                                  \
-      static_cast<Type__*>(node)->prop_name(pIsolate, value, setting,        \
-                                            attribute);                      \
-  }                                                                          \
-  void prop_name(v8::Isolate* pIsolate, CFXJSE_Value* pValue, bool bSetting, \
-                 XFA_Attribute eAttribute)
+#define JSE_PROP(prop_name)                                                 \
+  static void prop_name##_static(v8::Isolate* pIsolate, CJX_Object* node,   \
+                                 v8::Local<v8::Value>* value, bool setting, \
+                                 XFA_Attribute attribute) {                 \
+    if (node->DynamicTypeIs(static_type__))                                 \
+      static_cast<Type__*>(node)->prop_name(pIsolate, value, setting,       \
+                                            attribute);                     \
+  }                                                                         \
+  void prop_name(v8::Isolate* pIsolate, v8::Local<v8::Value>* pValue,       \
+                 bool bSetting, XFA_Attribute eAttribute)
 
 #endif  // FXJS_XFA_JSE_DEFINE_H_
diff --git a/xfa/fxfa/parser/xfa_basic_data.h b/xfa/fxfa/parser/xfa_basic_data.h
index 873d01c..500dfbe 100644
--- a/xfa/fxfa/parser/xfa_basic_data.h
+++ b/xfa/fxfa/parser/xfa_basic_data.h
@@ -16,7 +16,7 @@
 
 typedef void (*XFA_ATTRIBUTE_CALLBACK)(v8::Isolate* pIsolate,
                                        CJX_Object* pNode,
-                                       CFXJSE_Value* pValue,
+                                       v8::Local<v8::Value>* pValue,
                                        bool bSetting,
                                        XFA_Attribute eAttribute);