Remove use of CFXJSE_Value in CFXJSE_Engine::m_mapObjectToValue.

Just use v8::Global<v8::Object> directly, and avoid dynamic
allocation of another object.

-- Remove NDEBUG section that can reach an ASSERT() against
   document-controlled values that can't be constrained.

-- Return locals rather than reference to global, which required
   introducing a new scope in one place, since you can't have a
   local without a scope already in effect.

Bug: pdfium:1610
Change-Id: I8fb9982eb65ed2c01a1ac844f04eb722120b6331
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/75933
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
diff --git a/fxjs/xfa/cfxjse_context.cpp b/fxjs/xfa/cfxjse_context.cpp
index a22dcaa..fb706fc 100644
--- a/fxjs/xfa/cfxjse_context.cpp
+++ b/fxjs/xfa/cfxjse_context.cpp
@@ -107,23 +107,6 @@
   return hReturnValue;
 }
 
-class CFXJSE_ScopeUtil_IsolateHandleContext {
- public:
-  explicit CFXJSE_ScopeUtil_IsolateHandleContext(CFXJSE_Context* pContext)
-      : m_parent(pContext->GetIsolate()), m_cscope(pContext->GetContext()) {}
-  CFXJSE_ScopeUtil_IsolateHandleContext(
-      const CFXJSE_ScopeUtil_IsolateHandleContext&) = delete;
-  CFXJSE_ScopeUtil_IsolateHandleContext& operator=(
-      const CFXJSE_ScopeUtil_IsolateHandleContext&) = delete;
-
- private:
-  void* operator new(size_t size) = delete;
-  void operator delete(void*, size_t) = delete;
-
-  CFXJSE_ScopeUtil_IsolateHandle m_parent;
-  v8::Context::Scope m_cscope;
-};
-
 void FXJSE_UpdateProxyBinding(v8::Local<v8::Object> hObject) {
   ASSERT(!hObject.IsEmpty());
   ASSERT(hObject->InternalFieldCount() == 2);
@@ -244,19 +227,19 @@
 }
 
 void CFXJSE_Context::EnableCompatibleMode() {
-  ExecuteScript(szCompatibleModeScript, nullptr, nullptr);
-  ExecuteScript(szConsoleScript, nullptr, nullptr);
+  ExecuteScript(szCompatibleModeScript, nullptr, v8::Local<v8::Object>());
+  ExecuteScript(szConsoleScript, nullptr, v8::Local<v8::Object>());
 }
 
 bool CFXJSE_Context::ExecuteScript(const char* szScript,
                                    CFXJSE_Value* lpRetValue,
-                                   CFXJSE_Value* lpNewThisObject) {
+                                   v8::Local<v8::Object> hNewThis) {
   CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
   v8::Local<v8::Context> hContext = GetIsolate()->GetCurrentContext();
   v8::TryCatch trycatch(GetIsolate());
   v8::Local<v8::String> hScriptString =
       fxv8::NewStringHelper(GetIsolate(), szScript);
-  if (!lpNewThisObject) {
+  if (hNewThis.IsEmpty()) {
     v8::Local<v8::Script> hScript;
     if (v8::Script::Compile(hContext, hScriptString).ToLocal(&hScript)) {
       ASSERT(!trycatch.HasCaught());
@@ -274,9 +257,6 @@
     return false;
   }
 
-  v8::Local<v8::Value> hNewThis = v8::Local<v8::Value>::New(
-      GetIsolate(), lpNewThisObject->DirectGetValue());
-  ASSERT(!hNewThis.IsEmpty());
   v8::Local<v8::String> hEval = fxv8::NewStringHelper(
       GetIsolate(), "(function () { return eval(arguments[0]); })");
   v8::Local<v8::Script> hWrapper =
diff --git a/fxjs/xfa/cfxjse_context.h b/fxjs/xfa/cfxjse_context.h
index 8437a8b..876caa3 100644
--- a/fxjs/xfa/cfxjse_context.h
+++ b/fxjs/xfa/cfxjse_context.h
@@ -37,9 +37,11 @@
   void AddClass(std::unique_ptr<CFXJSE_Class> pClass);
   CFXJSE_Class* GetClassByName(ByteStringView szName) const;
   void EnableCompatibleMode();
+
+  // Note: `lpNewThisObject` may be empty.
   bool ExecuteScript(const char* szScript,
                      CFXJSE_Value* lpRetValue,
-                     CFXJSE_Value* lpNewThisObject);
+                     v8::Local<v8::Object> lpNewThisObject);
 
  private:
   CFXJSE_Context(v8::Isolate* pIsolate, CXFA_ThisProxy* pProxy);
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index bef3342..c30ed04 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -16,6 +16,7 @@
 #include "fxjs/xfa/cfxjse_class.h"
 #include "fxjs/xfa/cfxjse_context.h"
 #include "fxjs/xfa/cfxjse_formcalc_context.h"
+#include "fxjs/xfa/cfxjse_isolatetracker.h"
 #include "fxjs/xfa/cfxjse_nodehelper.h"
 #include "fxjs/xfa/cfxjse_resolveprocessor.h"
 #include "fxjs/xfa/cfxjse_value.h"
@@ -126,17 +127,22 @@
 CFXJSE_Engine::~CFXJSE_Engine() {
   // This is what ensures that the v8 object bound to a CJX_Object
   // no longer retains that binding since it will outlive that object.
-  for (const auto& pair : m_mapObjectToValue)
-    pair.second->ClearHostObject(GetIsolate());
+  CFXJSE_ScopeUtil_IsolateHandleContext scope(m_JsContext.get());
+  for (const auto& pair : m_mapObjectToObject) {
+    const v8::Global<v8::Object>& binding = pair.second;
+    FXJSE_ClearObjectBinding(v8::Local<v8::Object>::New(GetIsolate(), binding));
+  }
 }
 
 bool CFXJSE_Engine::RunScript(CXFA_Script::Type eScriptType,
                               WideStringView wsScript,
                               CFXJSE_Value* hRetValue,
                               CXFA_Object* pThisObject) {
-  ByteString btScript;
+  CFXJSE_ScopeUtil_IsolateHandleContext scope(m_JsContext.get());
   AutoRestorer<CXFA_Script::Type> typeRestorer(&m_eScriptType);
   m_eScriptType = eScriptType;
+
+  ByteString btScript;
   if (eScriptType == CXFA_Script::Type::Formcalc) {
     if (!m_FM2JSContext) {
       m_FM2JSContext = std::make_unique<CFXJSE_FormCalcContext>(
@@ -155,10 +161,12 @@
   AutoRestorer<cppgc::Persistent<CXFA_Object>> nodeRestorer(&m_pThisObject);
   m_pThisObject = pThisObject;
 
-  CFXJSE_Value* pValue =
-      pThisObject ? GetOrCreateJSBindingFromMap(pThisObject) : nullptr;
+  v8::Local<v8::Object> pThisBinding;
+  if (pThisObject)
+    pThisBinding = GetOrCreateJSBindingFromMap(pThisObject);
+
   IJS_Runtime::ScopedEventContext ctx(m_pSubordinateRuntime.Get());
-  return m_JsContext->ExecuteScript(btScript.c_str(), hRetValue, pValue);
+  return m_JsContext->ExecuteScript(btScript.c_str(), hRetValue, pThisBinding);
 }
 
 bool CFXJSE_Engine::QueryNodeByFlag(CXFA_Node* refNode,
@@ -173,8 +181,8 @@
   if (!ResolveObjects(refNode, propname, &resolveRs, dwFlag, nullptr))
     return false;
   if (resolveRs.dwFlags == XFA_ResolveNodeRS::Type::kNodes) {
-    pValue->Assign(GetIsolate(), GetOrCreateJSBindingFromMap(
-                                     resolveRs.objects.front().Get()));
+    pValue->ForceSetValue(GetIsolate(), GetOrCreateJSBindingFromMap(
+                                            resolveRs.objects.front().Get()));
     return true;
   }
   if (resolveRs.dwFlags == XFA_ResolveNodeRS::Type::kAttribute &&
@@ -250,8 +258,8 @@
       CXFA_Object* pObj =
           lpScriptContext->GetDocument()->GetXFAObject(uHashCode);
       if (pObj) {
-        pValue->Assign(pIsolate,
-                       lpScriptContext->GetOrCreateJSBindingFromMap(pObj));
+        pValue->ForceSetValue(
+            pIsolate, lpScriptContext->GetOrCreateJSBindingFromMap(pObj));
         return;
       }
     }
@@ -335,9 +343,9 @@
       pOriginalObject->GetDocument()->GetScriptContext();
   CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOriginalObject);
   if (wsPropName.EqualsASCII("xfa")) {
-    CFXJSE_Value* pValue = lpScriptContext->GetOrCreateJSBindingFromMap(
-        lpScriptContext->GetDocument()->GetRoot());
-    pReturnValue->Assign(pIsolate, pValue);
+    pReturnValue->ForceSetValue(pIsolate,
+                                lpScriptContext->GetOrCreateJSBindingFromMap(
+                                    lpScriptContext->GetDocument()->GetRoot()));
     return;
   }
 
@@ -561,7 +569,7 @@
   AutoRestorer<cppgc::Persistent<CXFA_Object>> nodeRestorer(&m_pThisObject);
   m_pThisObject = pThisObject;
   return pVariablesContext->ExecuteScript(btScript.c_str(), hRetValue.get(),
-                                          nullptr);
+                                          v8::Local<v8::Object>());
 }
 
 bool CFXJSE_Engine::QueryVariableValue(CXFA_Node* pScriptNode,
@@ -779,21 +787,21 @@
   return nNodes > 0;
 }
 
-CFXJSE_Value* CFXJSE_Engine::GetOrCreateJSBindingFromMap(CXFA_Object* pObject) {
+v8::Local<v8::Object> CFXJSE_Engine::GetOrCreateJSBindingFromMap(
+    CXFA_Object* pObject) {
   if (pObject->IsNode())
     RunVariablesScript(pObject->AsNode());
 
   CJX_Object* pCJXObject = pObject->JSObject();
-  auto iter = m_mapObjectToValue.find(pCJXObject);
-  if (iter != m_mapObjectToValue.end())
-    return iter->second.get();
+  auto iter = m_mapObjectToObject.find(pCJXObject);
+  if (iter != m_mapObjectToObject.end())
+    return v8::Local<v8::Object>::New(GetIsolate(), iter->second);
 
-  auto jsValue = std::make_unique<CFXJSE_Value>();
-  jsValue->SetHostObject(GetIsolate(), pCJXObject, m_pJsClass.Get());
+  v8::Local<v8::Object> binding = pCJXObject->NewBoundV8Object(
+      GetIsolate(), m_pJsClass->GetTemplate(GetIsolate()));
 
-  CFXJSE_Value* pValue = jsValue.get();
-  m_mapObjectToValue[pCJXObject] = std::move(jsValue);
-  return pValue;
+  m_mapObjectToObject[pCJXObject].Reset(GetIsolate(), binding);
+  return binding;
 }
 
 void CFXJSE_Engine::SetNodesOfRunScript(
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index 19e5225..57b5f35 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -91,7 +91,7 @@
                       uint32_t dwStyles,
                       CXFA_Node* bindNode);
 
-  CFXJSE_Value* GetOrCreateJSBindingFromMap(CXFA_Object* pObject);
+  v8::Local<v8::Object> GetOrCreateJSBindingFromMap(CXFA_Object* pObject);
 
   CXFA_Object* GetThisObject() const { return m_pThisObject; }
   CFXJSE_Class* GetJseNormalClass() const { return m_pJsClass.Get(); }
@@ -136,7 +136,7 @@
   CXFA_Script::Type m_eScriptType = CXFA_Script::Type::Unknown;
   // |m_mapObjectToValue| is what ensures the v8 object bound to a
   // CJX_Object remains valid for the lifetime of the engine.
-  std::map<CJX_Object*, std::unique_ptr<CFXJSE_Value>> m_mapObjectToValue;
+  std::map<CJX_Object*, v8::Global<v8::Object>> m_mapObjectToObject;
   std::map<CJX_Object*, std::unique_ptr<CFXJSE_Context>> m_mapVariableToContext;
   UnownedPtr<CXFA_EventParam> m_eventParam;
   std::vector<cppgc::Persistent<CXFA_Node>> m_upObjectArray;
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index cde20cf..e2f30d7 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -3248,13 +3248,13 @@
     return;
   }
 
-  std::unique_ptr<CFXJSE_Context> pNewContext(
-      CFXJSE_Context::Create(pIsolate, nullptr, nullptr, nullptr));
+  std::unique_ptr<CFXJSE_Context> pNewContext =
+      CFXJSE_Context::Create(pIsolate, nullptr, nullptr, nullptr);
 
   auto returnValue = std::make_unique<CFXJSE_Value>();
   pNewContext->ExecuteScript(
       FX_UTF8Encode(wsJavaScriptBuf.value().AsStringView()).c_str(),
-      returnValue.get(), nullptr);
+      returnValue.get(), v8::Local<v8::Object>());
 
   info.GetReturnValue().Set(returnValue->DirectGetValue());
 }
@@ -5479,8 +5479,9 @@
       dwFlags, nullptr);
   if (bRet && resolveNodeRS.dwFlags == XFA_ResolveNodeRS::Type::kNodes) {
     v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetIsolate();
-    accessorValue->Assign(pIsolate, pScriptContext->GetOrCreateJSBindingFromMap(
-                                        resolveNodeRS.objects.front().Get()));
+    accessorValue->ForceSetValue(pIsolate,
+                                 pScriptContext->GetOrCreateJSBindingFromMap(
+                                     resolveNodeRS.objects.front().Get()));
     return true;
   }
   return false;
