• 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/base/config.h"
17 #include "ecmascript/ecma_string-inl.h"
18 #include "ecmascript/ecma_vm.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/js_array.h"
21 #include "ecmascript/js_function.h"
22 #include "ecmascript/js_hclass.h"
23 #include "ecmascript/js_object-inl.h"
24 #include "ecmascript/js_primitive_ref.h"
25 #include "ecmascript/js_tagged_value-inl.h"
26 #include "ecmascript/lexical_env.h"
27 #include "ecmascript/object_factory.h"
28 #include "ecmascript/tagged_array-inl.h"
29 #include "ecmascript/tests/test_helper.h"
30 
31 using namespace panda;
32 
33 using namespace panda::ecmascript;
34 
35 namespace panda::test {
36 class ObjectFactoryTest : public BaseTestWithScope<false> {
37 };
38 
GetGlobal(JSThread * thread)39 JSHandle<GlobalEnv> GetGlobal(JSThread *thread)
40 {
41     return thread->GetEcmaVM()->GetGlobalEnv();
42 }
43 
HWTEST_F_L0(ObjectFactoryTest,NewJSObjectByConstructor)44 HWTEST_F_L0(ObjectFactoryTest, NewJSObjectByConstructor)
45 {
46     thread->GetEcmaVM()->SetEnableForceGC(false);
47     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
48     JSHandle<JSTaggedValue> objFun = GetGlobal(thread)->GetObjectFunction();
49 
50     // check mem alloc
51     JSHandle<JSObject> newObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun);
52     JSHandle<JSHClass> newObjCls(thread, newObj->GetJSHClass());
53     EXPECT_TRUE(*newObj != nullptr);
54     EXPECT_TRUE(*newObjCls != nullptr);
55 
56     // check feild
57     EXPECT_EQ(newObj->GetProperties(thread), thread->GlobalConstants()->GetEmptyArray());
58     EXPECT_EQ(newObj->GetElements(thread), thread->GlobalConstants()->GetEmptyArray());
59     EXPECT_TRUE(JSTaggedValue(*newObj).IsECMAObject());
60 
61     // check jshclass
62     JSHClass *cls = *newObjCls;
63     EXPECT_TRUE(cls->GetObjectSize() ==
64                 JSObject::SIZE + JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS * JSTaggedValue::TaggedTypeSize());
65     EXPECT_TRUE(cls->GetPrototype(thread) == GetGlobal(thread)->GetObjectFunctionPrototype().GetTaggedValue());
66     EXPECT_TRUE(cls->GetObjectType() == JSType::JS_OBJECT);
67 
68     // check gc handle update
69     auto *prototype = cls->GetPrototype(thread).GetTaggedObject();
70     thread->GetEcmaVM()->CollectGarbage(TriggerGCType::FULL_GC);
71     // After FullGC
72     // Test condition reply on gc.It is not suitable.
73     if (!g_isEnableCMCGC) {
74         if (thread->GetEcmaVM()->GetJSOptions().EnableSnapshotDeserialize()) {
75             EXPECT_TRUE(prototype == newObjCls->GetPrototype(thread).GetTaggedObject());
76         } else {
77             EXPECT_TRUE(prototype != newObjCls->GetPrototype(thread).GetTaggedObject());
78         }
79     }
80     thread->GetEcmaVM()->SetEnableForceGC(true);
81 }
82 
HWTEST_F_L0(ObjectFactoryTest,NewJSFunction)83 HWTEST_F_L0(ObjectFactoryTest, NewJSFunction)
84 {
85     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
86     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
87 
88     // check mem alloc
89     JSHandle<JSFunction> newFun = factory->NewJSFunction(env);
90     JSHandle<JSHClass> newFunCls(thread, newFun->GetJSHClass());
91     EXPECT_TRUE(*newFun != nullptr);
92     EXPECT_TRUE(*newFunCls != nullptr);
93 
94     // check feild
95     EXPECT_EQ(newFun->GetProperties(thread), thread->GlobalConstants()->GetEmptyArray());
96     EXPECT_EQ(newFun->GetElements(thread), thread->GlobalConstants()->GetEmptyArray());
97     EXPECT_EQ(newFun->GetProtoOrHClass(thread), JSTaggedValue::Hole());
98     EXPECT_EQ(newFun->GetHomeObject(thread), JSTaggedValue::Undefined());
99     EXPECT_TRUE(JSTaggedValue(*newFun).IsJSFunction());
100 
101     // check jshclass
102     JSHClass *cls = *newFunCls;
103     EXPECT_TRUE(cls->GetObjectSize() ==
104                 JSFunction::SIZE + JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS * JSTaggedValue::TaggedTypeSize());
105     EXPECT_TRUE(cls->GetPrototype(thread) == GetGlobal(thread)->GetFunctionPrototype().GetTaggedValue());
106     EXPECT_TRUE(cls->GetObjectType() == JSType::JS_FUNCTION);
107     EXPECT_TRUE(cls->IsCallable());
108     EXPECT_TRUE(cls->IsExtensible());
109     EXPECT_TRUE(!cls->IsConstructor());
110 }
111 
HWTEST_F_L0(ObjectFactoryTest,NewJSBoundFunction)112 HWTEST_F_L0(ObjectFactoryTest, NewJSBoundFunction)
113 {
114     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
115 
116     // test prepare
117     JSHandle<JSFunction> funFun(GetGlobal(thread)->GetObjectFunction());
118     JSHandle<JSTaggedValue> bound(thread, GetGlobal(thread)->GetObjectFunctionPrototype().GetTaggedValue());
119     const JSHandle<TaggedArray> array(thread->GlobalConstants()->GetHandledEmptyArray());
120 
121     // check mem alloc
122     JSHandle<JSBoundFunction> newBoundFun =
123         factory->NewJSBoundFunction(JSHandle<JSTaggedValue>::Cast(funFun), bound, array);
124     JSHandle<JSHClass> newBoundFunCls(thread, newBoundFun->GetJSHClass());
125     EXPECT_TRUE(*newBoundFun != nullptr);
126     EXPECT_TRUE(*newBoundFunCls != nullptr);
127 }
128 
HWTEST_F_L0(ObjectFactoryTest,NewJSPrimitiveRef)129 HWTEST_F_L0(ObjectFactoryTest, NewJSPrimitiveRef)
130 {
131     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
132 
133     // test prepare
134     JSHandle<JSFunction> numberFun(GetGlobal(thread)->GetNumberFunction());
135     JSHandle<JSTaggedValue> primitive(thread, JSTaggedValue(1));
136 
137     // check mem alloc
138     JSHandle<JSPrimitiveRef> newPrimitive = factory->NewJSPrimitiveRef(numberFun, primitive);
139     JSHandle<JSHClass> newPrimitiveCls(thread, newPrimitive->GetJSHClass());
140     EXPECT_TRUE(*newPrimitive != nullptr);
141     EXPECT_TRUE(*newPrimitiveCls != nullptr);
142 
143     EXPECT_TRUE(newPrimitive->GetValue(thread) == JSTaggedValue(1));
144 }
145 
HWTEST_F_L0(ObjectFactoryTest,NewLexicalEnv)146 HWTEST_F_L0(ObjectFactoryTest, NewLexicalEnv)
147 {
148     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
149 
150     // check mem alloc
151     JSHandle<LexicalEnv> newLexicalEnv = factory->NewLexicalEnv(0);
152     JSHandle<JSHClass> newLexicalEnvCls(thread, newLexicalEnv->GetClass());
153     EXPECT_TRUE(*newLexicalEnv != nullptr);
154     EXPECT_TRUE(*newLexicalEnvCls != nullptr);
155 }
156 
HWTEST_F_L0(ObjectFactoryTest,NewJSArray)157 HWTEST_F_L0(ObjectFactoryTest, NewJSArray)
158 {
159     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
160 
161     // check mem alloc
162     JSHandle<JSArray> newJSAarray = factory->NewJSArray();
163     JSHandle<JSHClass> newJSArrayCls(thread, newJSAarray->GetJSHClass());
164     EXPECT_TRUE(*newJSAarray != nullptr);
165     EXPECT_TRUE(*newJSArrayCls != nullptr);
166 }
167 
HWTEST_F_L0(ObjectFactoryTest,NewAndCopyTaggedArray)168 HWTEST_F_L0(ObjectFactoryTest, NewAndCopyTaggedArray)
169 {
170     constexpr uint32_t SHORT_ELEMENT_NUMS = 20;
171     constexpr uint32_t LONG_ELEMENT_NUMS = 100;
172     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
173     JSHandle<TaggedArray> shortTaggedarray = factory->NewTaggedArray(SHORT_ELEMENT_NUMS);
174     // init tagggedArray
175     for (uint32_t i = 0; i < SHORT_ELEMENT_NUMS; i++) {
176         shortTaggedarray->Set(thread, i, JSTaggedValue(i));
177     }
178     JSHandle<TaggedArray> copiedShort = factory->NewAndCopyTaggedArray(shortTaggedarray, SHORT_ELEMENT_NUMS,
179                                                                        SHORT_ELEMENT_NUMS);
180     JSHandle<TaggedArray> copiedLong = factory->NewAndCopyTaggedArray(shortTaggedarray, LONG_ELEMENT_NUMS,
181                                                                        SHORT_ELEMENT_NUMS);
182     // check
183     for (uint32_t i = 0; i < SHORT_ELEMENT_NUMS; i++) {
184         EXPECT_EQ(copiedShort->Get(thread, i), shortTaggedarray->Get(thread, i));
185         EXPECT_EQ(copiedLong->Get(thread, i), shortTaggedarray->Get(thread, i));
186     }
187     for (uint32_t i = SHORT_ELEMENT_NUMS; i < LONG_ELEMENT_NUMS; i++) {
188         EXPECT_EQ(copiedLong->Get(thread, i), JSTaggedValue::Hole());
189     }
190 }
191 
HWTEST_F_L0(ObjectFactoryTest,NewAndCopyTaggedArrayNeedBarrier)192 HWTEST_F_L0(ObjectFactoryTest, NewAndCopyTaggedArrayNeedBarrier)
193 {
194     constexpr uint32_t SHORT_ELEMENT_NUMS = 20;
195     constexpr uint32_t LONG_ELEMENT_NUMS = 100;
196     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
197     JSHandle<TaggedArray> shortTaggedarray = factory->NewTaggedArray(SHORT_ELEMENT_NUMS);
198     // init tagggedArray
199     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
200     for (uint32_t i = 0; i < SHORT_ELEMENT_NUMS; i++) {
201         JSHandle<JSFunction> newFun = factory->NewJSFunction(env);
202         shortTaggedarray->Set(thread, i, newFun);
203     }
204     JSHandle<TaggedArray> copiedShort = factory->NewAndCopyTaggedArray(shortTaggedarray, SHORT_ELEMENT_NUMS,
205                                                                        SHORT_ELEMENT_NUMS);
206     JSHandle<TaggedArray> copiedLong = factory->NewAndCopyTaggedArray(shortTaggedarray, LONG_ELEMENT_NUMS,
207                                                                        SHORT_ELEMENT_NUMS);
208     // check
209     for (uint32_t i = 0; i < SHORT_ELEMENT_NUMS; i++) {
210         EXPECT_EQ(copiedShort->Get(thread, i), shortTaggedarray->Get(thread, i));
211         EXPECT_EQ(copiedLong->Get(thread, i), shortTaggedarray->Get(thread, i));
212     }
213     for (uint32_t i = SHORT_ELEMENT_NUMS; i < LONG_ELEMENT_NUMS; i++) {
214         EXPECT_EQ(copiedLong->Get(thread, i), JSTaggedValue::Hole());
215     }
216 }
217 }  // namespace panda::test
218