Remove the CJS_EmbedObj template param from JSConstructor.

Each of the CJS_Objects can create their CJS_EmbedObj's internally and
we don't need to do it though the JSConstructor. This also removes the
need for the SetEmbedObj method in CJS_Object.

Change-Id: Ib0535ad922b370634fd1e622a04860a96c4f2825
Reviewed-on: https://pdfium-review.googlesource.com/25370
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: dsinclair <dsinclair@chromium.org>
diff --git a/fxjs/JS_Define.h b/fxjs/JS_Define.h
index 1c2410f..540746a 100644
--- a/fxjs/JS_Define.h
+++ b/fxjs/JS_Define.h
@@ -48,10 +48,9 @@
 // Rich JS classes provide constants, methods, properties, and the ability
 // to construct native object state.
 
-template <class T, class A>
+template <class T>
 static void JSConstructor(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) {
   auto pObj = pdfium::MakeUnique<T>(obj);
-  pObj->SetEmbedObject(pdfium::MakeUnique<A>(pObj.get()));
   pObj->InitInstance(static_cast<CJS_Runtime*>(pEngine));
   pEngine->SetObjectPrivate(obj, std::move(pObj));
 }
diff --git a/fxjs/cjs_annot.cpp b/fxjs/cjs_annot.cpp
index 100fa20..34084a9 100644
--- a/fxjs/cjs_annot.cpp
+++ b/fxjs/cjs_annot.cpp
@@ -34,13 +34,17 @@
 // static
 void CJS_Annot::DefineJSObjects(CFXJS_Engine* pEngine) {
   ObjDefnID = pEngine->DefineObj("Annot", FXJSOBJTYPE_DYNAMIC,
-                                 JSConstructor<CJS_Annot, Annot>, JSDestructor);
+                                 JSConstructor<CJS_Annot>, JSDestructor);
   DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
 }
 
