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