From 98b356a36bc9291a4f222d092afeeea0d5b5f379 Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Mon, 16 Jul 2018 21:35:06 +0000 Subject: Use UnownedPtr<> to v8::Isolates. Isolates are long-lived, but this may catch a few things. Introduce CFX_V8IsolateDeleter for unique_ptr usage. Fix Dispose()/SetIsolate(nullptr) ordering in cjs_runtime.cpp Remove one unused isolate member. Flip protected -> private in one place. Change-Id: I26cdd120f799192e93b0d9d04dcde8f348dc21f3 Reviewed-on: https://pdfium-review.googlesource.com/37931 Reviewed-by: Lei Zhang Commit-Queue: Tom Sepez --- fxjs/cfx_v8.cpp | 55 ++++++----- fxjs/cfx_v8.h | 12 ++- fxjs/cfxjs_engine.cpp | 18 ++-- fxjs/cfxjse_context.cpp | 28 +++--- fxjs/cfxjse_context.h | 7 +- fxjs/cfxjse_formcalc_context.h | 5 +- fxjs/cfxjse_runtimedata.cpp | 8 +- fxjs/cfxjse_runtimedata.h | 4 +- fxjs/cfxjse_value.cpp | 202 ++++++++++++++++++++++------------------- fxjs/cfxjse_value.h | 9 +- fxjs/cjs_runtime.cpp | 6 +- testing/js_embedder_test.cpp | 19 ++-- testing/js_embedder_test.h | 7 +- 13 files changed, 203 insertions(+), 177 deletions(-) diff --git a/fxjs/cfx_v8.cpp b/fxjs/cfx_v8.cpp index 4738030236..1d2dd94e27 100644 --- a/fxjs/cfx_v8.cpp +++ b/fxjs/cfx_v8.cpp @@ -9,7 +9,7 @@ #include "core/fxcrt/fx_memory.h" #include "third_party/base/allocator/partition_allocator/partition_alloc.h" -CFX_V8::CFX_V8(v8::Isolate* isolate) : m_isolate(isolate) {} +CFX_V8::CFX_V8(v8::Isolate* isolate) : m_pIsolate(isolate) {} CFX_V8::~CFX_V8() = default; @@ -19,7 +19,7 @@ v8::Local CFX_V8::GetObjectProperty( if (pObj.IsEmpty()) return v8::Local(); v8::Local val; - if (!pObj->Get(m_isolate->GetCurrentContext(), + if (!pObj->Get(m_pIsolate->GetCurrentContext(), NewString(wsPropertyName.AsStringView())) .ToLocal(&val)) return v8::Local(); @@ -32,7 +32,7 @@ std::vector CFX_V8::GetObjectPropertyNames( return std::vector(); v8::Local val; - v8::Local context = m_isolate->GetCurrentContext(); + v8::Local context = m_pIsolate->GetCurrentContext(); if (!pObj->GetPropertyNames(context).ToLocal(&val)) return std::vector(); @@ -49,17 +49,22 @@ void CFX_V8::PutObjectProperty(v8::Local pObj, v8::Local pPut) { if (pObj.IsEmpty()) return; - pObj->Set(m_isolate->GetCurrentContext(), + pObj->Set(m_pIsolate->GetCurrentContext(), NewString(wsPropertyName.AsStringView()), pPut) .FromJust(); } +void CFX_V8::DisposeIsolate() { + if (m_pIsolate) + m_pIsolate.Release()->Dispose(); +} + v8::Local CFX_V8::NewArray() { - return v8::Array::New(m_isolate); + return v8::Array::New(GetIsolate()); } v8::Local CFX_V8::NewObject() { - return v8::Object::New(m_isolate); + return v8::Object::New(GetIsolate()); } unsigned CFX_V8::PutArrayElement(v8::Local pArray, @@ -67,7 +72,7 @@ unsigned CFX_V8::PutArrayElement(v8::Local pArray, v8::Local pValue) { if (pArray.IsEmpty()) return 0; - if (pArray->Set(m_isolate->GetCurrentContext(), index, pValue).IsNothing()) + if (pArray->Set(m_pIsolate->GetCurrentContext(), index, pValue).IsNothing()) return 0; return 1; } @@ -77,7 +82,7 @@ v8::Local CFX_V8::GetArrayElement(v8::Local pArray, if (pArray.IsEmpty()) return v8::Local(); v8::Local val; - if (!pArray->Get(m_isolate->GetCurrentContext(), index).ToLocal(&val)) + if (!pArray->Get(m_pIsolate->GetCurrentContext(), index).ToLocal(&val)) return v8::Local(); return val; } @@ -89,23 +94,23 @@ unsigned CFX_V8::GetArrayLength(v8::Local pArray) { } v8::Local CFX_V8::NewNumber(int number) { - return v8::Int32::New(m_isolate, number); + return v8::Int32::New(GetIsolate(), number); } v8::Local CFX_V8::NewNumber(double number) { - return v8::Number::New(m_isolate, number); + return v8::Number::New(GetIsolate(), number); } v8::Local CFX_V8::NewNumber(float number) { - return v8::Number::New(m_isolate, (float)number); + return v8::Number::New(GetIsolate(), (float)number); } v8::Local CFX_V8::NewBoolean(bool b) { - return v8::Boolean::New(m_isolate, b); + return v8::Boolean::New(GetIsolate(), b); } v8::Local CFX_V8::NewString(const ByteStringView& str) { - v8::Isolate* pIsolate = m_isolate ? m_isolate : v8::Isolate::GetCurrent(); + v8::Isolate* pIsolate = m_pIsolate ? GetIsolate() : v8::Isolate::GetCurrent(); return v8::String::NewFromUtf8(pIsolate, str.unterminated_c_str(), v8::NewStringType::kNormal, str.GetLength()) .ToLocalChecked(); @@ -119,15 +124,15 @@ v8::Local CFX_V8::NewString(const WideStringView& str) { } v8::Local CFX_V8::NewNull() { - return v8::Null(m_isolate); + return v8::Null(GetIsolate()); } v8::Local CFX_V8::NewUndefined() { - return v8::Undefined(m_isolate); + return v8::Undefined(GetIsolate()); } v8::Local CFX_V8::NewDate(double d) { - return v8::Date::New(m_isolate->GetCurrentContext(), d) + return v8::Date::New(m_pIsolate->GetCurrentContext(), d) .ToLocalChecked() .As(); } @@ -135,7 +140,7 @@ v8::Local CFX_V8::NewDate(double d) { int CFX_V8::ToInt32(v8::Local pValue) { if (pValue.IsEmpty()) return 0; - v8::Local context = m_isolate->GetCurrentContext(); + v8::Local context = m_pIsolate->GetCurrentContext(); v8::MaybeLocal maybe_int32 = pValue->ToInt32(context); if (maybe_int32.IsEmpty()) return 0; @@ -145,7 +150,7 @@ int CFX_V8::ToInt32(v8::Local pValue) { bool CFX_V8::ToBoolean(v8::Local pValue) { if (pValue.IsEmpty()) return false; - v8::Local context = m_isolate->GetCurrentContext(); + v8::Local context = m_pIsolate->GetCurrentContext(); v8::MaybeLocal maybe_boolean = pValue->ToBoolean(context); if (maybe_boolean.IsEmpty()) return false; @@ -155,7 +160,7 @@ bool CFX_V8::ToBoolean(v8::Local pValue) { double CFX_V8::ToDouble(v8::Local pValue) { if (pValue.IsEmpty()) return 0.0; - v8::Local context = m_isolate->GetCurrentContext(); + v8::Local context = m_pIsolate->GetCurrentContext(); v8::MaybeLocal maybe_number = pValue->ToNumber(context); if (maybe_number.IsEmpty()) return 0.0; @@ -165,36 +170,36 @@ double CFX_V8::ToDouble(v8::Local pValue) { WideString CFX_V8::ToWideString(v8::Local pValue) { if (pValue.IsEmpty()) return WideString(); - v8::Local context = m_isolate->GetCurrentContext(); + v8::Local context = m_pIsolate->GetCurrentContext(); v8::MaybeLocal maybe_string = pValue->ToString(context); if (maybe_string.IsEmpty()) return WideString(); - v8::String::Utf8Value s(m_isolate, maybe_string.ToLocalChecked()); + v8::String::Utf8Value s(GetIsolate(), maybe_string.ToLocalChecked()); return WideString::FromUTF8(ByteStringView(*s, s.length())); } ByteString CFX_V8::ToByteString(v8::Local pValue) { if (pValue.IsEmpty()) return ByteString(); - v8::Local context = m_isolate->GetCurrentContext(); + v8::Local context = m_pIsolate->GetCurrentContext(); v8::MaybeLocal maybe_string = pValue->ToString(context); if (maybe_string.IsEmpty()) return ByteString(); - v8::String::Utf8Value s(m_isolate, maybe_string.ToLocalChecked()); + v8::String::Utf8Value s(GetIsolate(), maybe_string.ToLocalChecked()); return ByteString(*s); } v8::Local CFX_V8::ToObject(v8::Local pValue) { if (pValue.IsEmpty() || !pValue->IsObject()) return v8::Local(); - v8::Local context = m_isolate->GetCurrentContext(); + v8::Local context = m_pIsolate->GetCurrentContext(); return pValue->ToObject(context).ToLocalChecked(); } v8::Local CFX_V8::ToArray(v8::Local pValue) { if (pValue.IsEmpty() || !pValue->IsArray()) return v8::Local(); - v8::Local context = m_isolate->GetCurrentContext(); + v8::Local context = m_pIsolate->GetCurrentContext(); return v8::Local::Cast(pValue->ToObject(context).ToLocalChecked()); } diff --git a/fxjs/cfx_v8.h b/fxjs/cfx_v8.h index 08a18935ea..04468d5281 100644 --- a/fxjs/cfx_v8.h +++ b/fxjs/cfx_v8.h @@ -20,7 +20,7 @@ class CFX_V8 { explicit CFX_V8(v8::Isolate* pIsolate); virtual ~CFX_V8(); - v8::Isolate* GetIsolate() const { return m_isolate; } + v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); } v8::Local NewNull(); v8::Local NewUndefined(); @@ -59,10 +59,11 @@ class CFX_V8 { v8::Local pValue); protected: - void SetIsolate(v8::Isolate* pIsolate) { m_isolate = pIsolate; } + void SetIsolate(v8::Isolate* pIsolate) { m_pIsolate = pIsolate; } + void DisposeIsolate(); private: - v8::Isolate* m_isolate; + UnownedPtr m_pIsolate; }; class CFX_V8ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { @@ -72,4 +73,9 @@ class CFX_V8ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { void Free(void* data, size_t length) override; }; +// Use with std::unique_ptr to dispose of isolates correctly. +struct CFX_V8IsolateDeleter { + inline void operator()(v8::Isolate* ptr) { ptr->Dispose(); } +}; + #endif // FXJS_CFX_V8_H_ diff --git a/fxjs/cfxjs_engine.cpp b/fxjs/cfxjs_engine.cpp index 0978bee7c1..1a02ec9a78 100644 --- a/fxjs/cfxjs_engine.cpp +++ b/fxjs/cfxjs_engine.cpp @@ -10,6 +10,7 @@ #include #include +#include "core/fxcrt/unowned_ptr.h" #include "fxjs/cfxjse_runtimedata.h" #include "fxjs/cjs_object.h" @@ -143,8 +144,10 @@ class CFXJS_ObjDefinition { m_Signature.Reset(isolate, sig); } + v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); } + void DefineConst(const char* sConstName, v8::Local pDefault) { - GetInstanceTemplate()->Set(m_pIsolate, sConstName, pDefault); + GetInstanceTemplate()->Set(GetIsolate(), sConstName, pDefault); } void DefineProperty(v8::Local sPropName, @@ -156,7 +159,7 @@ class CFXJS_ObjDefinition { void DefineMethod(v8::Local sMethodName, v8::FunctionCallback pMethodCall) { v8::Local fun = v8::FunctionTemplate::New( - m_pIsolate, pMethodCall, v8::Local(), GetSignature()); + GetIsolate(), pMethodCall, v8::Local(), GetSignature()); fun->RemovePrototype(); GetInstanceTemplate()->Set(sMethodName, fun, v8::ReadOnly); } @@ -172,23 +175,22 @@ class CFXJS_ObjDefinition { } v8::Local GetInstanceTemplate() { - v8::EscapableHandleScope scope(m_pIsolate); + v8::EscapableHandleScope scope(GetIsolate()); v8::Local function = - m_FunctionTemplate.Get(m_pIsolate); + m_FunctionTemplate.Get(GetIsolate()); return scope.Escape(function->InstanceTemplate()); } v8::Local GetSignature() { - v8::EscapableHandleScope scope(m_pIsolate); - return scope.Escape(m_Signature.Get(m_pIsolate)); + v8::EscapableHandleScope scope(GetIsolate()); + return scope.Escape(m_Signature.Get(GetIsolate())); } const char* const m_ObjName; const FXJSOBJTYPE m_ObjType; const CFXJS_Engine::Constructor m_pConstructor; const CFXJS_Engine::Destructor m_pDestructor; - - v8::Isolate* m_pIsolate; + UnownedPtr m_pIsolate; v8::Global m_FunctionTemplate; v8::Global m_Signature; }; diff --git a/fxjs/cfxjse_context.cpp b/fxjs/cfxjse_context.cpp index 7ee561095b..32fdd60cda 100644 --- a/fxjs/cfxjse_context.cpp +++ b/fxjs/cfxjse_context.cpp @@ -198,10 +198,10 @@ CFXJSE_Context::CFXJSE_Context(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {} CFXJSE_Context::~CFXJSE_Context() {} std::unique_ptr CFXJSE_Context::GetGlobalObject() { - auto pValue = pdfium::MakeUnique(m_pIsolate); + auto pValue = pdfium::MakeUnique(GetIsolate()); CFXJSE_ScopeUtil_IsolateHandleContext scope(this); v8::Local hContext = - v8::Local::New(m_pIsolate, m_hContext); + v8::Local::New(GetIsolate(), m_hContext); v8::Local hGlobalObject = hContext->Global()->GetPrototype().As(); pValue->ForceSetValue(hGlobalObject); @@ -209,7 +209,7 @@ std::unique_ptr CFXJSE_Context::GetGlobalObject() { } v8::Local CFXJSE_Context::GetContext() { - return v8::Local::New(m_pIsolate, m_hContext); + return v8::Local::New(GetIsolate(), m_hContext); } void CFXJSE_Context::AddClass(std::unique_ptr pClass) { @@ -234,10 +234,10 @@ bool CFXJSE_Context::ExecuteScript(const char* szScript, CFXJSE_Value* lpRetValue, CFXJSE_Value* lpNewThisObject) { CFXJSE_ScopeUtil_IsolateHandleContext scope(this); - v8::Local hContext = m_pIsolate->GetCurrentContext(); - v8::TryCatch trycatch(m_pIsolate); + v8::Local hContext = GetIsolate()->GetCurrentContext(); + v8::TryCatch trycatch(GetIsolate()); v8::Local hScriptString = - v8::String::NewFromUtf8(m_pIsolate, szScript); + v8::String::NewFromUtf8(GetIsolate(), szScript); if (!lpNewThisObject) { v8::Local hScript; if (v8::Script::Compile(hContext, hScriptString).ToLocal(&hScript)) { @@ -246,25 +246,25 @@ bool CFXJSE_Context::ExecuteScript(const char* szScript, if (hScript->Run(hContext).ToLocal(&hValue)) { ASSERT(!trycatch.HasCaught()); if (lpRetValue) - lpRetValue->m_hValue.Reset(m_pIsolate, hValue); + lpRetValue->m_hValue.Reset(GetIsolate(), hValue); return true; } } if (lpRetValue) { - lpRetValue->m_hValue.Reset(m_pIsolate, - CreateReturnValue(m_pIsolate, trycatch)); + lpRetValue->m_hValue.Reset(GetIsolate(), + CreateReturnValue(GetIsolate(), trycatch)); } return false; } v8::Local hNewThis = - v8::Local::New(m_pIsolate, lpNewThisObject->m_hValue); + v8::Local::New(GetIsolate(), lpNewThisObject->m_hValue); ASSERT(!hNewThis.IsEmpty()); v8::Local hWrapper = v8::Script::Compile( hContext, v8::String::NewFromUtf8( - m_pIsolate, "(function () { return eval(arguments[0]); })")) + GetIsolate(), "(function () { return eval(arguments[0]); })")) .ToLocalChecked(); v8::Local hWrapperValue; if (hWrapper->Run(hContext).ToLocal(&hWrapperValue)) { @@ -276,7 +276,7 @@ bool CFXJSE_Context::ExecuteScript(const char* szScript, .ToLocal(&hValue)) { ASSERT(!trycatch.HasCaught()); if (lpRetValue) - lpRetValue->m_hValue.Reset(m_pIsolate, hValue); + lpRetValue->m_hValue.Reset(GetIsolate(), hValue); return true; } @@ -297,8 +297,8 @@ bool CFXJSE_Context::ExecuteScript(const char* szScript, #endif // NDEBUG if (lpRetValue) { - lpRetValue->m_hValue.Reset(m_pIsolate, - CreateReturnValue(m_pIsolate, trycatch)); + lpRetValue->m_hValue.Reset(GetIsolate(), + CreateReturnValue(GetIsolate(), trycatch)); } return false; } diff --git a/fxjs/cfxjse_context.h b/fxjs/cfxjse_context.h index b4db8f7a30..91c76d4c7a 100644 --- a/fxjs/cfxjse_context.h +++ b/fxjs/cfxjse_context.h @@ -10,6 +10,7 @@ #include #include +#include "core/fxcrt/unowned_ptr.h" #include "fxjs/fxjse.h" #include "v8/include/v8.h" @@ -28,7 +29,7 @@ class CFXJSE_Context { explicit CFXJSE_Context(v8::Isolate* pIsolate); ~CFXJSE_Context(); - v8::Isolate* GetIsolate() const { return m_pIsolate; } + v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); } v8::Local GetContext(); std::unique_ptr GetGlobalObject(); void AddClass(std::unique_ptr pClass); @@ -38,12 +39,12 @@ class CFXJSE_Context { CFXJSE_Value* lpRetValue, CFXJSE_Value* lpNewThisObject = nullptr); - protected: + private: CFXJSE_Context(const CFXJSE_Context&) = delete; CFXJSE_Context& operator=(const CFXJSE_Context&) = delete; v8::Global m_hContext; - v8::Isolate* m_pIsolate; + UnownedPtr m_pIsolate; std::vector> m_rgClasses; }; diff --git a/fxjs/cfxjse_formcalc_context.h b/fxjs/cfxjse_formcalc_context.h index 51e3178c13..052bba394a 100644 --- a/fxjs/cfxjse_formcalc_context.h +++ b/fxjs/cfxjse_formcalc_context.h @@ -10,6 +10,7 @@ #include #include +#include "core/fxcrt/unowned_ptr.h" #include "fxjs/cfxjse_arguments.h" #include "fxjs/cfxjse_context.h" #include "xfa/fxfa/parser/xfa_resolvenode_rs.h" @@ -423,7 +424,7 @@ class CFXJSE_FormCalcContext : public CFXJSE_HostObject { void GlobalPropertyGetter(CFXJSE_Value* pValue); private: - v8::Isolate* GetScriptRuntime() const { return m_pIsolate; } + v8::Isolate* GetScriptRuntime() const { return m_pIsolate.Get(); } CXFA_Document* GetDocument() const { return m_pDocument.Get(); } void ThrowNoDefaultPropertyException(const ByteStringView& name) const; @@ -436,7 +437,7 @@ class CFXJSE_FormCalcContext : public CFXJSE_HostObject { void ThrowParamCountMismatchException(const WideString& method) const; void ThrowException(const wchar_t* str, ...) const; - v8::Isolate* m_pIsolate; + UnownedPtr m_pIsolate; CFXJSE_Class* m_pFMClass; std::unique_ptr m_pValue; UnownedPtr const m_pDocument; diff --git a/fxjs/cfxjse_runtimedata.cpp b/fxjs/cfxjse_runtimedata.cpp index 540bcb084e..9db172dacd 100644 --- a/fxjs/cfxjse_runtimedata.cpp +++ b/fxjs/cfxjse_runtimedata.cpp @@ -11,15 +11,13 @@ #include "fxjs/cfxjs_engine.h" #include "fxjs/cfxjse_isolatetracker.h" -CFXJSE_RuntimeData::CFXJSE_RuntimeData(v8::Isolate* pIsolate) - : m_pIsolate(pIsolate) {} +CFXJSE_RuntimeData::CFXJSE_RuntimeData() = default; -CFXJSE_RuntimeData::~CFXJSE_RuntimeData() {} +CFXJSE_RuntimeData::~CFXJSE_RuntimeData() = default; std::unique_ptr CFXJSE_RuntimeData::Create( v8::Isolate* pIsolate) { - std::unique_ptr pRuntimeData( - new CFXJSE_RuntimeData(pIsolate)); + std::unique_ptr pRuntimeData(new CFXJSE_RuntimeData()); CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate); v8::Local hFuncTemplate = diff --git a/fxjs/cfxjse_runtimedata.h b/fxjs/cfxjse_runtimedata.h index 292fe26ae3..fd4cbd7c4e 100644 --- a/fxjs/cfxjse_runtimedata.h +++ b/fxjs/cfxjse_runtimedata.h @@ -9,6 +9,7 @@ #include +#include "core/fxcrt/unowned_ptr.h" #include "v8/include/v8.h" class CFXJSE_RuntimeList; @@ -19,12 +20,11 @@ class CFXJSE_RuntimeData { static CFXJSE_RuntimeData* Get(v8::Isolate* pIsolate); - v8::Isolate* m_pIsolate; v8::Global m_hRootContextGlobalTemplate; v8::Global m_hRootContext; protected: - explicit CFXJSE_RuntimeData(v8::Isolate* pIsolate); + CFXJSE_RuntimeData(); static std::unique_ptr Create(v8::Isolate* pIsolate); diff --git a/fxjs/cfxjse_value.cpp b/fxjs/cfxjse_value.cpp index c1dd7b0027..5d7f885746 100644 --- a/fxjs/cfxjse_value.cpp +++ b/fxjs/cfxjse_value.cpp @@ -71,8 +71,9 @@ CFXJSE_Value::~CFXJSE_Value() {} CFXJSE_HostObject* CFXJSE_Value::ToHostObject(CFXJSE_Class* lpClass) const { ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local pValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); + v8::Local pValue = + v8::Local::New(GetIsolate(), m_hValue); ASSERT(!pValue.IsEmpty()); if (!pValue->IsObject()) @@ -83,51 +84,52 @@ CFXJSE_HostObject* CFXJSE_Value::ToHostObject(CFXJSE_Class* lpClass) const { void CFXJSE_Value::SetObject(CFXJSE_HostObject* lpObject, CFXJSE_Class* pClass) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local hClass = - v8::Local::New(m_pIsolate, pClass->m_hTemplate); + v8::Local::New(GetIsolate(), pClass->m_hTemplate); v8::Local hObject = hClass->InstanceTemplate()->NewInstance(); FXJSE_UpdateObjectBinding(hObject, lpObject); - m_hValue.Reset(m_pIsolate, hObject); + m_hValue.Reset(GetIsolate(), hObject); } void CFXJSE_Value::SetArray( const std::vector>& values) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hArrayObject = v8::Array::New(m_pIsolate, values.size()); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); + v8::Local hArrayObject = + v8::Array::New(GetIsolate(), values.size()); uint32_t count = 0; for (auto& v : values) { hArrayObject->Set(count++, v8::Local::New( - m_pIsolate, v.get()->DirectGetValue())); + GetIsolate(), v.get()->DirectGetValue())); } - m_hValue.Reset(m_pIsolate, hArrayObject); + m_hValue.Reset(GetIsolate(), hArrayObject); } void CFXJSE_Value::SetDate(double dDouble) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hDate = v8::Date::New(m_pIsolate, dDouble); - m_hValue.Reset(m_pIsolate, hDate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); + v8::Local hDate = v8::Date::New(GetIsolate(), dDouble); + m_hValue.Reset(GetIsolate(), hDate); } void CFXJSE_Value::SetFloat(float fFloat) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local pValue = v8::Number::New(m_pIsolate, ftod(fFloat)); - m_hValue.Reset(m_pIsolate, pValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local pValue = v8::Number::New(GetIsolate(), ftod(fFloat)); + m_hValue.Reset(GetIsolate(), pValue); } bool CFXJSE_Value::SetObjectProperty(const ByteStringView& szPropName, CFXJSE_Value* lpPropValue) { ASSERT(lpPropValue); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); + v8::Local::New(GetIsolate(), m_hValue); if (!hObject->IsObject()) return false; v8::Local hPropValue = - v8::Local::New(m_pIsolate, lpPropValue->DirectGetValue()); + v8::Local::New(GetIsolate(), lpPropValue->DirectGetValue()); return (bool)hObject.As()->Set( - v8::String::NewFromUtf8(m_pIsolate, szPropName.unterminated_c_str(), + v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(), v8::String::kNormalString, szPropName.GetLength()), hPropValue); @@ -136,15 +138,15 @@ bool CFXJSE_Value::SetObjectProperty(const ByteStringView& szPropName, bool CFXJSE_Value::GetObjectProperty(const ByteStringView& szPropName, CFXJSE_Value* lpPropValue) { ASSERT(lpPropValue); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); + v8::Local::New(GetIsolate(), m_hValue); if (!hObject->IsObject()) return false; v8::Local hPropValue = hObject.As()->Get(v8::String::NewFromUtf8( - m_pIsolate, szPropName.unterminated_c_str(), + GetIsolate(), szPropName.unterminated_c_str(), v8::String::kNormalString, szPropName.GetLength())); lpPropValue->ForceSetValue(hPropValue); return true; @@ -152,22 +154,22 @@ bool CFXJSE_Value::GetObjectProperty(const ByteStringView& szPropName, bool CFXJSE_Value::SetObjectProperty(uint32_t uPropIdx, CFXJSE_Value* lpPropValue) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); + v8::Local::New(GetIsolate(), m_hValue); if (!hObject->IsObject()) return false; v8::Local hPropValue = - v8::Local::New(m_pIsolate, lpPropValue->DirectGetValue()); + v8::Local::New(GetIsolate(), lpPropValue->DirectGetValue()); return (bool)hObject.As()->Set(uPropIdx, hPropValue); } bool CFXJSE_Value::GetObjectPropertyByIdx(uint32_t uPropIdx, CFXJSE_Value* lpPropValue) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); + v8::Local::New(GetIsolate(), m_hValue); if (!hObject->IsObject()) return false; @@ -177,51 +179,51 @@ bool CFXJSE_Value::GetObjectPropertyByIdx(uint32_t uPropIdx, } bool CFXJSE_Value::DeleteObjectProperty(const ByteStringView& szPropName) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); + v8::Local::New(GetIsolate(), m_hValue); if (!hObject->IsObject()) return false; hObject.As()->Delete(v8::String::NewFromUtf8( - m_pIsolate, szPropName.unterminated_c_str(), v8::String::kNormalString, + GetIsolate(), szPropName.unterminated_c_str(), v8::String::kNormalString, szPropName.GetLength())); return true; } bool CFXJSE_Value::HasObjectOwnProperty(const ByteStringView& szPropName, bool bUseTypeGetter) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); + v8::Local::New(GetIsolate(), m_hValue); if (!hObject->IsObject()) return false; v8::Local hKey = v8::String::NewFromUtf8( - m_pIsolate, szPropName.unterminated_c_str(), v8::String::kNormalString, + GetIsolate(), szPropName.unterminated_c_str(), v8::String::kNormalString, szPropName.GetLength()); return hObject.As()->HasRealNamedProperty(hKey) || (bUseTypeGetter && hObject.As() - ->HasOwnProperty(m_pIsolate->GetCurrentContext(), hKey) + ->HasOwnProperty(GetIsolate()->GetCurrentContext(), hKey) .FromMaybe(false)); } bool CFXJSE_Value::SetObjectOwnProperty(const ByteStringView& szPropName, CFXJSE_Value* lpPropValue) { ASSERT(lpPropValue); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); + v8::Local::New(GetIsolate(), m_hValue); if (!hObject->IsObject()) return false; v8::Local pValue = - v8::Local::New(m_pIsolate, lpPropValue->m_hValue); + v8::Local::New(GetIsolate(), lpPropValue->m_hValue); return hObject.As() ->DefineOwnProperty( m_pIsolate->GetCurrentContext(), - v8::String::NewFromUtf8(m_pIsolate, szPropName.unterminated_c_str(), + v8::String::NewFromUtf8(GetIsolate(), szPropName.unterminated_c_str(), v8::String::kNormalString, szPropName.GetLength()), pValue) @@ -232,22 +234,22 @@ bool CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis) { ASSERT(lpOldFunction && lpNewThis); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); v8::Local rgArgs[2]; v8::Local hOldFunction = - v8::Local::New(m_pIsolate, lpOldFunction->DirectGetValue()); + v8::Local::New(GetIsolate(), lpOldFunction->DirectGetValue()); if (hOldFunction.IsEmpty() || !hOldFunction->IsFunction()) return false; rgArgs[0] = hOldFunction; v8::Local hNewThis = - v8::Local::New(m_pIsolate, lpNewThis->DirectGetValue()); + v8::Local::New(GetIsolate(), lpNewThis->DirectGetValue()); if (hNewThis.IsEmpty()) return false; rgArgs[1] = hNewThis; v8::Local hBinderFuncSource = - v8::String::NewFromUtf8(m_pIsolate, + v8::String::NewFromUtf8(GetIsolate(), "(function (oldfunction, newthis) { return " "oldfunction.bind(newthis); })"); v8::Local hContext = m_pIsolate->GetCurrentContext(); @@ -262,7 +264,7 @@ bool CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction, if (hBoundFunction.IsEmpty() || !hBoundFunction->IsFunction()) return false; - m_hValue.Reset(m_pIsolate, hBoundFunction); + m_hValue.Reset(GetIsolate(), hBoundFunction); return true; } @@ -270,8 +272,9 @@ bool CFXJSE_Value::IsUndefined() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsUndefined(); } @@ -279,8 +282,9 @@ bool CFXJSE_Value::IsNull() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsNull(); } @@ -288,8 +292,9 @@ bool CFXJSE_Value::IsBoolean() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsBoolean(); } @@ -297,8 +302,9 @@ bool CFXJSE_Value::IsString() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsString(); } @@ -306,8 +312,9 @@ bool CFXJSE_Value::IsNumber() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsNumber(); } @@ -315,8 +322,9 @@ bool CFXJSE_Value::IsInteger() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsInt32(); } @@ -324,8 +332,9 @@ bool CFXJSE_Value::IsObject() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsObject(); } @@ -333,8 +342,9 @@ bool CFXJSE_Value::IsArray() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsArray(); } @@ -342,8 +352,9 @@ bool CFXJSE_Value::IsFunction() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsFunction(); } @@ -351,83 +362,90 @@ bool CFXJSE_Value::IsDate() const { if (m_hValue.IsEmpty()) return false; - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return hValue->IsDate(); } bool CFXJSE_Value::ToBoolean() const { ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return static_cast(hValue->BooleanValue()); } float CFXJSE_Value::ToFloat() const { ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return static_cast(hValue->NumberValue()); } double CFXJSE_Value::ToDouble() const { ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return static_cast(hValue->NumberValue()); } int32_t CFXJSE_Value::ToInteger() const { ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); return static_cast(hValue->NumberValue()); } ByteString CFXJSE_Value::ToString() const { ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(GetIsolate()); + v8::Local hValue = + v8::Local::New(GetIsolate(), m_hValue); v8::Local hString = hValue->ToString(); - v8::String::Utf8Value hStringVal(m_pIsolate, hString); + v8::String::Utf8Value hStringVal(GetIsolate(), hString); return ByteString(*hStringVal); } void CFXJSE_Value::SetUndefined() { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Undefined(m_pIsolate); - m_hValue.Reset(m_pIsolate, hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = v8::Undefined(GetIsolate()); + m_hValue.Reset(GetIsolate(), hValue); } void CFXJSE_Value::SetNull() { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Null(m_pIsolate); - m_hValue.Reset(m_pIsolate, hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = v8::Null(GetIsolate()); + m_hValue.Reset(GetIsolate(), hValue); } void CFXJSE_Value::SetBoolean(bool bBoolean) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Boolean::New(m_pIsolate, bBoolean != false); - m_hValue.Reset(m_pIsolate, hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = + v8::Boolean::New(GetIsolate(), bBoolean != false); + m_hValue.Reset(GetIsolate(), hValue); } void CFXJSE_Value::SetInteger(int32_t nInteger) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Integer::New(m_pIsolate, nInteger); - m_hValue.Reset(m_pIsolate, hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = v8::Integer::New(GetIsolate(), nInteger); + m_hValue.Reset(GetIsolate(), hValue); } void CFXJSE_Value::SetDouble(double dDouble) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Number::New(m_pIsolate, dDouble); - m_hValue.Reset(m_pIsolate, hValue); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); + v8::Local hValue = v8::Number::New(GetIsolate(), dDouble); + m_hValue.Reset(GetIsolate(), hValue); } void CFXJSE_Value::SetString(const ByteStringView& szString) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + CFXJSE_ScopeUtil_IsolateHandle scope(GetIsolate()); v8::Local hValue = v8::String::NewFromUtf8( - m_pIsolate, reinterpret_cast(szString.raw_str()), + GetIsolate(), reinterpret_cast(szString.raw_str()), v8::String::kNormalString, szString.GetLength()); - m_hValue.Reset(m_pIsolate, hValue); + m_hValue.Reset(GetIsolate(), hValue); } diff --git a/fxjs/cfxjse_value.h b/fxjs/cfxjse_value.h index 52bb036b95..5fbac4d58a 100644 --- a/fxjs/cfxjse_value.h +++ b/fxjs/cfxjse_value.h @@ -12,6 +12,7 @@ #include "core/fxcrt/fx_string.h" #include "core/fxcrt/fx_system.h" +#include "core/fxcrt/unowned_ptr.h" #include "fxjs/cfxjse_isolatetracker.h" #include "fxjs/cfxjse_runtimedata.h" #include "v8/include/v8.h" @@ -69,15 +70,15 @@ class CFXJSE_Value { CFXJSE_Value* lpPropValue); bool SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis); - v8::Isolate* GetIsolate() const { return m_pIsolate; } + v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); } const v8::Global& DirectGetValue() const { return m_hValue; } void ForceSetValue(v8::Local hValue) { - m_hValue.Reset(m_pIsolate, hValue); + m_hValue.Reset(GetIsolate(), hValue); } void Assign(const CFXJSE_Value* lpValue) { ASSERT(lpValue); if (lpValue) { - m_hValue.Reset(m_pIsolate, lpValue->m_hValue); + m_hValue.Reset(GetIsolate(), lpValue->m_hValue); } else { m_hValue.Reset(); } @@ -91,7 +92,7 @@ class CFXJSE_Value { CFXJSE_Value(const CFXJSE_Value&); CFXJSE_Value& operator=(const CFXJSE_Value&); - v8::Isolate* m_pIsolate; + UnownedPtr m_pIsolate; v8::Global m_hValue; }; diff --git a/fxjs/cjs_runtime.cpp b/fxjs/cjs_runtime.cpp index 96253c08bf..634c48be74 100644 --- a/fxjs/cjs_runtime.cpp +++ b/fxjs/cjs_runtime.cpp @@ -81,10 +81,8 @@ CJS_Runtime::CJS_Runtime(CPDFSDK_FormFillEnvironment* pFormFillEnv) CJS_Runtime::~CJS_Runtime() { NotifyObservers(); ReleaseEngine(); - if (m_isolateManaged) { - GetIsolate()->Dispose(); - SetIsolate(nullptr); - } + if (m_isolateManaged) + DisposeIsolate(); } void CJS_Runtime::DefineJSObjects() { diff --git a/testing/js_embedder_test.cpp b/testing/js_embedder_test.cpp index 1ca957b44f..9821a21166 100644 --- a/testing/js_embedder_test.cpp +++ b/testing/js_embedder_test.cpp @@ -15,15 +15,15 @@ JSEmbedderTest::~JSEmbedderTest() {} void JSEmbedderTest::SetUp() { v8::Isolate::CreateParams params; params.array_buffer_allocator = m_pArrayBufferAllocator.get(); - m_pIsolate = v8::Isolate::New(params); + m_pIsolate.reset(v8::Isolate::New(params)); - EmbedderTest::SetExternalIsolate(m_pIsolate); + EmbedderTest::SetExternalIsolate(isolate()); EmbedderTest::SetUp(); - v8::Isolate::Scope isolate_scope(m_pIsolate); - v8::HandleScope handle_scope(m_pIsolate); - FXJS_PerIsolateData::SetUp(m_pIsolate); - m_Engine = pdfium::MakeUnique(m_pIsolate); + v8::Isolate::Scope isolate_scope(isolate()); + v8::HandleScope handle_scope(isolate()); + FXJS_PerIsolateData::SetUp(isolate()); + m_Engine = pdfium::MakeUnique(isolate()); m_Engine->InitializeEngine(); } @@ -31,12 +31,7 @@ void JSEmbedderTest::TearDown() { m_Engine->ReleaseEngine(); m_Engine.reset(); EmbedderTest::TearDown(); - m_pIsolate->Dispose(); - m_pIsolate = nullptr; -} - -v8::Isolate* JSEmbedderTest::isolate() { - return m_pIsolate; + m_pIsolate.reset(); } v8::Local JSEmbedderTest::GetV8Context() { diff --git a/testing/js_embedder_test.h b/testing/js_embedder_test.h index 44245e3024..089670e25b 100644 --- a/testing/js_embedder_test.h +++ b/testing/js_embedder_test.h @@ -7,6 +7,7 @@ #include +#include "core/fxcrt/unowned_ptr.h" #include "fxjs/cfxjs_engine.h" #include "testing/embedder_test.h" @@ -18,13 +19,13 @@ class JSEmbedderTest : public EmbedderTest { void SetUp() override; void TearDown() override; - v8::Isolate* isolate(); + v8::Isolate* isolate() const { return m_pIsolate.get(); } + CFXJS_Engine* engine() const { return m_Engine.get(); } v8::Local GetV8Context(); - CFXJS_Engine* engine() { return m_Engine.get(); } private: std::unique_ptr m_pArrayBufferAllocator; - v8::Isolate* m_pIsolate = nullptr; + std::unique_ptr m_pIsolate; std::unique_ptr m_Engine; }; -- cgit v1.2.3