+CJS_Annot::CJS_Annot(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<Annot>(this);
+}
+
 Annot::Annot(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
 
-Annot::~Annot() {}
+Annot::~Annot() = default;
 
 CJS_Return Annot::get_hidden(CJS_Runtime* pRuntime) {
   if (!m_pAnnot)
diff --git a/fxjs/cjs_annot.h b/fxjs/cjs_annot.h
index 18124f6..9f0d771 100644
--- a/fxjs/cjs_annot.h
+++ b/fxjs/cjs_annot.h
@@ -35,8 +35,8 @@
   static int GetObjDefnID();
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_Annot(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Annot() override {}
+  explicit CJS_Annot(v8::Local<v8::Object> pObject);
+  ~CJS_Annot() override = default;
 
   JS_STATIC_PROP(hidden, hidden, Annot);
   JS_STATIC_PROP(name, name, Annot);
diff --git a/fxjs/cjs_app.cpp b/fxjs/cjs_app.cpp
index 7d16cba..6a540f9 100644
--- a/fxjs/cjs_app.cpp
+++ b/fxjs/cjs_app.cpp
@@ -78,15 +78,19 @@
 // static
 void CJS_App::DefineJSObjects(CFXJS_Engine* pEngine) {
   ObjDefnID = pEngine->DefineObj("app", FXJSOBJTYPE_STATIC,
-                                 JSConstructor<CJS_App, app>, JSDestructor);
+                                 JSConstructor<CJS_App>, JSDestructor);
   DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
 }
 
+CJS_App::CJS_App(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<app>(this);
+}
+
 app::app(CJS_Object* pJSObject)
     : CJS_EmbedObj(pJSObject), m_bCalculate(true), m_bRuntimeHighLight(false) {}
 
-app::~app() {}
+app::~app() = default;
 
 CJS_Return app::get_active_docs(CJS_Runtime* pRuntime) {
   CJS_Document* pJSDocument = nullptr;
diff --git a/fxjs/cjs_app.h b/fxjs/cjs_app.h
index 703c705..33b61a0 100644
--- a/fxjs/cjs_app.h
+++ b/fxjs/cjs_app.h
@@ -122,8 +122,8 @@
  public:
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_App(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_App() override {}
+  explicit CJS_App(v8::Local<v8::Object> pObject);
+  ~CJS_App() override = default;
 
   JS_STATIC_PROP(activeDocs, active_docs, app);
   JS_STATIC_PROP(calculate, calculate, app);
diff --git a/fxjs/cjs_color.cpp b/fxjs/cjs_color.cpp
index cfef449..35747f9 100644
--- a/fxjs/cjs_color.cpp
+++ b/fxjs/cjs_color.cpp
@@ -36,11 +36,15 @@
 // static
 void CJS_Color::DefineJSObjects(CFXJS_Engine* pEngine) {
   ObjDefnID = pEngine->DefineObj("color", FXJSOBJTYPE_STATIC,
-                                 JSConstructor<CJS_Color, color>, JSDestructor);
+                                 JSConstructor<CJS_Color>, JSDestructor);
   DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
 }
 
+CJS_Color::CJS_Color(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<color>(this);
+}
+
 // static
 v8::Local<v8::Array> color::ConvertPWLColorToArray(CJS_Runtime* pRuntime,
                                                    const CFX_Color& color) {
diff --git a/fxjs/cjs_color.h b/fxjs/cjs_color.h
index 5f7c1e5..fab035d 100644
--- a/fxjs/cjs_color.h
+++ b/fxjs/cjs_color.h
@@ -87,8 +87,8 @@
  public:
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_Color(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Color() override {}
+  explicit CJS_Color(v8::Local<v8::Object> pObject);
+  ~CJS_Color() override = default;
 
   JS_STATIC_PROP(black, black, color);
   JS_STATIC_PROP(blue, blue, color);
diff --git a/fxjs/cjs_console.cpp b/fxjs/cjs_console.cpp
index f4158a9..2b4dd27 100644
--- a/fxjs/cjs_console.cpp
+++ b/fxjs/cjs_console.cpp
@@ -22,15 +22,18 @@
 
 // static
 void CJS_Console::DefineJSObjects(CFXJS_Engine* pEngine) {
-  ObjDefnID =
-      pEngine->DefineObj("console", FXJSOBJTYPE_STATIC,
-                         JSConstructor<CJS_Console, console>, JSDestructor);
+  ObjDefnID = pEngine->DefineObj("console", FXJSOBJTYPE_STATIC,
+                                 JSConstructor<CJS_Console>, JSDestructor);
   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
 }
 
+CJS_Console::CJS_Console(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<console>(this);
+}
+
 console::console(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
 
-console::~console() {}
+console::~console() = default;
 
 CJS_Return console::clear(CJS_Runtime* pRuntime,
                           const std::vector<v8::Local<v8::Value>>& params) {
diff --git a/fxjs/cjs_console.h b/fxjs/cjs_console.h
index 43a55bc..22c18de 100644
--- a/fxjs/cjs_console.h
+++ b/fxjs/cjs_console.h
@@ -31,8 +31,8 @@
  public:
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_Console(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Console() override {}
+  explicit CJS_Console(v8::Local<v8::Object> pObject);
+  ~CJS_Console() override = default;
 
   JS_STATIC_METHOD(clear, console);
   JS_STATIC_METHOD(hide, console);
diff --git a/fxjs/cjs_document.cpp b/fxjs/cjs_document.cpp
index e513ba0..f8bdecd 100644
--- a/fxjs/cjs_document.cpp
+++ b/fxjs/cjs_document.cpp
@@ -116,13 +116,17 @@
 
 // static
 void CJS_Document::DefineJSObjects(CFXJS_Engine* pEngine) {
-  ObjDefnID =
-      pEngine->DefineObj("Document", FXJSOBJTYPE_GLOBAL,
-                         JSConstructor<CJS_Document, Document>, JSDestructor);
+  ObjDefnID = pEngine->DefineObj("Document", FXJSOBJTYPE_GLOBAL,
+                                 JSConstructor<CJS_Document>, JSDestructor);
   DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
 }
 
+CJS_Document::CJS_Document(v8::Local<v8::Object> pObject)
+    : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<Document>(this);
+}
+
 void CJS_Document::InitInstance(IJS_Runtime* pIRuntime) {
   CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
   Document* pDoc = static_cast<Document*>(GetEmbedObject());
@@ -135,7 +139,7 @@
       m_cwBaseURL(L""),
       m_bDelay(false) {}
 
-Document::~Document() {}
+Document::~Document() = default;
 
 // The total number of fields in document.
 CJS_Return Document::get_num_fields(CJS_Runtime* pRuntime) {
diff --git a/fxjs/cjs_document.h b/fxjs/cjs_document.h
index 896522c..0b0a158 100644
--- a/fxjs/cjs_document.h
+++ b/fxjs/cjs_document.h
@@ -239,8 +239,8 @@
   static int GetObjDefnID();
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_Document(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Document() override {}
+  explicit CJS_Document(v8::Local<v8::Object> pObject);
+  ~CJS_Document() override = default;
 
   // CJS_Object
   void InitInstance(IJS_Runtime* pIRuntime) override;
diff --git a/fxjs/cjs_event.cpp b/fxjs/cjs_event.cpp
index 09b104a..7736f0d 100644
--- a/fxjs/cjs_event.cpp
+++ b/fxjs/cjs_event.cpp
@@ -39,13 +39,17 @@
 // static
 void CJS_Event::DefineJSObjects(CFXJS_Engine* pEngine) {
   ObjDefnID = pEngine->DefineObj("event", FXJSOBJTYPE_STATIC,
-                                 JSConstructor<CJS_Event, event>, JSDestructor);
+                                 JSConstructor<CJS_Event>, JSDestructor);
   DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
 }
 
+CJS_Event::CJS_Event(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<event>(this);
+}
+
 event::event(CJS_Object* pJsObject) : CJS_EmbedObj(pJsObject) {}
 
-event::~event() {}
+event::~event() = default;
 
 CJS_Return event::get_change(CJS_Runtime* pRuntime) {
   CJS_EventHandler* pEvent =
diff --git a/fxjs/cjs_event.h b/fxjs/cjs_event.h
index 4ae5fa2..fa8c40b 100644
--- a/fxjs/cjs_event.h
+++ b/fxjs/cjs_event.h
@@ -79,8 +79,8 @@
  public:
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_Event(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Event() override {}
+  explicit CJS_Event(v8::Local<v8::Object> pObject);
+  ~CJS_Event() override = default;
 
   JS_STATIC_PROP(change, change, event);
   JS_STATIC_PROP(changeEx, change_ex, event);
diff --git a/fxjs/cjs_field.cpp b/fxjs/cjs_field.cpp
index c8e4897..7882a85 100644
--- a/fxjs/cjs_field.cpp
+++ b/fxjs/cjs_field.cpp
@@ -165,11 +165,15 @@
 // static
 void CJS_Field::DefineJSObjects(CFXJS_Engine* pEngine) {
   ObjDefnID = pEngine->DefineObj("Field", FXJSOBJTYPE_DYNAMIC,
-                                 JSConstructor<CJS_Field, Field>, JSDestructor);
+                                 JSConstructor<CJS_Field>, JSDestructor);
   DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
 }
 
+CJS_Field::CJS_Field(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<Field>(this);
+}
+
 void CJS_Field::InitInstance(IJS_Runtime* pIRuntime) {}
 
 Field::Field(CJS_Object* pJSObject)
@@ -180,7 +184,7 @@
       m_bCanSet(false),
       m_bDelay(false) {}
 
-Field::~Field() {}
+Field::~Field() = default;
 
 // note: iControlNo = -1, means not a widget.
 void Field::ParseFieldName(const std::wstring& strFieldNameParsed,
diff --git a/fxjs/cjs_field.h b/fxjs/cjs_field.h
index 8116e07..7c470f5 100644
--- a/fxjs/cjs_field.h
+++ b/fxjs/cjs_field.h
@@ -344,8 +344,8 @@
   static int GetObjDefnID();
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_Field(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Field() override {}
+  explicit CJS_Field(v8::Local<v8::Object> pObject);
+  ~CJS_Field() override = default;
 
   void InitInstance(IJS_Runtime* pIRuntime) override;
 
diff --git a/fxjs/cjs_global.cpp b/fxjs/cjs_global.cpp
index 0326516..8816cf1 100644
--- a/fxjs/cjs_global.cpp
+++ b/fxjs/cjs_global.cpp
@@ -222,12 +222,15 @@
 // static
 void CJS_Global::DefineJSObjects(CFXJS_Engine* pEngine) {
   ObjDefnID = pEngine->DefineObj("global", FXJSOBJTYPE_STATIC,
-                                 JSConstructor<CJS_Global, JSGlobalAlternate>,
-                                 JSDestructor);
+                                 JSConstructor<CJS_Global>, JSDestructor);
   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
   DefineAllProperties(pEngine);
 }
 
+CJS_Global::CJS_Global(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<JSGlobalAlternate>(this);
+}
+
 void CJS_Global::InitInstance(IJS_Runtime* pIRuntime) {
   CJS_Runtime* pRuntime = static_cast<CJS_Runtime*>(pIRuntime);
   JSGlobalAlternate* pGlobal =
diff --git a/fxjs/cjs_global.h b/fxjs/cjs_global.h
index 203d6e9..719f4b4 100644
--- a/fxjs/cjs_global.h
+++ b/fxjs/cjs_global.h
@@ -28,8 +28,8 @@
   static void setPersistent_static(
       const v8::FunctionCallbackInfo<v8::Value>& info);
 
-  explicit CJS_Global(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Global() override {}
+  explicit CJS_Global(v8::Local<v8::Object> pObject);
+  ~CJS_Global() override = default;
 
   // CJS_Object
   void InitInstance(IJS_Runtime* pIRuntime) override;
diff --git a/fxjs/cjs_icon.cpp b/fxjs/cjs_icon.cpp
index 9a4b73b..69a6d45 100644
--- a/fxjs/cjs_icon.cpp
+++ b/fxjs/cjs_icon.cpp
@@ -19,14 +19,18 @@
 // static
 void CJS_Icon::DefineJSObjects(CFXJS_Engine* pEngine) {
   ObjDefnID = pEngine->DefineObj("Icon", FXJSOBJTYPE_DYNAMIC,
-                                 JSConstructor<CJS_Icon, Icon>, JSDestructor);
+                                 JSConstructor<CJS_Icon>, JSDestructor);
   DefineProps(pEngine, ObjDefnID, PropertySpecs, FX_ArraySize(PropertySpecs));
 }
 
+CJS_Icon::CJS_Icon(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<Icon>(this);
+}
+
 Icon::Icon(CJS_Object* pJSObject)
     : CJS_EmbedObj(pJSObject), m_swIconName(L"") {}
 
-Icon::~Icon() {}
+Icon::~Icon() = default;
 
 CJS_Return Icon::get_name(CJS_Runtime* pRuntime) {
   return CJS_Return(pRuntime->NewString(m_swIconName.c_str()));
diff --git a/fxjs/cjs_icon.h b/fxjs/cjs_icon.h
index 05b8438..3ded32f 100644
--- a/fxjs/cjs_icon.h
+++ b/fxjs/cjs_icon.h
@@ -29,8 +29,8 @@
   static int GetObjDefnID();
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_Icon(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Icon() override {}
+  explicit CJS_Icon(v8::Local<v8::Object> pObject);
+  ~CJS_Icon() override = default;
 
   JS_STATIC_PROP(name, name, Icon);
 
diff --git a/fxjs/cjs_object.h b/fxjs/cjs_object.h
index f4b0d29..67389f5 100644
--- a/fxjs/cjs_object.h
+++ b/fxjs/cjs_object.h
@@ -57,10 +57,6 @@
 
   v8::Local<v8::Object> ToV8Object() { return m_pV8Object.Get(m_pIsolate); }
 
-  // Takes ownership of |pObj|.
-  void SetEmbedObject(std::unique_ptr<CJS_EmbedObj> pObj) {
-    m_pEmbedObj = std::move(pObj);
-  }
   CJS_EmbedObj* GetEmbedObject() const { return m_pEmbedObj.get(); }
 
   v8::Isolate* GetIsolate() const { return m_pIsolate; }
diff --git a/fxjs/cjs_printparamsobj.cpp b/fxjs/cjs_printparamsobj.cpp
index 7d6a7ea..91d0220 100644
--- a/fxjs/cjs_printparamsobj.cpp
+++ b/fxjs/cjs_printparamsobj.cpp
@@ -15,9 +15,14 @@
 
 // static
 void CJS_PrintParamsObj::DefineJSObjects(CFXJS_Engine* pEngine) {
-  ObjDefnID = pEngine->DefineObj(
-      "PrintParamsObj", FXJSOBJTYPE_DYNAMIC,
-      JSConstructor<CJS_PrintParamsObj, PrintParamsObj>, JSDestructor);
+  ObjDefnID =
+      pEngine->DefineObj("PrintParamsObj", FXJSOBJTYPE_DYNAMIC,
+                         JSConstructor<CJS_PrintParamsObj>, JSDestructor);
+}
+
+CJS_PrintParamsObj::CJS_PrintParamsObj(v8::Local<v8::Object> pObject)
+    : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<PrintParamsObj>(this);
 }
 
 PrintParamsObj::PrintParamsObj(CJS_Object* pJSObject)
diff --git a/fxjs/cjs_printparamsobj.h b/fxjs/cjs_printparamsobj.h
index a0c91b0..aa2b365 100644
--- a/fxjs/cjs_printparamsobj.h
+++ b/fxjs/cjs_printparamsobj.h
@@ -30,9 +30,8 @@
   static int GetObjDefnID();
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_PrintParamsObj(v8::Local<v8::Object> pObject)
-      : CJS_Object(pObject) {}
-  ~CJS_PrintParamsObj() override {}
+  explicit CJS_PrintParamsObj(v8::Local<v8::Object> pObject);
+  ~CJS_PrintParamsObj() override = default;
 
  private:
   static int ObjDefnID;
diff --git a/fxjs/cjs_report.cpp b/fxjs/cjs_report.cpp
index 6af87a6..a5e5441 100644
--- a/fxjs/cjs_report.cpp
+++ b/fxjs/cjs_report.cpp
@@ -19,14 +19,18 @@
 
 // static
 void CJS_Report::DefineJSObjects(CFXJS_Engine* pEngine, FXJSOBJTYPE eObjType) {
-  ObjDefnID = pEngine->DefineObj(
-      "Report", eObjType, JSConstructor<CJS_Report, Report>, JSDestructor);
+  ObjDefnID = pEngine->DefineObj("Report", eObjType, JSConstructor<CJS_Report>,
+                                 JSDestructor);
   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
 }
 
+CJS_Report::CJS_Report(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<Report>(this);
+}
+
 Report::Report(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
 
-Report::~Report() {}
+Report::~Report() = default;
 
 CJS_Return Report::writeText(CJS_Runtime* pRuntime,
                              const std::vector<v8::Local<v8::Value>>& params) {
diff --git a/fxjs/cjs_report.h b/fxjs/cjs_report.h
index 50259ef..168df79 100644
--- a/fxjs/cjs_report.h
+++ b/fxjs/cjs_report.h
@@ -27,8 +27,8 @@
  public:
   static void DefineJSObjects(CFXJS_Engine* pEngine, FXJSOBJTYPE eObjType);
 
-  explicit CJS_Report(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Report() override {}
+  explicit CJS_Report(v8::Local<v8::Object> pObject);
+  ~CJS_Report() override = default;
 
   JS_STATIC_METHOD(save, Report)
   JS_STATIC_METHOD(writeText, Report);
diff --git a/fxjs/cjs_timerobj.cpp b/fxjs/cjs_timerobj.cpp
index d892e0b..172ee5c 100644
--- a/fxjs/cjs_timerobj.cpp
+++ b/fxjs/cjs_timerobj.cpp
@@ -17,15 +17,19 @@
 
 // static
 void CJS_TimerObj::DefineJSObjects(CFXJS_Engine* pEngine) {
-  ObjDefnID =
-      pEngine->DefineObj("TimerObj", FXJSOBJTYPE_DYNAMIC,
-                         JSConstructor<CJS_TimerObj, TimerObj>, JSDestructor);
+  ObjDefnID = pEngine->DefineObj("TimerObj", FXJSOBJTYPE_DYNAMIC,
+                                 JSConstructor<CJS_TimerObj>, JSDestructor);
+}
+
+CJS_TimerObj::CJS_TimerObj(v8::Local<v8::Object> pObject)
+    : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<TimerObj>(this);
 }
 
 TimerObj::TimerObj(CJS_Object* pJSObject)
     : CJS_EmbedObj(pJSObject), m_nTimerID(0) {}
 
-TimerObj::~TimerObj() {}
+TimerObj::~TimerObj() = default;
 
 void TimerObj::SetTimer(GlobalTimer* pTimer) {
   m_nTimerID = pTimer->GetTimerID();
diff --git a/fxjs/cjs_timerobj.h b/fxjs/cjs_timerobj.h
index be09555..b4938c4 100644
--- a/fxjs/cjs_timerobj.h
+++ b/fxjs/cjs_timerobj.h
@@ -28,8 +28,8 @@
   static int GetObjDefnID();
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_TimerObj(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_TimerObj() override {}
+  explicit CJS_TimerObj(v8::Local<v8::Object> pObject);
+  ~CJS_TimerObj() override = default;
 
  private:
   static int ObjDefnID;
diff --git a/fxjs/cjs_util.cpp b/fxjs/cjs_util.cpp
index b161ec7..db03dbd 100644
--- a/fxjs/cjs_util.cpp
+++ b/fxjs/cjs_util.cpp
@@ -69,13 +69,17 @@
 // static
 void CJS_Util::DefineJSObjects(CFXJS_Engine* pEngine) {
   ObjDefnID = pEngine->DefineObj("util", FXJSOBJTYPE_STATIC,
-                                 JSConstructor<CJS_Util, util>, JSDestructor);
+                                 JSConstructor<CJS_Util>, JSDestructor);
   DefineMethods(pEngine, ObjDefnID, MethodSpecs, FX_ArraySize(MethodSpecs));
 }
 
+CJS_Util::CJS_Util(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {
+  m_pEmbedObj = pdfium::MakeUnique<util>(this);
+}
+
 util::util(CJS_Object* pJSObject) : CJS_EmbedObj(pJSObject) {}
 
-util::~util() {}
+util::~util() = default;
 
 CJS_Return util::printf(CJS_Runtime* pRuntime,
                         const std::vector<v8::Local<v8::Value>>& params) {
diff --git a/fxjs/cjs_util.h b/fxjs/cjs_util.h
index cc2026d..1ed8405 100644
--- a/fxjs/cjs_util.h
+++ b/fxjs/cjs_util.h
@@ -46,8 +46,8 @@
  public:
   static void DefineJSObjects(CFXJS_Engine* pEngine);
 
-  explicit CJS_Util(v8::Local<v8::Object> pObject) : CJS_Object(pObject) {}
-  ~CJS_Util() override {}
+  explicit CJS_Util(v8::Local<v8::Object> pObject);
+  ~CJS_Util() override = default;
 
   JS_STATIC_METHOD(printd, util);
   JS_STATIC_METHOD(printf, util);