@@ -5558,7 +5559,7 @@
     CFXJSE_Engine* pScriptContext = pContext->GetDocument()->GetScriptContext();
     for (auto& pObject : resolveNodeRS.objects) {
       resultValues->push_back(std::make_unique<CFXJSE_Value>());
-      resultValues->back()->Assign(
+      resultValues->back()->ForceSetValue(
           pIsolate, pScriptContext->GetOrCreateJSBindingFromMap(pObject.Get()));
     }
     return;
diff --git a/fxjs/xfa/cfxjse_isolatetracker.cpp b/fxjs/xfa/cfxjse_isolatetracker.cpp
index 6a29e44..7f94ae1 100644
--- a/fxjs/xfa/cfxjse_isolatetracker.cpp
+++ b/fxjs/xfa/cfxjse_isolatetracker.cpp
@@ -6,6 +6,7 @@
 
 #include "fxjs/xfa/cfxjse_isolatetracker.h"
 
+#include "fxjs/xfa/cfxjse_context.h"
 #include "fxjs/xfa/cfxjse_runtimedata.h"
 
 CFXJSE_ScopeUtil_IsolateHandle::CFXJSE_ScopeUtil_IsolateHandle(
@@ -14,6 +15,13 @@
 
 CFXJSE_ScopeUtil_IsolateHandle::~CFXJSE_ScopeUtil_IsolateHandle() = default;
 
+CFXJSE_ScopeUtil_IsolateHandleContext::CFXJSE_ScopeUtil_IsolateHandleContext(
+    CFXJSE_Context* pContext)
+    : m_parent(pContext->GetIsolate()), m_cscope(pContext->GetContext()) {}
+
+CFXJSE_ScopeUtil_IsolateHandleContext::
+    ~CFXJSE_ScopeUtil_IsolateHandleContext() = default;
+
 CFXJSE_ScopeUtil_IsolateHandleRootContext::
     CFXJSE_ScopeUtil_IsolateHandleRootContext(v8::Isolate* pIsolate)
     : CFXJSE_ScopeUtil_IsolateHandle(pIsolate),
diff --git a/fxjs/xfa/cfxjse_isolatetracker.h b/fxjs/xfa/cfxjse_isolatetracker.h
index 020142d..c6e1edf 100644
--- a/fxjs/xfa/cfxjse_isolatetracker.h
+++ b/fxjs/xfa/cfxjse_isolatetracker.h
@@ -9,6 +9,8 @@
 
 #include "v8/include/v8.h"
 
+class CFXJSE_Context;
+
 class CFXJSE_ScopeUtil_IsolateHandle {
  public:
   explicit CFXJSE_ScopeUtil_IsolateHandle(v8::Isolate* pIsolate);
@@ -26,6 +28,23 @@
   v8::HandleScope m_hscope;
 };
 
+class CFXJSE_ScopeUtil_IsolateHandleContext {
+ public:
+  explicit CFXJSE_ScopeUtil_IsolateHandleContext(CFXJSE_Context* pContext);
+  CFXJSE_ScopeUtil_IsolateHandleContext(
+      const CFXJSE_ScopeUtil_IsolateHandleContext&) = delete;
+  CFXJSE_ScopeUtil_IsolateHandleContext& operator=(
+      const CFXJSE_ScopeUtil_IsolateHandleContext&) = delete;
+  ~CFXJSE_ScopeUtil_IsolateHandleContext();
+
+ private:
+  void* operator new(size_t size) = delete;
+  void operator delete(void*, size_t) = delete;
+
+  CFXJSE_ScopeUtil_IsolateHandle m_parent;
+  v8::Context::Scope m_cscope;
+};
+
 class CFXJSE_ScopeUtil_IsolateHandleRootContext final
     : public CFXJSE_ScopeUtil_IsolateHandle {
  public:
diff --git a/fxjs/xfa/cfxjse_value.cpp b/fxjs/xfa/cfxjse_value.cpp
index c3e05da..478e97e 100644
--- a/fxjs/xfa/cfxjse_value.cpp
+++ b/fxjs/xfa/cfxjse_value.cpp
@@ -87,13 +87,6 @@
                                pIsolate, pClass->GetTemplate(pIsolate)));
 }
 
