diff --git a/fxjs/cjs_global.cpp b/fxjs/cjs_global.cpp
new file mode 100644
index 0000000..c4a8edc
--- /dev/null
+++ b/fxjs/cjs_global.cpp
@@ -0,0 +1,614 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fxjs/cjs_global.h"
+
+#include <map>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "core/fxcrt/fx_extension.h"
+#include "fxjs/JS_Define.h"
+#include "fxjs/JS_GlobalData.h"
+#include "fxjs/JS_KeyValue.h"
+#include "fxjs/cjs_event_context.h"
+#include "fxjs/cjs_eventhandler.h"
+#include "fxjs/cjs_object.h"
+#include "fxjs/js_resources.h"
+
+namespace {
+
+WideString PropFromV8Prop(v8::Local<v8::String> property) {
+  v8::String::Utf8Value utf8_value(property);
+  return WideString::FromUTF8(ByteStringView(*utf8_value, utf8_value.length()));
+}
+
+template <class Alt>
+void JSSpecialPropQuery(const char*,
+                        v8::Local<v8::String> property,
+                        const v8::PropertyCallbackInfo<v8::Integer>& info) {
+  CJS_Runtime* pRuntime =
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
+  if (!pRuntime)
+    return;
+
+  CJS_Object* pJSObj =
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
+  if (!pJSObj)
+    return;
+
+  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
+  CJS_Return result = pObj->QueryProperty(PropFromV8Prop(property).c_str());
+  info.GetReturnValue().Set(!result.HasError() ? 4 : 0);
+}
+
+template <class Alt>
+void JSSpecialPropGet(const char* class_name,
+                      v8::Local<v8::String> property,
+                      const v8::PropertyCallbackInfo<v8::Value>& info) {
+  CJS_Runtime* pRuntime =
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
+  if (!pRuntime)
+    return;
+
+  CJS_Object* pJSObj =
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
+  if (!pJSObj)
+    return;
+
+  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
+  CJS_Return result =
+      pObj->GetProperty(pRuntime, PropFromV8Prop(property).c_str());
+  if (result.HasError()) {
+    pRuntime->Error(
+        JSFormatErrorString(class_name, "GetProperty", result.Error()));
+    return;
+  }
+
+  if (result.HasReturn())
+    info.GetReturnValue().Set(result.Return());
+}
+
+template <class Alt>
+void JSSpecialPropPut(const char* class_name,
+                      v8::Local<v8::String> property,
+                      v8::Local<v8::Value> value,
+                      const v8::PropertyCallbackInfo<v8::Value>& info) {
+  CJS_Runtime* pRuntime =
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
+  if (!pRuntime)
+    return;
+
+  CJS_Object* pJSObj =
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
+  if (!pJSObj)
+    return;
+
+  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
+  CJS_Return result =
+      pObj->SetProperty(pRuntime, PropFromV8Prop(property).c_str(), value);
+  if (result.HasError()) {
+    pRuntime->Error(
+        JSFormatErrorString(class_name, "PutProperty", result.Error()));
+  }
+}
+
+template <class Alt>
+void JSSpecialPropDel(const char* class_name,
+                      v8::Local<v8::String> property,
+                      const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+  CJS_Runtime* pRuntime =
+      CJS_Runtime::CurrentRuntimeFromIsolate(info.GetIsolate());
+  if (!pRuntime)
+    return;
+
+  CJS_Object* pJSObj =
+      static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(info.Holder()));
+  if (!pJSObj)
+    return;
+
+  Alt* pObj = reinterpret_cast<Alt*>(pJSObj->GetEmbedObject());
+  CJS_Return result =
+      pObj->DelProperty(pRuntime, PropFromV8Prop(property).c_str());
+  if (result.HasError()) {
+    // TODO(dsinclair): Should this set the pRuntime->Error result?
+    // ByteString cbName;
+    // cbName.Format("%s.%s", class_name, "DelProperty");
+  }
+}
+
+struct JSGlobalData {
+  JSGlobalData();
+  ~JSGlobalData();
+
+  JS_GlobalDataType nType;
+  double dData;
+  bool bData;
+  ByteString sData;
+  v8::Global<v8::Object> pData;
+  bool bPersistent;
+  bool bDeleted;
+};
+
+class JSGlobalAlternate : public CJS_EmbedObj {
+ public:
+  explicit JSGlobalAlternate(CJS_Object* pJSObject);
+  ~JSGlobalAlternate() override;
+
+  CJS_Return setPersistent(CJS_Runtime* pRuntime,
+                           const std::vector<v8::Local<v8::Value>>& params);
+  CJS_Return QueryProperty(const wchar_t* propname);
+  CJS_Return GetProperty(CJS_Runtime* pRuntime, const wchar_t* propname);
+  CJS_Return SetProperty(CJS_Runtime* pRuntime,
+                         const wchar_t* propname,
+                         v8::Local<v8::Value> vp);
+  CJS_Return DelProperty(CJS_Runtime* pRuntime, const wchar_t* propname);
+  void Initial(CPDFSDK_FormFillEnvironment* pFormFillEnv);
+
+ private:
+  void UpdateGlobalPersistentVariables();
+  void CommitGlobalPersisitentVariables(CJS_Runtime* pRuntime);
+  void DestroyGlobalPersisitentVariables();
+  CJS_Return SetGlobalVariables(const ByteString& propname,
+                                JS_GlobalDataType nType,
+                                double dData,
+                                bool bData,
+                                const ByteString& sData,
+                                v8::Local<v8::Object> pData,
+                                bool bDefaultPersistent);
+  void ObjectToArray(CJS_Runtime* pRuntime,
+                     v8::Local<v8::Object> pObj,
+                     CJS_GlobalVariableArray& array);
+  void PutObjectProperty(v8::Local<v8::Object> obj, CJS_KeyValue* pData);
+
+  std::map<ByteString, std::unique_ptr<JSGlobalData>> m_MapGlobal;
+  WideString m_sFilePath;
+  CJS_GlobalData* m_pGlobalData;
+  CPDFSDK_FormFillEnvironment::ObservedPtr m_pFormFillEnv;
+};
+
+}  // namespace
+
+const JSMethodSpec CJS_Global::MethodSpecs[] = {
+    {"setPersistent", setPersistent_static},
+    {0, 0}};
+
+int CJS_Global::ObjDefnID = -1;
+
+// static
+void CJS_Global::setPersistent_static(
+    const v8::FunctionCallbackInfo<v8::Value>& info) {
+  JSMethod<JSGlobalAlternate, &JSGlobalAlternate::setPersistent>(
+      "setPersistent", "global", info);
+}
+
+// static
+void CJS_Global::queryprop_static(
+    v8::Local<v8::String> property,
+    const v8::PropertyCallbackInfo<v8::Integer>& info) {
+  JSSpecialPropQuery<JSGlobalAlternate>("global", property, info);
+}
+
+// static
+void CJS_Global::getprop_static(
+    v8::Local<v8::String> property,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  JSSpecialPropGet<JSGlobalAlternate>("global", property, info);
+}
+
+// static
+void CJS_Global::putprop_static(
+    v8::Local<v8::String> property,
+    v8::Local<v8::Value> value,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
+  JSSpecialPropPut<JSGlobalAlternate>("global", property, value, info);
+}
+
+// static
+void CJS_Global::delprop_static(
+    v8::Local<v8::String> property,
+    const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+  JSSpecialPropDel<JSGlobalAlternate>("global", property, info);
+}
+
+// static
+void CJS_Global::DefineAllProperties(CFXJS_Engine* pEngine) {
+  pEngine->DefineObjAllProperties(
+      ObjDefnID, CJS_Global::queryprop_static, CJS_Global::getprop_static,
+      CJS_Global::putprop_static, CJS_Global::delprop_static);
+}
+
+// static
+void CJS_Global::DefineJSObjects(CFXJS_Engine* pEngine) {
+  ObjDefnID = pEngine->DefineObj("global", FXJSOBJTYPE_STATIC,
+                                 JSConstructor<CJS_Global, JSGlobalAlternate>,
+                                 JSDestructor<CJS_Global>);
+  DefineMethods(pEngine, ObjDefnID, MethodSpecs);
+  DefineAllProperties(pEngine);
+}
+
+void CJS_Global::InitInstance(IJS_Runtime* pIRuntime) {
+  CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
+  JSGlobalAlternate* pGlobal =
+      static_cast<JSGlobalAlternate*>(GetEmbedObject());
+  pGlobal->Initial(pRuntime->GetFormFillEnv());
+}
+
+JSGlobalData::JSGlobalData()
+    : nType(JS_GlobalDataType::NUMBER),
+      dData(0),
+      bData(false),
+      sData(""),
+      bPersistent(false),
+      bDeleted(false) {}
+
+JSGlobalData::~JSGlobalData() {
+  pData.Reset();
+}
+
+JSGlobalAlternate::JSGlobalAlternate(CJS_Object* pJSObject)
+    : CJS_EmbedObj(pJSObject), m_pFormFillEnv(nullptr) {}
+
+JSGlobalAlternate::~JSGlobalAlternate() {
+  DestroyGlobalPersisitentVariables();
+  m_pGlobalData->Release();
+}
+
+void JSGlobalAlternate::Initial(CPDFSDK_FormFillEnvironment* pFormFillEnv) {
+  m_pFormFillEnv.Reset(pFormFillEnv);
+  m_pGlobalData = CJS_GlobalData::GetRetainedInstance(pFormFillEnv);
+  UpdateGlobalPersistentVariables();
+}
+
+CJS_Return JSGlobalAlternate::QueryProperty(const wchar_t* propname) {
+  return CJS_Return(WideString(propname) != L"setPersistent");
+}
+
+CJS_Return JSGlobalAlternate::DelProperty(CJS_Runtime* pRuntime,
+                                          const wchar_t* propname) {
+  auto it = m_MapGlobal.find(ByteString::FromUnicode(propname));
+  if (it == m_MapGlobal.end())
+    return CJS_Return(false);
+
+  it->second->bDeleted = true;
+  return CJS_Return(true);
+}
+
+CJS_Return JSGlobalAlternate::GetProperty(CJS_Runtime* pRuntime,
+                                          const wchar_t* propname) {
+  auto it = m_MapGlobal.find(ByteString::FromUnicode(propname));
+  if (it == m_MapGlobal.end())
+    return CJS_Return(true);
+
+  JSGlobalData* pData = it->second.get();
+  if (pData->bDeleted)
+    return CJS_Return(true);
+
+  switch (pData->nType) {
+    case JS_GlobalDataType::NUMBER:
+      return CJS_Return(pRuntime->NewNumber(pData->dData));
+    case JS_GlobalDataType::BOOLEAN:
+      return CJS_Return(pRuntime->NewBoolean(pData->bData));
+    case JS_GlobalDataType::STRING:
+      return CJS_Return(pRuntime->NewString(
+          WideString::FromLocal(pData->sData.c_str()).c_str()));
+    case JS_GlobalDataType::OBJECT:
+      return CJS_Return(
+          v8::Local<v8::Object>::New(pRuntime->GetIsolate(), pData->pData));
+    case JS_GlobalDataType::NULLOBJ:
+      return CJS_Return(pRuntime->NewNull());
+    default:
+      break;
+  }
+  return CJS_Return(false);
+}
+
+CJS_Return JSGlobalAlternate::SetProperty(CJS_Runtime* pRuntime,
+                                          const wchar_t* propname,
+                                          v8::Local<v8::Value> vp) {
+  ByteString sPropName = ByteString::FromUnicode(propname);
+  if (vp->IsNumber()) {
+    return SetGlobalVariables(sPropName, JS_GlobalDataType::NUMBER,
+                              pRuntime->ToDouble(vp), false, "",
+                              v8::Local<v8::Object>(), false);
+  }
+  if (vp->IsBoolean()) {
+    return SetGlobalVariables(sPropName, JS_GlobalDataType::BOOLEAN, 0,
+                              pRuntime->ToBoolean(vp), "",
+                              v8::Local<v8::Object>(), false);
+  }
+  if (vp->IsString()) {
+    return SetGlobalVariables(
+        sPropName, JS_GlobalDataType::STRING, 0, false,
+        ByteString::FromUnicode(pRuntime->ToWideString(vp)),
+        v8::Local<v8::Object>(), false);
+  }
+  if (vp->IsObject()) {
+    return SetGlobalVariables(sPropName, JS_GlobalDataType::OBJECT, 0, false,
+                              "", pRuntime->ToObject(vp), false);
+  }
+  if (vp->IsNull()) {
+    return SetGlobalVariables(sPropName, JS_GlobalDataType::NULLOBJ, 0, false,
+                              "", v8::Local<v8::Object>(), false);
+  }
+  if (vp->IsUndefined()) {
+    DelProperty(pRuntime, propname);
+    return CJS_Return(true);
+  }
+  return CJS_Return(false);
+}
+
+CJS_Return JSGlobalAlternate::setPersistent(
+    CJS_Runtime* pRuntime,
+    const std::vector<v8::Local<v8::Value>>& params) {
+  if (params.size() != 2)
+    return CJS_Return(JSGetStringFromID(IDS_STRING_JSPARAMERROR));
+
+  auto it = m_MapGlobal.find(
+      ByteString::FromUnicode(pRuntime->ToWideString(params[0])));
+  if (it == m_MapGlobal.end() || it->second->bDeleted)
+    return CJS_Return(JSGetStringFromID(IDS_STRING_JSNOGLOBAL));
+
+  it->second->bPersistent = pRuntime->ToBoolean(params[1]);
+  return CJS_Return(true);
+}
+
+void JSGlobalAlternate::UpdateGlobalPersistentVariables() {
+  CJS_Runtime* pRuntime =
+      static_cast<CJS_Runtime*>(CFXJS_Engine::CurrentEngineFromIsolate(
+          m_pJSObject->ToV8Object()->GetIsolate()));
+
+  for (int i = 0, sz = m_pGlobalData->GetSize(); i < sz; i++) {
+    CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i);
+    switch (pData->data.nType) {
+      case JS_GlobalDataType::NUMBER:
+        SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::NUMBER,
+                           pData->data.dData, false, "",
+                           v8::Local<v8::Object>(), pData->bPersistent == 1);
+        pRuntime->PutObjectProperty(m_pJSObject->ToV8Object(),
+                                    pData->data.sKey.UTF8Decode(),
+                                    pRuntime->NewNumber(pData->data.dData));
+        break;
+      case JS_GlobalDataType::BOOLEAN:
+        SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::BOOLEAN, 0,
+                           pData->data.bData == 1, "", v8::Local<v8::Object>(),
+                           pData->bPersistent == 1);
+        pRuntime->PutObjectProperty(
+            m_pJSObject->ToV8Object(), pData->data.sKey.UTF8Decode(),
+            pRuntime->NewBoolean(pData->data.bData == 1));
+        break;
+      case JS_GlobalDataType::STRING:
+        SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::STRING, 0,
+                           false, pData->data.sData, v8::Local<v8::Object>(),
+                           pData->bPersistent == 1);
+        pRuntime->PutObjectProperty(
+            m_pJSObject->ToV8Object(), pData->data.sKey.UTF8Decode(),
+            pRuntime->NewString(pData->data.sData.UTF8Decode().AsStringView()));
+        break;
+      case JS_GlobalDataType::OBJECT: {
+        v8::Local<v8::Object> pObj = pRuntime->NewFxDynamicObj(-1);
+        if (!pObj.IsEmpty()) {
+          PutObjectProperty(pObj, &pData->data);
+          SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::OBJECT, 0,
+                             false, "", pObj, pData->bPersistent == 1);
+          pRuntime->PutObjectProperty(m_pJSObject->ToV8Object(),
+                                      pData->data.sKey.UTF8Decode(), pObj);
+        }
+      } break;
+      case JS_GlobalDataType::NULLOBJ:
+        SetGlobalVariables(pData->data.sKey, JS_GlobalDataType::NULLOBJ, 0,
+                           false, "", v8::Local<v8::Object>(),
+                           pData->bPersistent == 1);
+        pRuntime->PutObjectProperty(m_pJSObject->ToV8Object(),
+                                    pData->data.sKey.UTF8Decode(),
+                                    pRuntime->NewNull());
+        break;
+    }
+  }
+}
+
+void JSGlobalAlternate::CommitGlobalPersisitentVariables(
+    CJS_Runtime* pRuntime) {
+  for (const auto& iter : m_MapGlobal) {
+    ByteString name = iter.first;
+    JSGlobalData* pData = iter.second.get();
+    if (pData->bDeleted) {
+      m_pGlobalData->DeleteGlobalVariable(name);
+      continue;
+    }
+    switch (pData->nType) {
+      case JS_GlobalDataType::NUMBER:
+        m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
+        m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+        break;
+      case JS_GlobalDataType::BOOLEAN:
+        m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
+        m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+        break;
+      case JS_GlobalDataType::STRING:
+        m_pGlobalData->SetGlobalVariableString(name, pData->sData);
+        m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+        break;
+      case JS_GlobalDataType::OBJECT: {
+        CJS_GlobalVariableArray array;
+        v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(
+            GetJSObject()->GetIsolate(), pData->pData);
+        ObjectToArray(pRuntime, obj, array);
+        m_pGlobalData->SetGlobalVariableObject(name, array);
+        m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+      } break;
+      case JS_GlobalDataType::NULLOBJ:
+        m_pGlobalData->SetGlobalVariableNull(name);
+        m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
+        break;
+    }
+  }
+}
+
+void JSGlobalAlternate::ObjectToArray(CJS_Runtime* pRuntime,
+                                      v8::Local<v8::Object> pObj,
+                                      CJS_GlobalVariableArray& array) {
+  std::vector<WideString> pKeyList = pRuntime->GetObjectPropertyNames(pObj);
+  for (const auto& ws : pKeyList) {
+    ByteString sKey = ws.UTF8Encode();
+    v8::Local<v8::Value> v = pRuntime->GetObjectProperty(pObj, ws);
+    if (v->IsNumber()) {
+      CJS_KeyValue* pObjElement = new CJS_KeyValue;
+      pObjElement->nType = JS_GlobalDataType::NUMBER;
+      pObjElement->sKey = sKey;
+      pObjElement->dData = pRuntime->ToDouble(v);
+      array.Add(pObjElement);
+      continue;
+    }
+    if (v->IsBoolean()) {
+      CJS_KeyValue* pObjElement = new CJS_KeyValue;
+      pObjElement->nType = JS_GlobalDataType::BOOLEAN;
+      pObjElement->sKey = sKey;
+      pObjElement->dData = pRuntime->ToBoolean(v);
+      array.Add(pObjElement);
+      continue;
+    }
+    if (v->IsString()) {
+      ByteString sValue = ByteString::FromUnicode(pRuntime->ToWideString(v));
+      CJS_KeyValue* pObjElement = new CJS_KeyValue;
+      pObjElement->nType = JS_GlobalDataType::STRING;
+      pObjElement->sKey = sKey;
+      pObjElement->sData = sValue;
+      array.Add(pObjElement);
+      continue;
+    }
+    if (v->IsObject()) {
+      CJS_KeyValue* pObjElement = new CJS_KeyValue;
+      pObjElement->nType = JS_GlobalDataType::OBJECT;
+      pObjElement->sKey = sKey;
+      ObjectToArray(pRuntime, pRuntime->ToObject(v), pObjElement->objData);
+      array.Add(pObjElement);
+      continue;
+    }
+    if (v->IsNull()) {
+      CJS_KeyValue* pObjElement = new CJS_KeyValue;
+      pObjElement->nType = JS_GlobalDataType::NULLOBJ;
+      pObjElement->sKey = sKey;
+      array.Add(pObjElement);
+    }
+  }
+}
+
+void JSGlobalAlternate::PutObjectProperty(v8::Local<v8::Object> pObj,
+                                          CJS_KeyValue* pData) {
+  CJS_Runtime* pRuntime = CJS_Runtime::CurrentRuntimeFromIsolate(
+      m_pJSObject->ToV8Object()->GetIsolate());
+
+  for (int i = 0, sz = pData->objData.Count(); i < sz; i++) {
+    CJS_KeyValue* pObjData = pData->objData.GetAt(i);
+    switch (pObjData->nType) {
+      case JS_GlobalDataType::NUMBER:
+        pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(),
+                                    pRuntime->NewNumber(pObjData->dData));
+        break;
+      case JS_GlobalDataType::BOOLEAN:
+        pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(),
+                                    pRuntime->NewBoolean(pObjData->bData == 1));
+        break;
+      case JS_GlobalDataType::STRING:
+        pRuntime->PutObjectProperty(
+            pObj, pObjData->sKey.UTF8Decode(),
+            pRuntime->NewString(pObjData->sData.UTF8Decode().AsStringView()));
+        break;
+      case JS_GlobalDataType::OBJECT: {
+        v8::Local<v8::Object> pNewObj = pRuntime->NewFxDynamicObj(-1);
+        if (!pNewObj.IsEmpty()) {
+          PutObjectProperty(pNewObj, pObjData);
+          pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(),
+                                      pNewObj);
+        }
+      } break;
+      case JS_GlobalDataType::NULLOBJ:
+        pRuntime->PutObjectProperty(pObj, pObjData->sKey.UTF8Decode(),
+                                    pRuntime->NewNull());
+        break;
+    }
+  }
+}
+
+void JSGlobalAlternate::DestroyGlobalPersisitentVariables() {
+  m_MapGlobal.clear();
+}
+
+CJS_Return JSGlobalAlternate::SetGlobalVariables(const ByteString& propname,
+                                                 JS_GlobalDataType nType,
+                                                 double dData,
+                                                 bool bData,
+                                                 const ByteString& sData,
+                                                 v8::Local<v8::Object> pData,
+                                                 bool bDefaultPersistent) {
+  if (propname.IsEmpty())
+    return CJS_Return(false);
+
+  auto it = m_MapGlobal.find(propname);
+  if (it != m_MapGlobal.end()) {
+    JSGlobalData* pTemp = it->second.get();
+    if (pTemp->bDeleted || pTemp->nType != nType) {
+      pTemp->dData = 0;
+      pTemp->bData = 0;
+      pTemp->sData = "";
+      pTemp->nType = nType;
+    }
+    pTemp->bDeleted = false;
+    switch (nType) {
+      case JS_GlobalDataType::NUMBER:
+        pTemp->dData = dData;
+        break;
+      case JS_GlobalDataType::BOOLEAN:
+        pTemp->bData = bData;
+        break;
+      case JS_GlobalDataType::STRING:
+        pTemp->sData = sData;
+        break;
+      case JS_GlobalDataType::OBJECT:
+        pTemp->pData.Reset(pData->GetIsolate(), pData);
+        break;
+      case JS_GlobalDataType::NULLOBJ:
+        break;
+      default:
+        return CJS_Return(false);
+    }
+    return CJS_Return(true);
+  }
+
+  auto pNewData = pdfium::MakeUnique<JSGlobalData>();
+  switch (nType) {
+    case JS_GlobalDataType::NUMBER:
+      pNewData->nType = JS_GlobalDataType::NUMBER;
+      pNewData->dData = dData;
+      pNewData->bPersistent = bDefaultPersistent;
+      break;
+    case JS_GlobalDataType::BOOLEAN:
+      pNewData->nType = JS_GlobalDataType::BOOLEAN;
+      pNewData->bData = bData;
+      pNewData->bPersistent = bDefaultPersistent;
+      break;
+    case JS_GlobalDataType::STRING:
+      pNewData->nType = JS_GlobalDataType::STRING;
+      pNewData->sData = sData;
+      pNewData->bPersistent = bDefaultPersistent;
+      break;
+    case JS_GlobalDataType::OBJECT:
+      pNewData->nType = JS_GlobalDataType::OBJECT;
+      pNewData->pData.Reset(pData->GetIsolate(), pData);
+      pNewData->bPersistent = bDefaultPersistent;
+      break;
+    case JS_GlobalDataType::NULLOBJ:
+      pNewData->nType = JS_GlobalDataType::NULLOBJ;
+      pNewData->bPersistent = bDefaultPersistent;
+      break;
+    default:
+      return CJS_Return(false);
+  }
+  m_MapGlobal[propname] = std::move(pNewData);
+  return CJS_Return(true);
+}
