• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/ecma_string-inl.h"
17 #include "ecmascript/ecma_vm.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/js_array.h"
20 #include "ecmascript/js_function.h"
21 #include "ecmascript/js_hclass.h"
22 #include "ecmascript/js_object-inl.h"
23 #include "ecmascript/js_primitive_ref.h"
24 #include "ecmascript/js_tagged_value-inl.h"
25 #include "ecmascript/lexical_env.h"
26 #include "ecmascript/object_factory.h"
27 #include "ecmascript/tagged_array-inl.h"
28 #include "ecmascript/tests/test_helper.h"
29 
30 using namespace panda;
31 
32 using namespace panda::ecmascript;
33 
34 namespace panda::test {
35 class ObjectFactoryTest : public testing::Test {
36 public:
SetUpTestCase()37     static void SetUpTestCase()
38     {
39         GTEST_LOG_(INFO) << "SetUpTestCase";
40     }
41 
TearDownTestCase()42     static void TearDownTestCase()
43     {
44         GTEST_LOG_(INFO) << "TearDownCase";
45     }
46 
SetUp()47     void SetUp() override
48     {
49         TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
50     }
51 
TearDown()52     void TearDown() override
53     {
54         TestHelper::DestroyEcmaVMWithScope(instance, scope);
55     }
56 
57     EcmaVM *instance {nullptr};
58     ecmascript::EcmaHandleScope *scope {nullptr};
59     JSThread *thread {nullptr};
60 };
61 
GetGlobal(JSThread * thread)62 JSHandle<GlobalEnv> GetGlobal(JSThread *thread)
63 {
64     return thread->GetEcmaVM()->GetGlobalEnv();
65 }
66 
HWTEST_F_L0(ObjectFactoryTest,NewJSObjectByConstructor)67 HWTEST_F_L0(ObjectFactoryTest, NewJSObjectByConstructor)
68 {
69     thread->GetEcmaVM()->SetEnableForceGC(false);
70     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
71     JSHandle<JSTaggedValue> objFun = GetGlobal(thread)->GetObjectFunction();
72 
73     // check mem alloc
74     JSHandle<JSObject> newObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
75     JSHandle<JSHClass> newObjCls(thread, newObj->GetJSHClass());
76     EXPECT_TRUE(*newObj != nullptr);
77     EXPECT_TRUE(*newObjCls != nullptr);
78 
79     // check feild
80     EXPECT_EQ(newObj->GetProperties(), thread->GlobalConstants()->GetEmptyArray());
81     EXPECT_EQ(newObj->GetElements(), thread->GlobalConstants()->GetEmptyArray());
82     EXPECT_TRUE(JSTaggedValue(*newObj).IsECMAObject());
83 
84     // check jshclass
85     JSHClass *cls = *newObjCls;
86     EXPECT_TRUE(cls->GetObjectSize() ==
87                 JSObject::SIZE + JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS * JSTaggedValue::TaggedTypeSize());
88     EXPECT_TRUE(cls->GetPrototype() == GetGlobal(thread)->GetObjectFunctionPrototype().GetTaggedValue());
89     EXPECT_TRUE(cls->GetObjectType() == JSType::JS_OBJECT);
90 
91     // check gc handle update
92     auto *prototype = cls->GetPrototype().GetTaggedObject();
93     thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
94     // After FullGC
95     if (thread->GetEcmaVM()->GetJSOptions().EnableSnapshotDeserialize()) {
96         EXPECT_TRUE(prototype == newObjCls->GetPrototype().GetTaggedObject());
97     } else {
98         EXPECT_TRUE(prototype != newObjCls->GetPrototype().GetTaggedObject());
99     }
100     thread->GetEcmaVM()->SetEnableForceGC(true);
101 }
102 
HWTEST_F_L0(ObjectFactoryTest,NewJSFunction)103 HWTEST_F_L0(ObjectFactoryTest, NewJSFunction)
104 {
105     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
106     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
107 
108     // check mem alloc
109     JSHandle<JSFunction> newFun = factory->NewJSFunction(env);
110     JSHandle<JSHClass> newFunCls(thread, newFun->GetJSHClass());
111     EXPECT_TRUE(*newFun != nullptr);
112     EXPECT_TRUE(*newFunCls != nullptr);
113 
114     // check feild
115     EXPECT_EQ(newFun->GetProperties(), thread->GlobalConstants()->GetEmptyArray());
116     EXPECT_EQ(newFun->GetElements(), thread->GlobalConstants()->GetEmptyArray());
117     EXPECT_EQ(newFun->GetProtoOrHClass(), JSTaggedValue::Hole());
118     EXPECT_EQ(newFun->GetHomeObject(), JSTaggedValue::Undefined());
119     EXPECT_TRUE(JSTaggedValue(*newFun).IsJSFunction());
120 
121     // check jshclass
122     JSHClass *cls = *newFunCls;
123     EXPECT_TRUE(cls->GetObjectSize() ==
124                 JSFunction::SIZE + JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS * JSTaggedValue::TaggedTypeSize());
125     EXPECT_TRUE(cls->GetPrototype() == GetGlobal(thread)->GetFunctionPrototype().GetTaggedValue());
126     EXPECT_TRUE(cls->GetObjectType() == JSType::JS_FUNCTION);
127     EXPECT_TRUE(cls->IsCallable());
128     EXPECT_TRUE(cls->IsExtensible());
129     EXPECT_TRUE(!cls->IsConstructor());
130 }
131 
HWTEST_F_L0(ObjectFactoryTest,NewJSBoundFunction)132 HWTEST_F_L0(ObjectFactoryTest, NewJSBoundFunction)
133 {
134     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
135 
136     // test prepare
137     JSHandle<JSFunction> funFun(GetGlobal(thread)->GetObjectFunction());
138     JSHandle<JSTaggedValue> bound(thread, GetGlobal(thread)->GetObjectFunctionPrototype().GetTaggedValue());
139     const JSHandle<TaggedArray> array(thread->GlobalConstants()->GetHandledEmptyArray());
140 
141     // check mem alloc
142     JSHandle<JSFunctionBase> targetFunc(funFun);
143     JSHandle<JSBoundFunction> newBoundFun = factory->NewJSBoundFunction(targetFunc, bound, array);
144     JSHandle<JSHClass> newBoundFunCls(thread, newBoundFun->GetJSHClass());
145     EXPECT_TRUE(*newBoundFun != nullptr);
146     EXPECT_TRUE(*newBoundFunCls != nullptr);
147 }
148 
HWTEST_F_L0(ObjectFactoryTest,NewJSPrimitiveRef)149 HWTEST_F_L0(ObjectFactoryTest, NewJSPrimitiveRef)
150 {
151     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
152 
153     // test prepare
154     JSHandle<JSFunction> numberFun(GetGlobal(thread)->GetNumberFunction());
155     JSHandle<JSTaggedValue> primitive(thread, JSTaggedValue(1));
156 
157     // check mem alloc
158     JSHandle<JSPrimitiveRef> newPrimitive = factory->NewJSPrimitiveRef(numberFun, primitive);
159     JSHandle<JSHClass> newPrimitiveCls(thread, newPrimitive->GetJSHClass());
160     EXPECT_TRUE(*newPrimitive != nullptr);
161     EXPECT_TRUE(*newPrimitiveCls != nullptr);
162 
163     EXPECT_TRUE(newPrimitive->GetValue() == JSTaggedValue(1));
164 }
165 
HWTEST_F_L0(ObjectFactoryTest,NewLexicalEnv)166 HWTEST_F_L0(ObjectFactoryTest, NewLexicalEnv)
167 {
168     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
169 
170     // check mem alloc
171     JSHandle<LexicalEnv> newLexicalEnv = factory->NewLexicalEnv(0);
172     JSHandle<JSHClass> newLexicalEnvCls(thread, newLexicalEnv->GetClass());
173     EXPECT_TRUE(*newLexicalEnv != nullptr);
174     EXPECT_TRUE(*newLexicalEnvCls != nullptr);
175 }
176 
HWTEST_F_L0(ObjectFactoryTest,NewJSArray)177 HWTEST_F_L0(ObjectFactoryTest, NewJSArray)
178 {
179     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
180 
181     // check mem alloc
182     JSHandle<JSArray> newJSAarray = factory->NewJSArray();
183     JSHandle<JSHClass> newJSArrayCls(thread, newJSAarray->GetJSHClass());
184     EXPECT_TRUE(*newJSAarray != nullptr);
185     EXPECT_TRUE(*newJSArrayCls != nullptr);
186 }
187 
HWTEST_F_L0(ObjectFactoryTest,NewAndCopyTaggedArray)188 HWTEST_F_L0(ObjectFactoryTest, NewAndCopyTaggedArray)
189 {
190     constexpr uint32_t SHORT_ELEMENT_NUMS = 20;
191     constexpr uint32_t LONG_ELEMENT_NUMS = 100;
192     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
193     JSHandle<TaggedArray> shortTaggedarray = factory->NewTaggedArray(SHORT_ELEMENT_NUMS);
194     // init tagggedArray
195     for (uint32_t i = 0; i < SHORT_ELEMENT_NUMS; i++) {
196         shortTaggedarray->Set(thread, i, JSTaggedValue(i));
197     }
198     JSHandle<TaggedArray> copiedShort = factory->NewAndCopyTaggedArray(shortTaggedarray, SHORT_ELEMENT_NUMS,
199                                                                        SHORT_ELEMENT_NUMS);
200     JSHandle<TaggedArray> copiedLong = factory->NewAndCopyTaggedArray(shortTaggedarray, LONG_ELEMENT_NUMS,
201                                                                        SHORT_ELEMENT_NUMS);
202     // check
203     for (uint32_t i = 0; i < SHORT_ELEMENT_NUMS; i++) {
204         EXPECT_EQ(copiedShort->Get(thread, i), shortTaggedarray->Get(thread, i));
205         EXPECT_EQ(copiedLong->Get(thread, i), shortTaggedarray->Get(thread, i));
206     }
207     for (uint32_t i = SHORT_ELEMENT_NUMS; i < LONG_ELEMENT_NUMS; i++) {
208         EXPECT_EQ(copiedLong->Get(thread, i), JSTaggedValue::Hole());
209     }
210 }
211 }  // namespace panda::test
212