-void CFXJSE_Value::ClearHostObject(v8::Isolate* pIsolate) {
-  CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
-  FXJSE_ClearObjectBinding(m_hValue.Get(pIsolate).As<v8::Object>());
-  v8::Local<v8::Value> hValue = v8::Null(pIsolate);
-  m_hValue.Reset(pIsolate, hValue);
-}
-
 void CFXJSE_Value::SetArray(
     v8::Isolate* pIsolate,
     const std::vector<std::unique_ptr<CFXJSE_Value>>& values) {
diff --git a/fxjs/xfa/cfxjse_value.h b/fxjs/xfa/cfxjse_value.h
index 909145f..d02f00a 100644
--- a/fxjs/xfa/cfxjse_value.h
+++ b/fxjs/xfa/cfxjse_value.h
@@ -55,7 +55,6 @@
   void SetHostObject(v8::Isolate* pIsolate,
                      CFXJSE_HostObject* lpObject,
                      CFXJSE_Class* pClass);
-  void ClearHostObject(v8::Isolate* pIsolate);
 
   void SetArray(v8::Isolate* pIsolate,
                 const std::vector<std::unique_ptr<CFXJSE_Value>>& values);
diff --git a/fxjs/xfa/cjx_exclgroup.cpp b/fxjs/xfa/cjx_exclgroup.cpp
index 74807ee..77fbd32 100644
--- a/fxjs/xfa/cjx_exclgroup.cpp
+++ b/fxjs/xfa/cjx_exclgroup.cpp
@@ -107,12 +107,9 @@
   if (!pReturnNode)
     return CJS_Result::Success(runtime->NewNull());
 
-  CFXJSE_Value* value =
-      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-          pReturnNode);
-
   return CJS_Result::Success(
-      value->DirectGetValue().Get(runtime->GetIsolate()));
+      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+          pReturnNode));
 }
 
 void CJX_ExclGroup::defaultValue(v8::Isolate* pIsolate,
diff --git a/fxjs/xfa/cjx_form.cpp b/fxjs/xfa/cjx_form.cpp
index d398437..20f9542 100644
--- a/fxjs/xfa/cjx_form.cpp
+++ b/fxjs/xfa/cjx_form.cpp
@@ -52,9 +52,8 @@
       pDoc->GetHeap()->GetAllocationHandle(), pDoc);
   pDoc->GetNodeOwner()->PersistList(pFormNodes);
 
