Introduce IJS_Runtime::ScopedEventContext helper class.

This proves that m_EventContextArray is, in fact, a stack.
Tidy one function by using AutoRestorer while at it.

Change-Id: I319538b4eadcd9ce83319aa73861635dd5eb8c36
Reviewed-on: https://pdfium-review.googlesource.com/33970
Reviewed-by: dsinclair <dsinclair@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/fxjs/cfxjse_engine.cpp b/fxjs/cfxjse_engine.cpp
index 90fcc31..2361a64 100644
--- a/fxjs/cfxjse_engine.cpp
+++ b/fxjs/cfxjse_engine.cpp
@@ -145,13 +145,10 @@
   }
   AutoRestorer<CXFA_Object*> nodeRestorer(&m_pThisObject);
   m_pThisObject = pThisObject;
+
   CFXJSE_Value* pValue = pThisObject ? GetJSValueFromMap(pThisObject) : nullptr;
-
-  IJS_EventContext* ctx = m_pSubordinateRuntime->NewEventContext();
-  bool ret = m_JsContext->ExecuteScript(btScript.c_str(), hRetValue, pValue);
-  m_pSubordinateRuntime->ReleaseEventContext(ctx);
-
-  return ret;
+  IJS_Runtime::ScopedEventContext ctx(m_pSubordinateRuntime.Get());
+  return m_JsContext->ExecuteScript(btScript.c_str(), hRetValue, pValue);
 }
 
 bool CFXJSE_Engine::QueryNodeByFlag(CXFA_Node* refNode,
diff --git a/fxjs/cjs_app.cpp b/fxjs/cjs_app.cpp
index 9ce8dc3..3f9244c 100644
--- a/fxjs/cjs_app.cpp
+++ b/fxjs/cjs_app.cpp
@@ -414,12 +414,12 @@
 }
 
 void CJS_App::RunJsScript(CJS_Runtime* pRuntime, const WideString& wsScript) {
-  if (!pRuntime->IsBlocking()) {
-    IJS_EventContext* pContext = pRuntime->NewEventContext();
-    pContext->OnExternal_Exec();
-    pContext->RunScript(wsScript);
-    pRuntime->ReleaseEventContext(pContext);
-  }
+  if (pRuntime->IsBlocking())
+    return;
+
+  IJS_Runtime::ScopedEventContext pContext(pRuntime);
+  pContext->OnExternal_Exec();
+  pContext->RunScript(wsScript);
 }
 
 CJS_Return CJS_App::goBack(CJS_Runtime* pRuntime,
diff --git a/fxjs/cjs_runtime.cpp b/fxjs/cjs_runtime.cpp
index 22dc904..a8640ea 100644
--- a/fxjs/cjs_runtime.cpp
+++ b/fxjs/cjs_runtime.cpp
@@ -80,9 +80,8 @@
   if (m_isolateManaged || FXJS_GlobalIsolateRefCount() == 0)
     DefineJSObjects();
 
-  IJS_EventContext* pContext = NewEventContext();
+  ScopedEventContext pContext(this);
   InitializeEngine();
-  ReleaseEventContext(pContext);
   SetFormFillEnvToDocument();
 }
 
@@ -153,11 +152,8 @@
 }
 
 void CJS_Runtime::ReleaseEventContext(IJS_EventContext* pContext) {
-  auto it = std::find(m_EventContextArray.begin(), m_EventContextArray.end(),
-                      pdfium::FakeUniquePtr<CJS_EventContext>(
-                          static_cast<CJS_EventContext*>(pContext)));
-  if (it != m_EventContextArray.end())
-    m_EventContextArray.erase(it);
+  ASSERT(pContext == m_EventContextArray.back().get());
+  m_EventContextArray.pop_back();
 }
 
 CJS_EventContext* CJS_Runtime::GetCurrentEventContext() const {
diff --git a/fxjs/ijs_runtime.h b/fxjs/ijs_runtime.h
index a21aae8..9f15aba 100644
--- a/fxjs/ijs_runtime.h
+++ b/fxjs/ijs_runtime.h
@@ -34,10 +34,26 @@
     JS_Error(int line, int column, const WideString& exception);
   };
 
+  class ScopedEventContext {
+   public:
+    explicit ScopedEventContext(IJS_Runtime* pRuntime)
+        : m_pRuntime(pRuntime), m_pContext(pRuntime->NewEventContext()) {}
+
+    ~ScopedEventContext() { m_pRuntime->ReleaseEventContext(m_pContext); }
+
+    IJS_EventContext* Get() const { return m_pContext; }
+    IJS_EventContext* operator->() const { return m_pContext; }
+
+   private:
+    IJS_Runtime* m_pRuntime;
+    IJS_EventContext* m_pContext;
+  };
+
   static void Initialize(unsigned int slot, void* isolate);
   static void Destroy();
   static std::unique_ptr<IJS_Runtime> Create(
       CPDFSDK_FormFillEnvironment* pFormFillEnv);
+
   virtual ~IJS_Runtime();
 
   virtual CJS_Runtime* AsCJSRuntime() = 0;