From 1b9e7fb4572a408eb82ebe660706ce2c4f8ef01b Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Mon, 5 Oct 2015 12:20:37 -0700 Subject: Fix v8 isolate initialization / release, M46 edition. BUG=531339,539106 R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1384223002 . --- fpdfsdk/include/javascript/JS_Runtime.h | 2 +- fpdfsdk/include/jsapi/fxjs_v8.h | 3 ++- fpdfsdk/src/javascript/JS_Runtime.cpp | 31 ++++++++++++++++++++----------- fpdfsdk/src/jsapi/fxjs_v8.cpp | 16 +++++++++++++--- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/fpdfsdk/include/javascript/JS_Runtime.h b/fpdfsdk/include/javascript/JS_Runtime.h index 0617597428..560d5035a2 100644 --- a/fpdfsdk/include/javascript/JS_Runtime.h +++ b/fpdfsdk/include/javascript/JS_Runtime.h @@ -40,7 +40,7 @@ class CJS_Runtime : public IFXJS_Runtime { virtual ~Observer() {} }; - CJS_Runtime(CPDFDoc_Environment* pApp); + CJS_Runtime(CPDFDoc_Environment* pApp, bool bInitJsObjects); ~CJS_Runtime() override; // IFXJS_Runtime diff --git a/fpdfsdk/include/jsapi/fxjs_v8.h b/fpdfsdk/include/jsapi/fxjs_v8.h index 72f2a5de01..6d9e4c0474 100644 --- a/fpdfsdk/include/jsapi/fxjs_v8.h +++ b/fpdfsdk/include/jsapi/fxjs_v8.h @@ -88,8 +88,9 @@ void JS_InitialRuntime(IJS_Runtime* pJSRuntime, IFXJS_Context* context, v8::Global& v8PersistentContext); void JS_ReleaseRuntime(IJS_Runtime* pJSRuntime, + bool bReleaseGlobal, v8::Global& v8PersistentContext); -void JS_Initial(unsigned int embedderDataSlot); +void JS_Initial(unsigned int embedderDataSlot, v8::Isolate* isolate); void JS_Release(); int JS_Parse(IJS_Runtime* pJSRuntime, IFXJS_Context* pJSContext, diff --git a/fpdfsdk/src/javascript/JS_Runtime.cpp b/fpdfsdk/src/javascript/JS_Runtime.cpp index 8efb277dd7..01bf9f2de0 100644 --- a/fpdfsdk/src/javascript/JS_Runtime.cpp +++ b/fpdfsdk/src/javascript/JS_Runtime.cpp @@ -26,23 +26,30 @@ #include "../../include/javascript/global.h" #include "../../include/javascript/console.h" +static bool g_only_one_js_runtime_left = false; + CJS_RuntimeFactory::~CJS_RuntimeFactory() {} IFXJS_Runtime* CJS_RuntimeFactory::NewJSRuntime(CPDFDoc_Environment* pApp) { + bool bInitJsObjects = false; if (!m_bInit) { unsigned int embedderDataSlot = 0; - if (pApp->GetFormFillInfo()->m_pJsPlatform->version >= 2) { - embedderDataSlot = - pApp->GetFormFillInfo()->m_pJsPlatform->m_v8EmbedderSlot; + v8::Isolate* isolate = nullptr; + IPDF_JSPLATFORM* pJsPlatform = pApp->GetFormFillInfo()->m_pJsPlatform; + if (pJsPlatform->version >= 2) { + embedderDataSlot = pJsPlatform->m_v8EmbedderSlot; + isolate = static_cast(pJsPlatform->m_isolate); } - JS_Initial(embedderDataSlot); + JS_Initial(embedderDataSlot, isolate); m_bInit = TRUE; + bInitJsObjects = true; } - return new CJS_Runtime(pApp); + return new CJS_Runtime(pApp, bInitJsObjects); } void CJS_RuntimeFactory::AddRef() { // to do.Should be implemented as atom manipulation. m_nRef++; + g_only_one_js_runtime_left = (m_nRef == 1); } void CJS_RuntimeFactory::Release() { if (m_bInit) { @@ -53,6 +60,7 @@ void CJS_RuntimeFactory::Release() { m_bInit = FALSE; } } + g_only_one_js_runtime_left = (m_nRef == 1); } void CJS_RuntimeFactory::DeleteJSRuntime(IFXJS_Runtime* pRuntime) { @@ -92,16 +100,16 @@ void CJS_ArrayBufferAllocator::Free(void* data, size_t length) { /* ------------------------------ CJS_Runtime ------------------------------ */ -CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp) +CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp, bool bInitJsObjects) : m_pApp(pApp), m_pDocument(NULL), m_bBlocking(FALSE), m_pFieldEventPath(NULL), m_isolate(NULL), m_isolateManaged(false) { - if (m_pApp->GetFormFillInfo()->m_pJsPlatform->version >= 2) { - m_isolate = reinterpret_cast( - m_pApp->GetFormFillInfo()->m_pJsPlatform->m_isolate); + IPDF_JSPLATFORM* pJsPlatform = pApp->GetFormFillInfo()->m_pJsPlatform; + if (pJsPlatform->version >= 2) { + m_isolate = static_cast(pJsPlatform->m_isolate); } if (!m_isolate) { m_pArrayBufferAllocator.reset(new CJS_ArrayBufferAllocator()); @@ -112,7 +120,8 @@ CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp) m_isolateManaged = true; } - InitJSObjects(); + if (m_isolateManaged || bInitJsObjects) + InitJSObjects(); CJS_Context* pContext = (CJS_Context*)NewContext(); JS_InitialRuntime(*this, this, pContext, m_context); @@ -128,7 +137,7 @@ CJS_Runtime::~CJS_Runtime() { m_ContextArray.RemoveAll(); - JS_ReleaseRuntime(*this, m_context); + JS_ReleaseRuntime(*this, g_only_one_js_runtime_left, m_context); RemoveEventsInLoop(m_pFieldEventPath); diff --git a/fpdfsdk/src/jsapi/fxjs_v8.cpp b/fpdfsdk/src/jsapi/fxjs_v8.cpp index ba65d30755..bcea3e14cd 100644 --- a/fpdfsdk/src/jsapi/fxjs_v8.cpp +++ b/fpdfsdk/src/jsapi/fxjs_v8.cpp @@ -26,6 +26,7 @@ static double GetNan() { return *(double*)g_nan; } static unsigned int g_embedderDataSlot = 0u; +static v8::Isolate* g_isolate = nullptr; class CJS_PrivateData { public: @@ -338,8 +339,12 @@ void JS_InitialRuntime(IJS_Runtime* pJSRuntime, } void JS_ReleaseRuntime(IJS_Runtime* pJSRuntime, + bool bReleaseGlobal, v8::Global& v8PersistentContext) { v8::Isolate* isolate = (v8::Isolate*)pJSRuntime; + if (isolate == g_isolate && !bReleaseGlobal) + return; + v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope handle_scope(isolate); v8::Local context = @@ -362,13 +367,18 @@ void JS_ReleaseRuntime(IJS_Runtime* pJSRuntime, delete pObjDef; } delete pArray; - isolate->SetData(g_embedderDataSlot, NULL); } -void JS_Initial(unsigned int embedderDataSlot) { +void JS_Initial(unsigned int embedderDataSlot, v8::Isolate* isolate) { g_embedderDataSlot = embedderDataSlot; + g_isolate = isolate; } -void JS_Release() {} +void JS_Release() { + g_isolate->SetData(g_embedderDataSlot, nullptr); + g_isolate = nullptr; + g_embedderDataSlot = 0; +} + int JS_Parse(IJS_Runtime* pJSRuntime, IFXJS_Context* pJSContext, const wchar_t* script, -- cgit v1.2.3