-  CFXJSE_Value* value = pEngine->GetOrCreateJSBindingFromMap(pFormNodes);
-  return CJS_Result::Success(
-      value->DirectGetValue().Get(runtime->GetIsolate()));
+  v8::Local<v8::Value> value = pEngine->GetOrCreateJSBindingFromMap(pFormNodes);
+  return CJS_Result::Success(value);
 }
 
 CJS_Result CJX_Form::remerge(CFX_V8* runtime,
diff --git a/fxjs/xfa/cjx_hostpseudomodel.cpp b/fxjs/xfa/cjx_hostpseudomodel.cpp
index 34be45d..b06fd06 100644
--- a/fxjs/xfa/cjx_hostpseudomodel.cpp
+++ b/fxjs/xfa/cjx_hostpseudomodel.cpp
@@ -469,11 +469,10 @@
   if (!pNode)
     return CJS_Result::Success();
 
-  CFXJSE_Value* value =
+  v8::Local<v8::Value> value =
       GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode);
 
-  return CJS_Result::Success(
-      value->DirectGetValue().Get(runtime->GetIsolate()));
+  return CJS_Result::Success(value);
 }
 
 CJS_Result CJX_HostPseudoModel::messageBox(
diff --git a/fxjs/xfa/cjx_instancemanager.cpp b/fxjs/xfa/cjx_instancemanager.cpp
index 7d1fdb6..0188cbf 100644
--- a/fxjs/xfa/cjx_instancemanager.cpp
+++ b/fxjs/xfa/cjx_instancemanager.cpp
@@ -249,12 +249,9 @@
         ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form)));
   }
 
