• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "fxjs/cfxjs_engine.h"
6 
7 #include <memory>
8 
9 #include "fxjs/cfx_v8_unittest.h"
10 #include "fxjs/cjs_object.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "third_party/base/ptr_util.h"
13 
14 class FXJSEngineUnitTest : public FXV8UnitTest {
15  public:
16   FXJSEngineUnitTest() = default;
17   ~FXJSEngineUnitTest() override = default;
18 
SetUp()19   void SetUp() override {
20     FXV8UnitTest::SetUp();
21     FXJS_Initialize(1, isolate());
22     engine_ = pdfium::MakeUnique<CFXJS_Engine>(isolate());
23   }
24 
TearDown()25   void TearDown() override { FXJS_Release(); }
26 
engine() const27   CFXJS_Engine* engine() const { return engine_.get(); }
28 
29  private:
30   std::unique_ptr<CFXJS_Engine> engine_;
31 };
32 
33 static bool perm_created = false;
34 static bool perm_destroyed = false;
35 static bool temp_created = false;
36 static bool temp_destroyed = false;
37 
TEST_F(FXJSEngineUnitTest,GC)38 TEST_F(FXJSEngineUnitTest, GC) {
39   v8::Isolate::Scope isolate_scope(isolate());
40   v8::HandleScope handle_scope(isolate());
41 
42   // Object: 0
43   engine()->DefineObj(
44       "perm", FXJSOBJTYPE_DYNAMIC,
45       [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) {
46         pEngine->SetObjectPrivate(obj,
47                                   pdfium::MakeUnique<CJS_Object>(obj, nullptr));
48         perm_created = true;
49       },
50       [](v8::Local<v8::Object> obj) {
51         perm_destroyed = true;
52         CFXJS_Engine::SetObjectPrivate(obj, nullptr);
53       });
54 
55   // Object: 1
56   engine()->DefineObj(
57       "temp", FXJSOBJTYPE_DYNAMIC,
58       [](CFXJS_Engine* pEngine, v8::Local<v8::Object> obj) {
59         pEngine->SetObjectPrivate(obj,
60                                   pdfium::MakeUnique<CJS_Object>(obj, nullptr));
61         temp_created = true;
62       },
63       [](v8::Local<v8::Object> obj) {
64         temp_destroyed = true;
65         CFXJS_Engine::SetObjectPrivate(obj, nullptr);
66       });
67 
68   engine()->InitializeEngine();
69 
70   v8::Context::Scope context_scope(engine()->GetV8Context());
71   v8::Local<v8::Object> perm =
72       engine()->NewFXJSBoundObject(0, FXJSOBJTYPE_DYNAMIC);
73   EXPECT_FALSE(perm.IsEmpty());
74   EXPECT_TRUE(perm_created);
75   EXPECT_FALSE(perm_destroyed);
76 
77   {
78     v8::HandleScope inner_handle_scope(isolate());
79     v8::Local<v8::Object> temp =
80         engine()->NewFXJSBoundObject(1, FXJSOBJTYPE_DYNAMIC);
81     EXPECT_FALSE(temp.IsEmpty());
82     EXPECT_TRUE(temp_created);
83     EXPECT_FALSE(temp_destroyed);
84   }
85 
86   Optional<IJS_Runtime::JS_Error> err = engine()->Execute(L"gc();");
87   EXPECT_FALSE(err);
88 
89   EXPECT_TRUE(perm_created);
90   EXPECT_FALSE(perm_destroyed);
91   EXPECT_TRUE(temp_created);
92   // TODO(tsepez): temp_destroyed should be true, but it isnt.
93   // EXPECT_TRUE(temp_destroyed);
94 
95   engine()->ReleaseEngine();
96   EXPECT_TRUE(perm_created);
97   EXPECT_TRUE(perm_destroyed);
98   EXPECT_TRUE(temp_created);
99   EXPECT_TRUE(temp_destroyed);
100 }
101