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