-  CFXJSE_Value* value =
-      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-          pNewInstance);
-
   return CJS_Result::Success(
-      value->DirectGetValue().Get(runtime->GetIsolate()));
+      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+          pNewInstance));
 }
 
 CJS_Result CJX_InstanceManager::insertInstance(
@@ -294,12 +291,9 @@
         ToNode(GetDocument()->GetXFAObject(XFA_HASHCODE_Form)));
   }
 
-  CFXJSE_Value* value =
-      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-          pNewInstance);
-
   return CJS_Result::Success(
-      value->DirectGetValue().Get(runtime->GetIsolate()));
+      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+          pNewInstance));
 }
 
 void CJX_InstanceManager::max(v8::Isolate* pIsolate,
diff --git a/fxjs/xfa/cjx_model.cpp b/fxjs/xfa/cjx_model.cpp
index fc70823..677a4da 100644
--- a/fxjs/xfa/cjx_model.cpp
+++ b/fxjs/xfa/cjx_model.cpp
@@ -65,11 +65,10 @@
       pNewNode->CreateXMLMappingNode();
   }
 
-  CFXJSE_Value* value =
+  v8::Local<v8::Value> value =
       GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNewNode);
 
-  return CJS_Result::Success(
-      value->DirectGetValue().Get(runtime->GetIsolate()));
+  return CJS_Result::Success(value);
 }
 
 CJS_Result CJX_Model::isCompatibleNS(
diff --git a/fxjs/xfa/cjx_node.cpp b/fxjs/xfa/cjx_node.cpp
index db57654..16a40c7 100644
--- a/fxjs/xfa/cjx_node.cpp
+++ b/fxjs/xfa/cjx_node.cpp
@@ -179,12 +179,9 @@
     return CJS_Result::Failure(JSMessage::kParamError);
 
   CXFA_Node* pCloneNode = GetXFANode()->Clone(runtime->ToBoolean(params[0]));
-  CFXJSE_Value* value =
-      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-          pCloneNode);
-
   return CJS_Result::Success(
-      value->DirectGetValue().Get(runtime->GetIsolate()));
+      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+          pCloneNode));
 }
 
 CJS_Result CJX_Node::getAttribute(
@@ -214,11 +211,8 @@
   if (!pNode)
     return CJS_Result::Success(runtime->NewNull());
 
-  CFXJSE_Value* value =
-      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode);
-
   return CJS_Result::Success(
-      value->DirectGetValue().Get(runtime->GetIsolate()));
+      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode));
 }
 
 CJS_Result CJX_Node::isPropertySpecified(
@@ -468,9 +462,9 @@
     ThrowInvalidPropertyException();
     return;
   }
