| // 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 <memory> |
| |
| #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<CFXJS_Engine>(isolate()); |
| } |
| |
| void TearDown() override { FXJS_Release(); } |
| |
| CFXJS_Engine* engine() const { return engine_.get(); } |
| |
| private: |
| std::unique_ptr<CFXJS_Engine> 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<v8::Object> obj) { |
| pEngine->SetObjectPrivate( |
| obj, pdfium::MakeUnique<CJS_Object>(obj, nullptr)); |
| perm_created = true; |
| }, |
| [](v8::Local<v8::Object> obj) { |
| perm_destroyed = true; |
| CFXJS_Engine::SetObjectPrivate(obj, nullptr); |
| }); |
| |
| // Object: 1 |
| engine()->DefineObj("temp", FXJSOBJTYPE_DYNAMIC, |
| [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) { |
| pEngine->SetObjectPrivate( |
| obj, pdfium::MakeUnique<CJS_Object>(obj, nullptr)); |
| temp_created = true; |
| }, |
| [](v8::Local<v8::Object> obj) { |
| temp_destroyed = true; |
| CFXJS_Engine::SetObjectPrivate(obj, nullptr); |
| }); |
| |
| engine()->InitializeEngine(); |
| |
| v8::Context::Scope context_scope(engine()->GetV8Context()); |
| v8::Local<v8::Object> 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<v8::Object> temp = engine()->NewFXJSBoundObject(1, false); |
| EXPECT_FALSE(temp.IsEmpty()); |
| EXPECT_TRUE(temp_created); |
| EXPECT_FALSE(temp_destroyed); |
| } |
| |
| Optional<IJS_Runtime::JS_Error> err = engine()->Execute(L"gc();"); |
| EXPECT_FALSE(err); |
| |
| 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); |
| } |