From 3e5fac8169987afe652752ca5c7b9350ffabce0d Mon Sep 17 00:00:00 2001 From: Tom Sepez Date: Mon, 12 Feb 2018 21:49:04 +0000 Subject: Test if GC'd FXJS objects have their C-side counterparts cleaned up. Small correctness fix in other engine embeddertest. Change-Id: I6c2721921a659eef1b2f155ea1797722d37209d0 Reviewed-on: https://pdfium-review.googlesource.com/26270 Reviewed-by: dsinclair Commit-Queue: Tom Sepez --- fxjs/cfx_v8_unittest.cpp | 40 ++++++---------- fxjs/cfx_v8_unittest.h | 34 ++++++++++++++ fxjs/cfxjs_engine_embeddertest.cpp | 13 ++++-- fxjs/cfxjs_engine_unittest.cpp | 95 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+), 31 deletions(-) create mode 100644 fxjs/cfx_v8_unittest.h create mode 100644 fxjs/cfxjs_engine_unittest.cpp (limited to 'fxjs') diff --git a/fxjs/cfx_v8_unittest.cpp b/fxjs/cfx_v8_unittest.cpp index db7da961e8..879d90462d 100644 --- a/fxjs/cfx_v8_unittest.cpp +++ b/fxjs/cfx_v8_unittest.cpp @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fxjs/cfx_v8.h" +#include "fxjs/cfx_v8_unittest.h" #include @@ -10,37 +10,23 @@ #include "testing/test_support.h" #include "third_party/base/ptr_util.h" -namespace { - -struct V8IsolateDeleter { - inline void operator()(v8::Isolate* ptr) const { ptr->Dispose(); } -}; - -} // namespace - -class FXV8UnitTest : public ::testing::Test { - public: - FXV8UnitTest() = default; - ~FXV8UnitTest() override = default; +void FXV8UnitTest::V8IsolateDeleter::operator()(v8::Isolate* ptr) const { + ptr->Dispose(); +} - void SetUp() override { - array_buffer_allocator_ = pdfium::MakeUnique(); +FXV8UnitTest::FXV8UnitTest() = default; - v8::Isolate::CreateParams params; - params.array_buffer_allocator = array_buffer_allocator_.get(); - isolate_.reset(v8::Isolate::New(params)); +FXV8UnitTest::~FXV8UnitTest() = default; - cfx_v8_ = pdfium::MakeUnique(isolate_.get()); - } +void FXV8UnitTest::SetUp() { + array_buffer_allocator_ = pdfium::MakeUnique(); - v8::Isolate* isolate() const { return isolate_.get(); } - CFX_V8* cfx_v8() const { return cfx_v8_.get(); } + v8::Isolate::CreateParams params; + params.array_buffer_allocator = array_buffer_allocator_.get(); + isolate_.reset(v8::Isolate::New(params)); - protected: - std::unique_ptr array_buffer_allocator_; - std::unique_ptr isolate_; - std::unique_ptr cfx_v8_; -}; + cfx_v8_ = pdfium::MakeUnique(isolate_.get()); +} TEST_F(FXV8UnitTest, EmptyLocal) { v8::Isolate::Scope isolate_scope(isolate()); diff --git a/fxjs/cfx_v8_unittest.h b/fxjs/cfx_v8_unittest.h new file mode 100644 index 0000000000..196a10f3ff --- /dev/null +++ b/fxjs/cfx_v8_unittest.h @@ -0,0 +1,34 @@ +// Copyright 2018 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. + +#ifndef FXJS_CFX_V8_UNITTEST_H_ +#define FXJS_CFX_V8_UNITTEST_H_ + +#include "fxjs/cfx_v8.h" + +#include + +#include "testing/gtest/include/gtest/gtest.h" + +class FXV8UnitTest : public ::testing::Test { + public: + struct V8IsolateDeleter { + void operator()(v8::Isolate* ptr) const; + }; + + FXV8UnitTest(); + ~FXV8UnitTest() override; + + void SetUp() override; + + v8::Isolate* isolate() const { return isolate_.get(); } + CFX_V8* cfx_v8() const { return cfx_v8_.get(); } + + protected: + std::unique_ptr array_buffer_allocator_; + std::unique_ptr isolate_; + std::unique_ptr cfx_v8_; +}; + +#endif // FXJS_CFX_V8_UNITTEST_H_ diff --git a/fxjs/cfxjs_engine_embeddertest.cpp b/fxjs/cfxjs_engine_embeddertest.cpp index f25bfbe060..bcd4183de0 100644 --- a/fxjs/cfxjs_engine_embeddertest.cpp +++ b/fxjs/cfxjs_engine_embeddertest.cpp @@ -22,15 +22,20 @@ const wchar_t kScript2[] = L"fred = 8"; class CFXJSEngineEmbedderTest : public JSEmbedderTest { public: void ExecuteInCurrentContext(const WideString& script) { + auto* current_engine = + CFXJS_Engine::EngineFromIsolateCurrentContext(isolate()); FXJSErr error; - int sts = engine()->Execute(script, &error); + int sts = current_engine->Execute(script, &error); EXPECT_EQ(0, sts); } void CheckAssignmentInCurrentContext(double expected) { - v8::Local This = engine()->GetThisObj(); - v8::Local fred = engine()->GetObjectProperty(This, L"fred"); + auto* current_engine = + CFXJS_Engine::EngineFromIsolateCurrentContext(isolate()); + v8::Local This = current_engine->GetThisObj(); + v8::Local fred = + current_engine->GetObjectProperty(This, L"fred"); EXPECT_TRUE(fred->IsNumber()); - EXPECT_EQ(expected, engine()->ToDouble(fred)); + EXPECT_EQ(expected, current_engine->ToDouble(fred)); } }; diff --git a/fxjs/cfxjs_engine_unittest.cpp b/fxjs/cfxjs_engine_unittest.cpp new file mode 100644 index 0000000000..d5c473c178 --- /dev/null +++ b/fxjs/cfxjs_engine_unittest.cpp @@ -0,0 +1,95 @@ +// Copyright 2018 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. + +#include "fxjs/cfxjs_engine.h" + +#include + +#include "fxjs/cfx_v8_unittest.h" +#include "fxjs/cjs_object.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/base/ptr_util.h" + +class FXJSEngineUnitTest : public FXV8UnitTest { + public: + FXJSEngineUnitTest() = default; + ~FXJSEngineUnitTest() override = default; + + void SetUp() override { + FXV8UnitTest::SetUp(); + FXJS_Initialize(1, isolate()); + engine_ = pdfium::MakeUnique(isolate()); + } + + void TearDown() override { FXJS_Release(); } + + CFXJS_Engine* engine() const { return engine_.get(); } + + private: + std::unique_ptr engine_; +}; + +static bool perm_created = false; +static bool perm_destroyed = false; +static bool temp_created = false; +static bool temp_destroyed = false; + +TEST_F(FXJSEngineUnitTest, GC) { + v8::Isolate::Scope isolate_scope(isolate()); + v8::HandleScope handle_scope(isolate()); + + // Object: 0 + engine()->DefineObj("perm", FXJSOBJTYPE_DYNAMIC, + [](CFXJS_Engine* pEngine, v8::Local obj) { + pEngine->SetObjectPrivate( + obj, pdfium::MakeUnique(obj)); + perm_created = true; + }, + [](v8::Local obj) { + perm_destroyed = true; + CFXJS_Engine::SetObjectPrivate(obj, nullptr); + }); + + // Object: 1 + engine()->DefineObj("temp", FXJSOBJTYPE_DYNAMIC, + [](CFXJS_Engine* pEngine, v8::Local obj) { + pEngine->SetObjectPrivate( + obj, pdfium::MakeUnique(obj)); + temp_created = true; + }, + [](v8::Local obj) { + temp_destroyed = true; + CFXJS_Engine::SetObjectPrivate(obj, nullptr); + }); + + engine()->InitializeEngine(); + + v8::Context::Scope context_scope(engine()->GetV8Context()); + v8::Local perm = engine()->NewFXJSBoundObject(0, false); + EXPECT_FALSE(perm.IsEmpty()); + EXPECT_TRUE(perm_created); + EXPECT_FALSE(perm_destroyed); + + { + v8::HandleScope inner_handle_scope(isolate()); + v8::Local temp = engine()->NewFXJSBoundObject(1, false); + EXPECT_FALSE(temp.IsEmpty()); + EXPECT_TRUE(temp_created); + EXPECT_FALSE(temp_destroyed); + } + + FXJSErr error; + engine()->Execute(L"gc();", &error); + EXPECT_TRUE(perm_created); + EXPECT_FALSE(perm_destroyed); + EXPECT_TRUE(temp_created); + // TODO(tsepez): temp_destroyed should be true, but it isnt. + // EXPECT_TRUE(temp_destroyed); + + engine()->ReleaseEngine(); + EXPECT_TRUE(perm_created); + EXPECT_TRUE(perm_destroyed); + EXPECT_TRUE(temp_created); + EXPECT_TRUE(temp_destroyed); +} -- cgit v1.2.3