-  pValue->Assign(pIsolate,
-                 GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-                     GetXFANode()->GetModelNode()));
+  pValue->ForceSetValue(
+      pIsolate, GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+                    GetXFANode()->GetModelNode()));
 }
 
 void CJX_Node::isContainer(v8::Isolate* pIsolate,
@@ -511,7 +505,7 @@
   std::vector<CXFA_Node*> properties =
       GetXFANode()->GetNodeListWithFilter(XFA_NODEFILTER_OneOfProperty);
   if (!properties.empty()) {
-    pValue->Assign(
+    pValue->ForceSetValue(
         pIsolate,
         GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
             properties.front()));
diff --git a/fxjs/xfa/cjx_object.cpp b/fxjs/xfa/cjx_object.cpp
index 4944a2b..f1defde 100644
--- a/fxjs/xfa/cjx_object.cpp
+++ b/fxjs/xfa/cjx_object.cpp
@@ -1330,9 +1330,9 @@
     return;
   }
 
-  pValue->Assign(pIsolate,
-                 GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-                     pDataNode));
+  pValue->ForceSetValue(
+      pIsolate, GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+                    pDataNode));
 }
 
 void CJX_Object::ScriptSomMandatory(v8::Isolate* pIsolate,
diff --git a/fxjs/xfa/cjx_subform.cpp b/fxjs/xfa/cjx_subform.cpp
index 709be8a..4162b1d 100644
--- a/fxjs/xfa/cjx_subform.cpp
+++ b/fxjs/xfa/cjx_subform.cpp
@@ -129,7 +129,7 @@
     return;
   }
 
-  pValue->Assign(pIsolate,
-                 GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
-                     pInstanceMgr));
+  pValue->ForceSetValue(
+      pIsolate, GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+                    pInstanceMgr));
 }
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp
index d32c100..a074ad1 100644
--- a/fxjs/xfa/cjx_tree.cpp
+++ b/fxjs/xfa/cjx_tree.cpp
@@ -59,11 +59,9 @@
 
   if (resolveNodeRS.dwFlags == XFA_ResolveNodeRS::Type::kNodes) {
     CXFA_Object* pObject = resolveNodeRS.objects.front().Get();
-    CFXJSE_Value* value =
-        GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pObject);
-
     return CJS_Result::Success(
-        value->DirectGetValue().Get(runtime->GetIsolate()));
+        GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(
+            pObject));
   }
 
   if (!resolveNodeRS.script_attribute.callback ||
@@ -166,7 +164,7 @@
     return;
   }
 
-  pValue->Assign(
+  pValue->ForceSetValue(
       pIsolate,
       GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pParent));
 }
diff --git a/fxjs/xfa/cjx_treelist.cpp b/fxjs/xfa/cjx_treelist.cpp
index 151db82..b7727e1 100644
--- a/fxjs/xfa/cjx_treelist.cpp
+++ b/fxjs/xfa/cjx_treelist.cpp
@@ -43,9 +43,6 @@
   if (!pNode)
     return CJS_Result::Success();
 
-  CFXJSE_Value* value =
-      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode);
-
   return CJS_Result::Success(
-      value->DirectGetValue().Get(runtime->GetIsolate()));
+      GetDocument()->GetScriptContext()->GetOrCreateJSBindingFromMap(pNode));
 }
diff --git a/fxjs/xfa/cjx_xfa.cpp b/fxjs/xfa/cjx_xfa.cpp
index f107f76..88982dc 100644
--- a/fxjs/xfa/cjx_xfa.cpp
+++ b/fxjs/xfa/cjx_xfa.cpp
@@ -32,5 +32,6 @@
     pValue->SetNull(pIsolate);
     return;
   }
-  pValue->Assign(pIsolate, pScriptContext->GetOrCreateJSBindingFromMap(pThis));
+  pValue->ForceSetValue(pIsolate,
+                        pScriptContext->GetOrCreateJSBindingFromMap(pThis));
 }