• 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/builtins_base.h"
17 
18 #include "ecmascript/ecma_runtime_call_info.h"
19 #include "ecmascript/ecma_string.h"
20 #include "ecmascript/ecma_vm.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/ic/proto_change_details.h"
23 #include "ecmascript/js_function.h"
24 #include "ecmascript/js_handle.h"
25 #include "ecmascript/js_hclass.h"
26 #include "ecmascript/js_object-inl.h"
27 #include "ecmascript/js_thread.h"
28 #include "ecmascript/mem/verification.h"
29 #include "ecmascript/object_factory.h"
30 #include "ecmascript/object_operator.h"
31 #include "ecmascript/property_attributes.h"
32 #include "ecmascript/tagged_array-inl.h"
33 #include "ecmascript/tagged_dictionary.h"
34 #include "ecmascript/tests/test_helper.h"
35 #include "ecmascript/weak_vector.h"
36 
37 using namespace panda::ecmascript;
38 using namespace panda::ecmascript::base;
39 
40 namespace panda::test {
41 class JSObjectTest : public BaseTestWithScope<false> {
42 };
43 
JSObjectTestCreate(JSThread * thread)44 static JSFunction *JSObjectTestCreate(JSThread *thread)
45 {
46     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
47     return globalEnv->GetObjectFunction().GetObject<JSFunction>();
48 }
49 
HWTEST_F_L0(JSObjectTest,Create)50 HWTEST_F_L0(JSObjectTest, Create)
51 {
52     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
53     JSHandle<JSObject> jsobject =
54         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
55     EXPECT_TRUE(*jsobject != nullptr);
56 }
57 
HWTEST_F_L0(JSObjectTest,SetProperty)58 HWTEST_F_L0(JSObjectTest, SetProperty)
59 {
60     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
61     JSHandle<JSObject> jsobject =
62         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
63     EXPECT_TRUE(*jsobject != nullptr);
64 
65     char array[] = "x";
66     JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array));
67     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
68 
69     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsobject), key, value);
70     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsobject), key).GetValue()->GetInt(), 1);
71 
72     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
73     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(jsobject), key, value2);
74     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(jsobject), key).GetValue()->GetInt(), 2);
75 }
76 
HWTEST_F_L0(JSObjectTest,GetProperty)77 HWTEST_F_L0(JSObjectTest, GetProperty)
78 {
79     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
80     JSHandle<JSObject> obj =
81         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
82     EXPECT_TRUE(*obj != nullptr);
83 
84     char array[] = "x";
85     JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array));
86     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
87 
88     EXPECT_TRUE(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->IsUndefined());
89 
90     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key, value);
91     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->GetInt(), 1);
92 }
93 
HWTEST_F_L0(JSObjectTest,DeleteProperty)94 HWTEST_F_L0(JSObjectTest, DeleteProperty)
95 {
96     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
97     JSHandle<JSObject> obj =
98         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
99     EXPECT_TRUE(*obj != nullptr);
100 
101     char array[] = "print";
102     JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array));
103     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
104 
105     JSObject::DeleteProperty(thread, (obj), key);
106     EXPECT_TRUE(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->IsUndefined());
107 
108     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key, value);
109     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->GetInt(), 1);
110 
111     JSHandle<JSTaggedValue> key2(thread->GetEcmaVM()->GetFactory()->NewFromASCII("print_test"));
112     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2,
113                           JSHandle<JSTaggedValue>(thread, JSTaggedValue(10)));
114     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key2).GetValue()->GetInt(), 10);
115 
116     JSObject::DeleteProperty(thread, (obj), key);
117     EXPECT_TRUE(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->IsUndefined());
118     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key2).GetValue()->GetInt(), 10);
119 }
120 
HWTEST_F_L0(JSObjectTest,DeletePropertyGlobal)121 HWTEST_F_L0(JSObjectTest, DeletePropertyGlobal)
122 {
123     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
124     JSHandle<JSTaggedValue> global(thread, globalEnv->GetGlobalObject());
125     JSHandle<JSTaggedValue> printKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("print"));
126     JSHandle<JSTaggedValue> printTestKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("print_test"));
127 
128     JSHandle<JSTaggedValue> value = JSObject::GetProperty(thread, global, printKey).GetValue();
129 
130     JSObject::SetProperty(thread, global, printTestKey, value);
131 
132     JSTaggedValue val2 = JSObject::GetProperty(thread, global, printTestKey).GetValue().GetTaggedValue();
133     EXPECT_EQ(val2, value.GetTaggedValue());
134     JSTaggedValue::DeletePropertyOrThrow(thread, global, printTestKey);
135     JSTaggedValue val3 = JSObject::GetProperty(thread, global, printKey).GetValue().GetTaggedValue();
136     EXPECT_NE(val3, JSTaggedValue::Undefined());
137 }
138 
GetPropertyHasOwnPeroperty(JSThread * thread,bool hasOwnProperty=false)139 void GetPropertyHasOwnPeroperty(JSThread *thread, bool hasOwnProperty = false)
140 {
141     JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
142     JSHandle<JSObject> grandfather = JSObject::ObjectCreate(thread, nullHandle);
143     JSHandle<JSObject> father = JSObject::ObjectCreate(thread, grandfather);
144     JSHandle<JSObject> son = JSObject::ObjectCreate(thread, father);
145 
146     JSHandle<JSTaggedValue> sonKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key1"));
147     JSHandle<JSTaggedValue> fatherKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2"));
148     JSHandle<JSTaggedValue> grandfatherKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key3"));
149     JSHandle<JSTaggedValue> sonValue(thread, JSTaggedValue(1)); // 1 : value
150     JSHandle<JSTaggedValue> fatherValue(thread, JSTaggedValue(2)); // 2 : value
151     JSHandle<JSTaggedValue> grandfatherValue(thread, JSTaggedValue(3)); // 3 : value
152 
153     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(son), sonKey, sonValue);
154     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(father), fatherKey, fatherValue);
155     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(grandfather), grandfatherKey, grandfatherValue);
156 
157     if (hasOwnProperty) {
158         bool flag = JSTaggedValue::HasOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(son), sonKey);
159         EXPECT_TRUE(flag);
160         flag = JSTaggedValue::HasOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(son), fatherKey);
161         EXPECT_FALSE(flag);
162         flag = JSTaggedValue::HasOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(son), grandfatherKey);
163         EXPECT_FALSE(flag);
164     } else {
165         EXPECT_EQ(sonValue.GetTaggedValue(),
166                   JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(son), sonKey).GetValue().GetTaggedValue());
167         EXPECT_EQ(fatherValue.GetTaggedValue(),
168                   JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(son), fatherKey).GetValue().GetTaggedValue());
169         EXPECT_EQ(
170             grandfatherValue.GetTaggedValue(),
171             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(son), grandfatherKey).GetValue().GetTaggedValue());
172     }
173 }
174 
HWTEST_F_L0(JSObjectTest,GetPropertyInPrototypeChain)175 HWTEST_F_L0(JSObjectTest, GetPropertyInPrototypeChain)
176 {
177     GetPropertyHasOwnPeroperty(thread);
178 }
179 
HWTEST_F_L0(JSObjectTest,PropertyAttribute)180 HWTEST_F_L0(JSObjectTest, PropertyAttribute)
181 {
182     JSHandle<JSTaggedValue> constructor(thread, JSObjectTestCreate(thread));
183     JSHandle<JSObject> obj1 =
184         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor);
185     JSHandle<JSObject> obj2 =
186         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor);
187 
188     JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key3"));
189     JSHandle<JSTaggedValue> key2(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key3"));
190 
191     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
192     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
193 
194     // test set property
195     PropertyDescriptor desc(thread);
196     desc.SetValue(value1);
197     desc.SetWritable(false);
198     JSObject::DefineOwnProperty(thread, obj1, key1, desc);
199     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value2);
200     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key1, value1);
201     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key1, value2);
202     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1).GetValue().GetTaggedValue(),
203               value1.GetTaggedValue());
204     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj2), key1).GetValue().GetTaggedValue(),
205               value2.GetTaggedValue());
206 
207     // test delete property
208     PropertyDescriptor desc1(thread);
209     desc1.SetValue(value1);
210     desc1.SetConfigurable(false);
211     JSObject::DefineOwnProperty(thread, obj1, key2, desc1);
212     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value1);
213     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key2, value1);
214     JSObject::DeleteProperty(thread, (obj1), key2);
215     JSObject::DeleteProperty(thread, (obj2), key2);
216     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2).GetValue().GetTaggedValue(),
217               value1.GetTaggedValue());
218     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj2), key2).GetValue().GetTaggedValue(),
219               JSTaggedValue::Undefined());
220 }
221 
HWTEST_F_L0(JSObjectTest,CreateDataProperty)222 HWTEST_F_L0(JSObjectTest, CreateDataProperty)
223 {
224     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
225     JSHandle<JSObject> obj =
226         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
227     EXPECT_TRUE(*obj != nullptr);
228 
229     char array[] = "x";
230     JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array));
231     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
232 
233     bool success = JSObject::CreateDataProperty(thread, obj, key, value);
234     EXPECT_TRUE(success);
235 
236     success = JSTaggedValue::HasOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(obj), key);
237     EXPECT_TRUE(success);
238 
239     PropertyDescriptor desc(thread);
240     success = JSObject::GetOwnProperty(thread, obj, key, desc);
241     EXPECT_TRUE(success);
242     EXPECT_EQ(true, desc.IsWritable());
243     EXPECT_EQ(true, desc.IsEnumerable());
244     EXPECT_EQ(true, desc.IsConfigurable());
245 }
246 
HWTEST_F_L0(JSObjectTest,CreateMethodProperty)247 HWTEST_F_L0(JSObjectTest, CreateMethodProperty)
248 {
249     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
250     JSHandle<JSObject> obj =
251         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
252     EXPECT_TRUE(*obj != nullptr);
253 
254     char array[] = "x";
255     JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array));
256     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
257 
258     bool success = JSObject::CreateMethodProperty(thread, obj, key, value);
259     EXPECT_TRUE(success);
260 
261     success = JSTaggedValue::HasOwnProperty(thread, JSHandle<JSTaggedValue>::Cast(obj), key);
262     EXPECT_TRUE(success);
263 
264     PropertyDescriptor desc(thread);
265     success = JSObject::GetOwnProperty(thread, obj, key, desc);
266     EXPECT_TRUE(success);
267     EXPECT_EQ(true, desc.IsWritable());
268     EXPECT_EQ(false, desc.IsEnumerable());
269     EXPECT_EQ(true, desc.IsConfigurable());
270 }
271 
HWTEST_F_L0(JSObjectTest,DefinePropertyOrThrow)272 HWTEST_F_L0(JSObjectTest, DefinePropertyOrThrow)
273 {
274     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
275     JSHandle<JSObject> obj =
276         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
277     EXPECT_TRUE(*obj != nullptr);
278 
279     char array[] = "x";
280     JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array));
281 
282     PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, true, true);
283     bool success = JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, desc1);
284     EXPECT_TRUE(success);
285     PropertyDescriptor descRes1(thread);
286     success = JSObject::GetOwnProperty(thread, obj, key, descRes1);
287     EXPECT_TRUE(success);
288     EXPECT_EQ(1, descRes1.GetValue()->GetInt());
289     EXPECT_EQ(true, descRes1.IsWritable());
290     EXPECT_EQ(true, descRes1.IsEnumerable());
291     EXPECT_EQ(true, descRes1.IsConfigurable());
292 
293     PropertyDescriptor desc2(thread, false, true, true);
294     success = JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, desc2);
295     EXPECT_TRUE(success);
296     PropertyDescriptor descRes2(thread);
297     success = JSObject::GetOwnProperty(thread, obj, key, descRes2);
298     EXPECT_TRUE(success);
299     EXPECT_EQ(1, descRes2.GetValue()->GetInt());
300     EXPECT_EQ(false, descRes2.IsWritable());
301     EXPECT_EQ(true, descRes2.IsEnumerable());
302     EXPECT_EQ(true, descRes2.IsConfigurable());
303 
304     PropertyDescriptor desc3(thread);
305     desc3.SetWritable(false);
306     desc3.SetEnumerable(false);
307     desc3.SetConfigurable(false);
308     success = JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, desc3);
309     EXPECT_TRUE(success);
310     PropertyDescriptor descRes3(thread);
311     success = JSObject::GetOwnProperty(thread, obj, key, descRes3);
312     EXPECT_TRUE(success);
313     EXPECT_EQ(1, descRes3.GetValue()->GetInt());
314     EXPECT_EQ(false, descRes3.IsWritable());
315     EXPECT_EQ(false, descRes3.IsEnumerable());
316     EXPECT_EQ(false, descRes3.IsConfigurable());
317 
318     PropertyDescriptor desc4(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(2)));
319     success = JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, desc4);
320     EXPECT_FALSE(success);
321 }
322 
HWTEST_F_L0(JSObjectTest,HasProperty)323 HWTEST_F_L0(JSObjectTest, HasProperty)
324 {
325     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
326     JSHandle<JSObject> obj =
327         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
328     EXPECT_TRUE(*obj != nullptr);
329 
330     char array[] = "x";
331     JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII(array));
332     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
333 
334     bool flag = JSObject::HasProperty(thread, obj, key);
335     EXPECT_FALSE(flag);
336 
337     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key, value);
338     flag = JSObject::HasProperty(thread, obj, key);
339     EXPECT_TRUE(flag);
340 
341     JSObject::DeleteProperty(thread, (obj), key);
342     flag = JSObject::HasProperty(thread, obj, key);
343     EXPECT_FALSE(flag);
344 }
345 
HWTEST_F_L0(JSObjectTest,HasPropertyWithPrototype)346 HWTEST_F_L0(JSObjectTest, HasPropertyWithPrototype)
347 {
348     JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
349     JSHandle<JSObject> grandfather = JSObject::ObjectCreate(thread, nullHandle);
350     JSHandle<JSObject> father = JSObject::ObjectCreate(thread, grandfather);
351     JSHandle<JSObject> son = JSObject::ObjectCreate(thread, father);
352 
353     JSHandle<JSTaggedValue> testGrand(thread,
354         JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(grandfather)));
355     JSHandle<JSTaggedValue> testFather(thread, JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(father)));
356     JSHandle<JSTaggedValue> testSon(thread, JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(son)));
357     EXPECT_TRUE(testSon.GetTaggedValue() != testFather.GetTaggedValue());
358     EXPECT_TRUE(testGrand.GetTaggedValue() != testFather.GetTaggedValue());
359     JSHandle<JSTaggedValue> sonKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key1"));
360     JSHandle<JSTaggedValue> fatherKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2"));
361     JSHandle<JSTaggedValue> grandfatherKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key3"));
362     JSHandle<JSTaggedValue> sonValue(thread, JSTaggedValue(1));
363     JSHandle<JSTaggedValue> fatherValue(thread, JSTaggedValue(2));
364     JSHandle<JSTaggedValue> grandfatherValue(thread, JSTaggedValue(3));
365 
366     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(son), sonKey, sonValue);
367     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(father), fatherKey, fatherValue);
368     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(grandfather), grandfatherKey, grandfatherValue);
369 
370     bool flag = JSObject::HasProperty(thread, son, sonKey);
371     EXPECT_TRUE(flag);
372     flag = JSObject::HasProperty(thread, son, fatherKey);
373     EXPECT_TRUE(flag);
374     flag = JSObject::HasProperty(thread, son, grandfatherKey);
375     EXPECT_TRUE(flag);
376 }
377 
HWTEST_F_L0(JSObjectTest,HasOwnProperty)378 HWTEST_F_L0(JSObjectTest, HasOwnProperty)
379 {
380     GetPropertyHasOwnPeroperty(thread, true);
381 }
382 
HWTEST_F_L0(JSObjectTest,GetOwnPropertyKeys)383 HWTEST_F_L0(JSObjectTest, GetOwnPropertyKeys)
384 {
385     JSHandle<JSTaggedValue> constructor(thread, JSObjectTestCreate(thread));
386     JSHandle<JSObject> obj =
387         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(constructor), constructor);
388 
389     JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
390     JSHandle<JSTaggedValue> key2(thread->GetEcmaVM()->GetFactory()->NewFromASCII("y"));
391     JSHandle<JSTaggedValue> key3(thread->GetEcmaVM()->GetFactory()->NewFromASCII("3"));
392     JSHandle<JSTaggedValue> key4(thread->GetEcmaVM()->GetFactory()->NewFromASCII("4"));
393     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
394     JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
395     JSHandle<JSTaggedValue> value3(thread, JSTaggedValue(3));
396     JSHandle<JSTaggedValue> value4(thread, JSTaggedValue(4));
397 
398     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, value1);
399     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key2, value2);
400     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key3, value3);
401     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key4, value4);
402 
403     JSHandle<TaggedArray> array = JSObject::GetOwnPropertyKeys(thread, obj);
404     uint32_t length = array->GetLength();
405     EXPECT_EQ(length, 4U);
406     int sum = 0;
407     for (uint32_t i = 0; i < length; i++) {
408         JSHandle<JSTaggedValue> key(thread, array->Get(thread, i));
409         sum += JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->GetInt();
410     }
411     EXPECT_EQ(sum, 10);
412 }
413 
HWTEST_F_L0(JSObjectTest,ObjectCreateMethod)414 HWTEST_F_L0(JSObjectTest, ObjectCreateMethod)
415 {
416     JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
417     JSHandle<JSObject> grandfather = JSObject::ObjectCreate(thread, nullHandle);
418     JSHandle<JSObject> father = JSObject::ObjectCreate(thread, grandfather);
419     JSHandle<JSObject> son = JSObject::ObjectCreate(thread, father);
420 
421     EXPECT_EQ(JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(son)), father.GetTaggedValue());
422     EXPECT_EQ(JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(father)), grandfather.GetTaggedValue());
423     EXPECT_EQ(JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(grandfather)), JSTaggedValue::Null());
424 }
425 
HWTEST_F_L0(JSObjectTest,GetMethod)426 HWTEST_F_L0(JSObjectTest, GetMethod)
427 {
428     JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
429     JSHandle<JSObject> obj = JSObject::ObjectCreate(thread, nullHandle);
430     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
431     JSHandle<JSTaggedValue> func(thread->GetEcmaVM()->GetFactory()->NewJSFunction(env));
432     JSHandle<JSFunction>::Cast(func)->GetJSHClass()->SetCallable(true);
433     EXPECT_TRUE(*func != nullptr);
434     JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("1"));
435     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key, func);
436     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue().GetTaggedValue(),
437               func.GetTaggedValue());
438 }
439 
HWTEST_F_L0(JSObjectTest,EnumerableOwnNames)440 HWTEST_F_L0(JSObjectTest, EnumerableOwnNames)
441 {
442     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
443     JSHandle<JSObject> obj =
444         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
445     EXPECT_TRUE(*obj != nullptr);
446 
447     CString tagCStr = "x";
448     JSHandle<EcmaString> tagString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(&tagCStr[0]);
449     JSHandle<JSTaggedValue> key(tagString);
450 
451     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
452 
453     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key, value);
454     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->GetInt(), 1);
455 
456     JSHandle<TaggedArray> names = JSObject::EnumerableOwnNames(thread, obj);
457 
458     JSHandle<JSTaggedValue> keyFromNames(thread, JSTaggedValue(names->Get(thread, 0)));
459     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), keyFromNames).GetValue()->GetInt(), 1);
460 
461     PropertyDescriptor descNoEnum(thread);
462     descNoEnum.SetEnumerable(false);
463     JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, descNoEnum);
464     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->GetInt(), 1);
465 
466     JSHandle<TaggedArray> namesNoEnum = JSObject::EnumerableOwnNames(thread, obj);
467     EXPECT_TRUE(namesNoEnum->GetLength() == 0U);
468 
469     PropertyDescriptor descEnum(thread);
470     descEnum.SetConfigurable(false);
471     descEnum.SetEnumerable(true);
472     JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, descEnum);
473     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->GetInt(), 1);
474 
475     JSHandle<TaggedArray> namesNoConfig = JSObject::EnumerableOwnNames(thread, obj);
476 
477     JSHandle<JSTaggedValue> keyNoConfig(thread, JSTaggedValue(namesNoConfig->Get(thread, 0)));
478     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), keyNoConfig).GetValue()->GetInt(), 1);
479 }
480 
HWTEST_F_L0(JSObjectTest,SetIntegrityLevelSealed)481 HWTEST_F_L0(JSObjectTest, SetIntegrityLevelSealed)
482 {
483     JSHandle<JSTaggedValue> hclass1(thread, JSObjectTestCreate(thread));
484     JSHandle<JSObject> obj1 =
485         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass1), hclass1);
486     EXPECT_TRUE(*obj1 != nullptr);
487     CString undefinedCStr = "x";
488     JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII(&undefinedCStr[0]));
489     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
490     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1);
491 
492     // test SetIntegrityLevel::SEALED
493     JSHandle<JSObject> jsobject(obj1);
494     bool status1 = JSObject::SetIntegrityLevel(thread, jsobject, IntegrityLevel::SEALED);
495     EXPECT_TRUE(status1);
496     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1).GetValue().GetTaggedValue(),
497               value1.GetTaggedValue());
498     PropertyDescriptor desc1(thread);
499     bool success1 = JSObject::GetOwnProperty(thread, jsobject, key1, desc1);
500     EXPECT_TRUE(success1);
501     EXPECT_EQ(true, desc1.IsWritable());
502     EXPECT_EQ(true, desc1.IsEnumerable());
503     EXPECT_EQ(false, desc1.IsConfigurable());
504 }
505 
HWTEST_F_L0(JSObjectTest,SetIntegrityLevelFrozen)506 HWTEST_F_L0(JSObjectTest, SetIntegrityLevelFrozen)
507 {
508     JSHandle<JSTaggedValue> hclass1(thread, JSObjectTestCreate(thread));
509     JSHandle<JSObject> obj1 =
510         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass1), hclass1);
511     EXPECT_TRUE(*obj1 != nullptr);
512 
513     CString undefinedCStr = "x";
514     JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII(&undefinedCStr[0]));
515     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
516     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1);
517 
518     // test SetIntegrityLevel::FROZEN
519     bool status1 = JSObject::SetIntegrityLevel(thread, obj1, IntegrityLevel::FROZEN);
520     EXPECT_TRUE(status1);
521     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1).GetValue().GetTaggedValue(),
522               value1.GetTaggedValue());
523     PropertyDescriptor desc1(thread);
524     bool success1 = JSObject::GetOwnProperty(thread, obj1, key1, desc1);
525     EXPECT_TRUE(success1);
526     EXPECT_EQ(false, desc1.IsWritable());
527     EXPECT_EQ(true, desc1.IsEnumerable());
528     EXPECT_EQ(false, desc1.IsConfigurable());
529 }
530 
HWTEST_F_L0(JSObjectTest,TestIntegrityLevelSealed)531 HWTEST_F_L0(JSObjectTest, TestIntegrityLevelSealed)
532 {
533     JSHandle<JSTaggedValue> hclass1(thread, JSObjectTestCreate(thread));
534     JSHandle<JSObject> obj1 =
535         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass1), hclass1);
536     CString undefinedCStr = "level";
537     JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII(&undefinedCStr[0]));
538     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
539     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1);
540     obj1->GetJSHClass()->SetExtensible(false);
541 
542     // test SetIntegrityLevel::SEALED
543     bool status1 = JSObject::SetIntegrityLevel(thread, obj1, IntegrityLevel::SEALED);
544     EXPECT_TRUE(status1);
545     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1).GetValue().GetTaggedValue(),
546               value1.GetTaggedValue());
547 
548     PropertyDescriptor desc1(thread);
549     bool success1 = JSObject::GetOwnProperty(thread, obj1, key1, desc1);
550     EXPECT_TRUE(success1);
551     EXPECT_EQ(true, JSObject::TestIntegrityLevel(thread, obj1, IntegrityLevel::SEALED));
552     EXPECT_EQ(false, JSObject::TestIntegrityLevel(thread, obj1, IntegrityLevel::FROZEN));
553 }
554 
HWTEST_F_L0(JSObjectTest,TestIntegrityLevelFrozen)555 HWTEST_F_L0(JSObjectTest, TestIntegrityLevelFrozen)
556 {
557     JSHandle<JSTaggedValue> hclass1(thread, JSObjectTestCreate(thread));
558     JSHandle<JSObject> obj1 =
559         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass1), hclass1);
560     CString undefinedCStr = "level";
561     JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII(&undefinedCStr[0]));
562     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
563     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value1);
564     obj1->GetJSHClass()->SetExtensible(false);
565 
566     // test SetIntegrityLevel::FROZEN
567     bool status1 = JSObject::SetIntegrityLevel(thread, obj1, IntegrityLevel::FROZEN);
568     EXPECT_TRUE(status1);
569     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1).GetValue().GetTaggedValue(),
570               value1.GetTaggedValue());
571 
572     PropertyDescriptor desc1(thread);
573     bool success1 = JSObject::GetOwnProperty(thread, obj1, key1, desc1);
574     EXPECT_TRUE(success1);
575     EXPECT_EQ(true, JSObject::TestIntegrityLevel(thread, obj1, IntegrityLevel::SEALED));
576     EXPECT_EQ(true, JSObject::TestIntegrityLevel(thread, obj1, IntegrityLevel::FROZEN));
577 }
578 
HWTEST_F_L0(JSObjectTest,TestIntegrityLevelWithoutProperty)579 HWTEST_F_L0(JSObjectTest, TestIntegrityLevelWithoutProperty)
580 {
581     JSHandle<JSTaggedValue> hclass1(thread, JSObjectTestCreate(thread));
582     JSHandle<JSTaggedValue> obj1(
583         thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass1), hclass1));
584     JSHandle<JSObject>::Cast(obj1)->GetJSHClass()->SetExtensible(false);
585     CString undefinedCStr = "level";
586     JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII(&undefinedCStr[0]));
587 
588     // test SetIntegrityLevel::FROZEN
589     JSHandle<JSObject> jsobject(obj1);
590     bool status1 = JSObject::SetIntegrityLevel(thread, jsobject, IntegrityLevel::SEALED);
591     EXPECT_TRUE(status1);
592 
593     PropertyDescriptor desc1(thread);
594     bool success1 = JSObject::GetOwnProperty(thread, jsobject, key1, desc1);
595     EXPECT_TRUE(!success1);
596     EXPECT_EQ(true, JSObject::TestIntegrityLevel(thread, jsobject, IntegrityLevel::SEALED));
597     EXPECT_EQ(true, JSObject::TestIntegrityLevel(thread, jsobject, IntegrityLevel::FROZEN));
598 }
599 
TestGetter(EcmaRuntimeCallInfo * argv)600 JSTaggedValue TestGetter(EcmaRuntimeCallInfo *argv)
601 {
602     auto thread = argv->GetThread();
603     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
604     JSHandle<JSObject> obj(BuiltinsBase::GetThis(argv));
605     JSHandle<JSTaggedValue> key(factory->NewFromASCII("y"));
606     JSTaggedValue value = JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue().GetTaggedValue();
607 
608     return JSTaggedValue(value.GetInt() + 1);
609 }
610 
HWTEST_F_L0(JSObjectTest,Getter)611 HWTEST_F_L0(JSObjectTest, Getter)
612 {
613     JSHandle<JSTaggedValue> hclass1(thread, JSObjectTestCreate(thread));
614     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
615     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass1), hclass1);
616     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("x"));
617     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("y"));
618     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
619     JSHandle<JSFunction> getter =
620         thread->GetEcmaVM()->GetFactory()->NewJSFunction(env, reinterpret_cast<void *>(TestGetter));
621 
622     PropertyDescriptor desc1(thread);
623     desc1.SetGetter(JSHandle<JSTaggedValue>::Cast(getter));
624     bool success1 = JSObject::DefineOwnProperty(thread, obj, key1, desc1);
625     EXPECT_TRUE(success1);
626 
627     PropertyDescriptor desc2(thread);
628     desc2.SetValue(JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)));
629     success1 = JSObject::DefineOwnProperty(thread, obj, key2, desc2);
630     EXPECT_TRUE(success1);
631 
632     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key1).GetValue().GetTaggedValue(),
633               JSTaggedValue(2));
634 }
635 
TestSetter(EcmaRuntimeCallInfo * argv)636 JSTaggedValue TestSetter(EcmaRuntimeCallInfo *argv)
637 {
638     JSThread *thread = argv->GetThread();
639     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
640     JSHandle<JSObject> obj(BuiltinsBase::GetThis(argv));
641     JSHandle<JSTaggedValue> key(factory->NewFromASCII("y"));
642     JSTaggedValue value(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue().GetTaggedValue());
643     JSHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue(value.GetInt() + 1));
644     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key, valueHandle);
645 
646     return JSTaggedValue(JSTaggedValue::True());
647 }
648 
HWTEST_F_L0(JSObjectTest,Setter)649 HWTEST_F_L0(JSObjectTest, Setter)
650 {
651     JSHandle<JSTaggedValue> hclass1(thread, JSObjectTestCreate(thread));
652     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
653     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass1), hclass1);
654     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("x"));
655     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("y"));
656     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
657     JSHandle<JSFunction> setter =
658         thread->GetEcmaVM()->GetFactory()->NewJSFunction(env, reinterpret_cast<void *>(TestSetter));
659 
660     PropertyDescriptor desc1(thread);
661     desc1.SetSetter(JSHandle<JSTaggedValue>::Cast(setter));
662     bool success1 = JSObject::DefineOwnProperty(thread, obj, key1, desc1);
663     EXPECT_TRUE(success1);
664 
665     PropertyDescriptor desc2(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), true, true, true);
666     success1 = JSObject::DefineOwnProperty(thread, obj, key2, desc2);
667     EXPECT_TRUE(success1);
668 
669     JSHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue::Undefined());
670     EXPECT_TRUE(JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj), key1, valueHandle));
671     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key2).GetValue().GetTaggedValue(),
672               JSTaggedValue(2));
673 }
674 
HWTEST_F_L0(JSObjectTest,SpeciesConstructor)675 HWTEST_F_L0(JSObjectTest, SpeciesConstructor)
676 {
677     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
678     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
679     const GlobalEnvConstants *globalConst = thread->GlobalConstants();
680     JSHandle<JSFunction> constructorFunc =
681         factory->NewJSFunction(env, static_cast<void *>(nullptr), FunctionKind::BASE_CONSTRUCTOR);
682     JSHandle<JSTaggedValue> constructorFuncValue(constructorFunc);
683     constructorFunc->GetJSHClass()->SetExtensible(true);
684     JSFunction::NewJSFunctionPrototype(thread, constructorFunc);
685 
686     JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
687     JSHandle<JSTaggedValue> undefinedValue(thread, JSTaggedValue::Undefined());
688     JSHandle<JSObject> protoObj = JSObject::ObjectCreate(thread, nullHandle);
689     JSHandle<JSTaggedValue> protoObjValue(protoObj);
690 
691     JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
692     JSObject::SetProperty(thread, protoObjValue, constructorKey, constructorFuncValue);
693 
694     factory->NewJSObjectByConstructor(constructorFunc, JSHandle<JSTaggedValue>::Cast(constructorFunc));
695     JSHandle<JSFunction> speciesConstruct =
696         factory->NewJSFunction(env, static_cast<void *>(nullptr), FunctionKind::BASE_CONSTRUCTOR);
697     JSHandle<JSTaggedValue> speciesConstructValue(speciesConstruct);
698     constructorFunc->GetJSHClass()->SetExtensible(true);
699     JSFunction::MakeConstructor(thread, speciesConstruct, undefinedValue);
700 
701     JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol();
702     JSObject::SetProperty(thread, constructorFuncValue, speciesSymbol, speciesConstructValue);
703 
704     JSTaggedValue speciesValue =
705         JSObject::SpeciesConstructor(thread, protoObj, constructorFuncValue).GetTaggedValue();
706     EXPECT_EQ(speciesValue, speciesConstructValue.GetTaggedValue());
707 }
708 
TestUndefinedGetter(EcmaRuntimeCallInfo * argv)709 JSTaggedValue TestUndefinedGetter([[maybe_unused]] EcmaRuntimeCallInfo *argv)
710 {
711     // 10 : test case
712     return JSTaggedValue(10);
713 }
714 
TestUndefinedSetter(EcmaRuntimeCallInfo * argv)715 JSTaggedValue TestUndefinedSetter([[maybe_unused]] EcmaRuntimeCallInfo *argv)
716 {
717     // 10 : test case
718     return JSTaggedValue(10);
719 }
720 
GetterOrSetterIsUndefined(JSThread * thread,JSHandle<JSTaggedValue> & key)721 JSHandle<JSObject> GetterOrSetterIsUndefined(JSThread *thread, JSHandle<JSTaggedValue>& key)
722 {
723     JSHandle<JSTaggedValue> hclass1(thread, JSObjectTestCreate(thread));
724     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
725     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(hclass1), hclass1);
726 
727     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
728     JSHandle<JSFunction> getter =
729         thread->GetEcmaVM()->GetFactory()->NewJSFunction(env, reinterpret_cast<void *>(TestUndefinedGetter));
730     JSHandle<JSFunction> setter =
731         thread->GetEcmaVM()->GetFactory()->NewJSFunction(env, reinterpret_cast<void *>(TestUndefinedSetter));
732 
733     PropertyDescriptor desc1(thread);
734     desc1.SetGetter(JSHandle<JSTaggedValue>::Cast(getter));
735     desc1.SetSetter(JSHandle<JSTaggedValue>::Cast(setter));
736     desc1.SetConfigurable(true);
737     desc1.SetEnumerable(true);
738     bool success1 = JSObject::DefineOwnProperty(thread, obj, key, desc1);
739     EXPECT_TRUE(success1);
740     return obj;
741 }
742 
HWTEST_F_L0(JSObjectTest,GetterIsUndefined)743 HWTEST_F_L0(JSObjectTest, GetterIsUndefined)
744 {
745     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
746     JSHandle<JSTaggedValue> unGetter(thread, JSTaggedValue::Undefined());
747     JSHandle<JSTaggedValue> key(factory->NewFromASCII("property"));
748     auto obj = GetterOrSetterIsUndefined(thread, key);
749     PropertyDescriptor desc2(thread);
750     desc2.SetGetter(unGetter);
751     bool success2 = JSObject::DefineOwnProperty(thread, obj, key, desc2);
752     EXPECT_TRUE(success2);
753 
754     PropertyDescriptor desc(thread);
755     bool success = JSObject::GetOwnProperty(thread, obj, key, desc);
756     EXPECT_TRUE(success);
757     EXPECT_TRUE(desc.GetSetter()->IsJSFunction());
758     EXPECT_TRUE(desc.GetGetter()->IsUndefined());
759 }
760 
HWTEST_F_L0(JSObjectTest,SetterIsUndefined)761 HWTEST_F_L0(JSObjectTest, SetterIsUndefined)
762 {
763     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
764     JSHandle<JSTaggedValue> unSetter(thread, JSTaggedValue::Undefined());
765     JSHandle<JSTaggedValue> key(factory->NewFromASCII("property"));
766     auto obj = GetterOrSetterIsUndefined(thread, key);
767     PropertyDescriptor desc2(thread);
768     desc2.SetSetter(unSetter);
769     bool success2 = JSObject::DefineOwnProperty(thread, obj, key, desc2);
770     EXPECT_TRUE(success2);
771 
772     PropertyDescriptor desc(thread);
773     bool success = JSObject::GetOwnProperty(thread, obj, key, desc);
774     EXPECT_TRUE(success);
775     EXPECT_TRUE(desc.GetSetter()->IsUndefined());
776 
777     EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue().GetTaggedValue(),
778               JSTaggedValue(10));
779 }
780 
HWTEST_F_L0(JSObjectTest,Transitions)781 HWTEST_F_L0(JSObjectTest, Transitions)
782 {
783     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
784     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
785     JSHandle<JSObject> obj1 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
786     JSHandle<JSObject> obj2 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
787 
788     JSHandle<JSHClass> hc1(thread, obj1->GetJSHClass());
789     JSHandle<JSHClass> hc2(thread, obj2->GetJSHClass());
790     EXPECT_EQ(hc1.GetTaggedValue(), hc2.GetTaggedValue());
791 
792     JSHandle<JSTaggedValue> key1(factory->NewFromASCII("x"));
793     JSHandle<JSTaggedValue> key2(factory->NewFromASCII("y"));
794     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
795 
796     // key1
797     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, value);
798     JSHandle<JSHClass> hc3(thread, obj1->GetJSHClass());
799     EXPECT_NE(hc1.GetTaggedValue(), hc3.GetTaggedValue());
800 
801     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key1, value);
802     JSHandle<JSHClass> hc4(thread, obj2->GetJSHClass());
803     EXPECT_EQ(hc3.GetTaggedValue(), hc4.GetTaggedValue());
804 
805     // key2
806     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2, value);
807     JSHandle<JSHClass> hc5(thread, obj1->GetJSHClass());
808     EXPECT_NE(hc3.GetTaggedValue(), hc5.GetTaggedValue());
809 
810     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key2, value);
811     JSHandle<JSHClass> hc6(thread, obj2->GetJSHClass());
812     EXPECT_EQ(hc5.GetTaggedValue(), hc6.GetTaggedValue());
813 }
814 
HWTEST_F_L0(JSObjectTest,FastToSlow)815 HWTEST_F_L0(JSObjectTest, FastToSlow)
816 {
817     auto ecmaVM = thread->GetEcmaVM();
818     ObjectFactory *factory = ecmaVM->GetFactory();
819 
820     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
821     JSHandle<JSObject> obj1 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
822 
823     JSMutableHandle<EcmaString> key(thread, factory->NewFromASCII("x"));
824     JSMutableHandle<JSTaggedValue> number(thread, JSTaggedValue(0));
825     JSMutableHandle<JSTaggedValue> newkey(thread, JSTaggedValue(0));
826     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
827 
828     ecmaVM->SetEnableForceGC(false);
829     for (uint32_t i = 0; i < PropertyAttributes::MAX_FAST_PROPS_CAPACITY; i++) {
830         number.Update(JSTaggedValue(i));
831         number.Update(JSTaggedValue::ToString(thread, number).GetTaggedValue());
832         EcmaString *newString = *factory->ConcatFromString(key, JSTaggedValue::ToString(thread, number));
833         newkey.Update(JSTaggedValue(newString));
834         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), newkey, value);
835     }
836     ecmaVM->SetEnableForceGC(true);
837 
838     EXPECT_FALSE(TaggedArray::Cast(obj1->GetProperties(thread).GetTaggedObject())->IsDictionaryMode());
839 
840     number.Update(JSTaggedValue(PropertyAttributes::MAX_FAST_PROPS_CAPACITY));
841     number.Update(JSTaggedValue::ToString(thread, number).GetTaggedValue());
842     EcmaString *newString = *factory->ConcatFromString(key, JSTaggedValue::ToString(thread, number));
843     newkey.Update(JSTaggedValue(newString));
844     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), newkey, value);
845 
846     EXPECT_TRUE(TaggedArray::Cast(obj1->GetProperties(thread).GetTaggedObject())->IsDictionaryMode());
847     NameDictionary *dict = NameDictionary::Cast(obj1->GetProperties(thread).GetTaggedObject());
848     EXPECT_EQ(dict->EntriesCount(), static_cast<int>(PropertyAttributes::MAX_FAST_PROPS_CAPACITY + 1));
849     EXPECT_EQ(dict->NextEnumerationIndex(thread),
850               static_cast<int>(PropertyAttributes::MAX_FAST_PROPS_CAPACITY + 1));
851 }
852 
HWTEST_F_L0(JSObjectTest,DeleteMiddle)853 HWTEST_F_L0(JSObjectTest, DeleteMiddle)
854 {
855     auto ecmaVM = thread->GetEcmaVM();
856     ObjectFactory *factory = ecmaVM->GetFactory();
857 
858     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
859     JSHandle<JSObject> obj1 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
860 
861     JSMutableHandle<EcmaString> key(thread, factory->NewFromASCII("x"));
862     JSMutableHandle<JSTaggedValue> number(thread, JSTaggedValue(0));
863     JSMutableHandle<JSTaggedValue> newkey(thread, JSTaggedValue(0));
864     JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
865 
866     for (uint32_t i = 0; i < 10; i++) {
867         number.Update(JSTaggedValue(i));
868         number.Update(JSTaggedValue::ToString(thread, number).GetTaggedValue());
869         EcmaString *newString = *factory->ConcatFromString(key, JSTaggedValue::ToString(thread, number));
870         newkey.Update(JSTaggedValue(newString));
871         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), newkey, value);
872     }
873 
874     EXPECT_FALSE(TaggedArray::Cast(obj1->GetProperties(thread).GetTaggedObject())->IsDictionaryMode());
875 
876     JSMutableHandle<JSTaggedValue> key5(thread, factory->NewFromASCII("x5"));
877     JSObject::DeleteProperty(thread, (obj1), key5);
878 
879     EXPECT_TRUE(TaggedArray::Cast(obj1->GetProperties(thread).GetTaggedObject())->IsDictionaryMode());
880     NameDictionary *dict = NameDictionary::Cast(obj1->GetProperties(thread).GetTaggedObject());
881     EXPECT_EQ(dict->EntriesCount(), 9);
882     EXPECT_FALSE(JSObject::HasProperty(thread, obj1, key5));
883 }
884 
HWTEST_F_L0(JSObjectTest,ElementFastToSlow)885 HWTEST_F_L0(JSObjectTest, ElementFastToSlow)
886 {
887     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
888     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
889     JSHandle<JSTaggedValue> key0(thread, JSTaggedValue(0));
890     JSHandle<JSTaggedValue> key1(thread, JSTaggedValue(1));
891     JSHandle<JSTaggedValue> key2(thread, JSTaggedValue(2));
892     JSHandle<JSTaggedValue> key2000(thread, JSTaggedValue(2000));
893     JSHandle<JSTaggedValue> keyStr(factory->NewFromASCII("str"));
894 
895     // test dictionary [0,1,2,...,2000]
896     JSHandle<JSObject> obj1 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
897     EXPECT_TRUE(!TaggedArray::Cast(obj1->GetElements(thread).GetTaggedObject())->IsDictionaryMode());
898     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), keyStr, key2);
899     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key0, key0);
900     EXPECT_TRUE(!TaggedArray::Cast(obj1->GetElements(thread).GetTaggedObject())->IsDictionaryMode());
901     JSHandle<JSHClass> hclass(thread, obj1->GetJSHClass());
902     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key1, key1);
903     EXPECT_TRUE(!TaggedArray::Cast(obj1->GetElements(thread).GetTaggedObject())->IsDictionaryMode());
904     EXPECT_EQ(obj1->GetJSHClass(), *hclass);
905 
906     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), key2000, key2000);
907     EXPECT_TRUE(TaggedArray::Cast(obj1->GetElements(thread).GetTaggedObject())->IsDictionaryMode());
908     JSTaggedValue value =
909         JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj1), keyStr).GetValue().GetTaggedValue();
910     EXPECT_EQ(value, key2.GetTaggedValue());
911     // test holey [0,,2]
912     JSHandle<JSObject> obj2 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
913     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key0, key0);
914     EXPECT_TRUE(!TaggedArray::Cast(obj2->GetElements(thread).GetTaggedObject())->IsDictionaryMode());
915     JSHandle<JSHClass> hclass2(thread, obj2->GetJSHClass());
916     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), key2, key2);
917     EXPECT_TRUE(!TaggedArray::Cast(obj2->GetElements(thread).GetTaggedObject())->IsDictionaryMode());
918     EXPECT_EQ(obj2->GetJSHClass(), *hclass2);
919     // test change attr
920     JSHandle<JSObject> obj3 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
921     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj3), key0, key0);
922     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj3), key1, key1);
923     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj3), key2, key2);
924     EXPECT_TRUE(!TaggedArray::Cast(obj3->GetElements(thread).GetTaggedObject())->IsDictionaryMode());
925     PropertyDescriptor desc(thread);
926     desc.SetValue(key1);
927     desc.SetWritable(false);
928     JSObject::DefineOwnProperty(thread, obj3, key1, desc);
929     EXPECT_TRUE(TaggedArray::Cast(obj3->GetElements(thread).GetTaggedObject())->IsDictionaryMode());
930     // test delete element
931     JSHandle<JSObject> obj4 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
932     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj4), key0, key0);
933     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj4), key1, key1);
934     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj4), key2, key2);
935     EXPECT_TRUE(!TaggedArray::Cast(obj4->GetElements(thread).GetTaggedObject())->IsDictionaryMode());
936 
937     JSHandle<JSTaggedValue> value1001(thread, JSTaggedValue(1001));
938     JSHandle<JSObject> obj100 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
939     PropertyDescriptor desc1(thread);
940     desc1.SetValue(value1001);
941     desc1.SetWritable(false);
942     desc1.SetEnumerable(false);
943     desc1.SetConfigurable(false);
944     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj100), key0, key1);
945     JSObject::DefineOwnProperty(thread, obj100, key0, desc1);
946     JSTaggedValue result1001 =
947         JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj100), key0).GetValue().GetTaggedValue();
948     EXPECT_EQ(result1001, value1001.GetTaggedValue());
949 }
950 
HWTEST_F_L0(JSObjectTest,EnableProtoChangeMarker)951 HWTEST_F_L0(JSObjectTest, EnableProtoChangeMarker)
952 {
953     JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
954     JSHandle<JSObject> obj1 = JSObject::ObjectCreate(thread, nullHandle);
955     JSHandle<JSObject> obj2 = JSObject::ObjectCreate(thread, obj1);
956     JSHandle<JSObject> obj3 = JSObject::ObjectCreate(thread, obj2);
957 
958     JSHandle<JSTaggedValue> obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key1"));
959     JSHandle<JSTaggedValue> obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2"));
960     JSHandle<JSTaggedValue> obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key3"));
961     JSHandle<JSTaggedValue> obj1Value(thread, JSTaggedValue(1));
962     JSHandle<JSTaggedValue> obj2Value(thread, JSTaggedValue(2));
963     JSHandle<JSTaggedValue> obj3Value(thread, JSTaggedValue(3));
964 
965     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), obj1Key, obj1Value);
966     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), obj2Key, obj2Value);
967     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj3), obj3Key, obj3Value);
968     JSHandle<JSHClass> obj3Class(thread, obj3->GetJSHClass());
969     JSHandle<JSTaggedValue> resultMarker = JSHClass::EnableProtoChangeMarker(thread, obj3Class);
970     EXPECT_TRUE(resultMarker->IsProtoChangeMarker());
971     bool hasChanged = ProtoChangeMarker::Cast(resultMarker->GetTaggedObject())->GetHasChanged();
972     EXPECT_TRUE(!hasChanged);
973 
974     JSHandle<JSHClass> obj1Class(thread, obj1->GetJSHClass());
975     JSHandle<JSHClass> obj2Class(thread, obj2->GetJSHClass());
976     JSTaggedValue obj2Marker = obj2Class->GetProtoChangeMarker(thread);
977     EXPECT_TRUE(obj2Marker.IsProtoChangeMarker());
978     bool hasChanged2 = ProtoChangeMarker::Cast(obj2Marker.GetTaggedObject())->GetHasChanged();
979     EXPECT_TRUE(!hasChanged2);
980 
981     JSTaggedValue obj1Marker = obj1Class->GetProtoChangeMarker(thread);
982     EXPECT_TRUE(!obj1Marker.IsProtoChangeMarker());
983 
984     JSTaggedValue protoDetails2 = obj2Class->GetProtoChangeDetails(thread);
985     EXPECT_TRUE(protoDetails2.IsProtoChangeDetails());
986     JSTaggedValue protoDetails1 = obj1Class->GetProtoChangeDetails(thread);
987     EXPECT_TRUE(protoDetails1.IsProtoChangeDetails());
988     JSTaggedValue listeners1 = ProtoChangeDetails::Cast(protoDetails1.GetTaggedObject())->GetChangeListener(thread);
989     EXPECT_TRUE(!listeners1.IsUndefined());
990     JSTaggedValue listeners2 = ProtoChangeDetails::Cast(protoDetails2.GetTaggedObject())->GetChangeListener(thread);
991     EXPECT_TRUE(listeners2.IsUndefined());
992     uint32_t index = ProtoChangeDetails::Cast(protoDetails2.GetTaggedObject())->GetRegisterIndex();
993     JSTaggedValue listenersResult = ChangeListener::Cast(listeners1.GetTaggedObject())->Get(thread, index);
994     EXPECT_TRUE(listenersResult == obj2Class.GetTaggedValue());
995 }
996 
HWTEST_F_L0(JSObjectTest,BuildRegisterTree)997 HWTEST_F_L0(JSObjectTest, BuildRegisterTree)
998 {
999     JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
1000     JSHandle<JSObject> obj1 = JSObject::ObjectCreate(thread, nullHandle);
1001     JSHandle<JSObject> obj2 = JSObject::ObjectCreate(thread, obj1);
1002     JSHandle<JSObject> obj3 = JSObject::ObjectCreate(thread, obj2);
1003     JSHandle<JSObject> obj4 = JSObject::ObjectCreate(thread, obj2);
1004     JSHandle<JSObject> obj5 = JSObject::ObjectCreate(thread, obj4);
1005     JSHandle<JSObject> obj6 = JSObject::ObjectCreate(thread, obj2);
1006     JSHandle<JSObject> obj7 = JSObject::ObjectCreate(thread, obj6);
1007 
1008     JSHandle<JSTaggedValue> obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key1"));
1009     JSHandle<JSTaggedValue> obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2"));
1010     JSHandle<JSTaggedValue> obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key3"));
1011     JSHandle<JSTaggedValue> obj4Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key4"));
1012     JSHandle<JSTaggedValue> obj5Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key5"));
1013     JSHandle<JSTaggedValue> obj6Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key6"));
1014     JSHandle<JSTaggedValue> obj7Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key7"));
1015 
1016     JSHandle<JSTaggedValue> obj1Value(thread, JSTaggedValue(1));
1017     JSHandle<JSTaggedValue> obj2Value(thread, JSTaggedValue(2));
1018     JSHandle<JSTaggedValue> obj3Value(thread, JSTaggedValue(3));
1019     JSHandle<JSTaggedValue> obj4Value(thread, JSTaggedValue(4));
1020     JSHandle<JSTaggedValue> obj5Value(thread, JSTaggedValue(5));
1021     JSHandle<JSTaggedValue> obj6Value(thread, JSTaggedValue(6));
1022     JSHandle<JSTaggedValue> obj7Value(thread, JSTaggedValue(7));
1023 
1024     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), obj1Key, obj1Value);
1025     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), obj2Key, obj2Value);
1026     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj3), obj3Key, obj3Value);
1027     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj4), obj4Key, obj4Value);
1028     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj5), obj5Key, obj5Value);
1029     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj6), obj6Key, obj6Value);
1030     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj7), obj7Key, obj7Value);
1031 
1032     JSHandle<JSHClass> obj1Class(thread, obj1->GetJSHClass());
1033     JSHandle<JSHClass> obj2Class(thread, obj2->GetJSHClass());
1034     JSHandle<JSHClass> obj3Class(thread, obj3->GetJSHClass());
1035     JSHandle<JSHClass> obj4Class(thread, obj4->GetJSHClass());
1036     JSHandle<JSHClass> obj5Class(thread, obj5->GetJSHClass());
1037     JSHandle<JSHClass> obj6Class(thread, obj6->GetJSHClass());
1038     JSHandle<JSHClass> obj7Class(thread, obj7->GetJSHClass());
1039 
1040     JSHandle<JSTaggedValue> result3Marker = JSHClass::EnableProtoChangeMarker(thread, obj3Class);
1041     JSHandle<JSTaggedValue> result5Marker = JSHClass::EnableProtoChangeMarker(thread, obj5Class);
1042     EXPECT_TRUE(result3Marker->IsProtoChangeMarker());
1043     EXPECT_TRUE(!(ProtoChangeMarker::Cast(result3Marker->GetTaggedObject())->GetHasChanged()));
1044     EXPECT_TRUE(result5Marker->IsProtoChangeMarker());
1045     EXPECT_TRUE(!(ProtoChangeMarker::Cast(result5Marker->GetTaggedObject())->GetHasChanged()));
1046 
1047     EXPECT_TRUE(obj4Class->GetProtoChangeMarker(thread).IsProtoChangeMarker());
1048     EXPECT_TRUE(!obj6Class->GetProtoChangeMarker(thread).IsProtoChangeMarker());
1049 
1050     JSHandle<JSTaggedValue> result7Marker = JSHClass::EnableProtoChangeMarker(thread, obj7Class);
1051     EXPECT_TRUE(result7Marker->IsProtoChangeMarker());
1052     EXPECT_TRUE(!(ProtoChangeMarker::Cast(result7Marker->GetTaggedObject())->GetHasChanged()));
1053 
1054     JSTaggedValue protoDetails1 = obj1Class->GetProtoChangeDetails(thread);
1055     EXPECT_TRUE(protoDetails1.IsProtoChangeDetails());
1056     JSTaggedValue listeners1Value =
1057         ProtoChangeDetails::Cast(protoDetails1.GetTaggedObject())->GetChangeListener(thread);
1058     EXPECT_TRUE(listeners1Value != JSTaggedValue(0));
1059     JSHandle<ChangeListener> listeners1(thread, listeners1Value.GetTaggedObject());
1060     JSTaggedValue protoDetails2 = obj2Class->GetProtoChangeDetails(thread);
1061     EXPECT_TRUE(protoDetails2.IsProtoChangeDetails());
1062     uint32_t index2 = ProtoChangeDetails::Cast(protoDetails2.GetTaggedObject())->GetRegisterIndex();
1063     EXPECT_TRUE(listeners1->Get(thread, index2) == obj2Class.GetTaggedValue());
1064 
1065     JSTaggedValue listeners2Value =
1066         ProtoChangeDetails::Cast(protoDetails2.GetTaggedObject())->GetChangeListener(thread);
1067     EXPECT_TRUE(listeners2Value != JSTaggedValue(0));
1068     JSHandle<ChangeListener> listeners2(thread, listeners2Value.GetTaggedObject());
1069     JSTaggedValue protoDetails4 = obj4Class->GetProtoChangeDetails(thread);
1070     JSTaggedValue protoDetails6 = obj6Class->GetProtoChangeDetails(thread);
1071     EXPECT_TRUE(protoDetails4.IsProtoChangeDetails());
1072     EXPECT_TRUE(protoDetails6.IsProtoChangeDetails());
1073     uint32_t index4 = ProtoChangeDetails::Cast(protoDetails4.GetTaggedObject())->GetRegisterIndex();
1074     EXPECT_TRUE(listeners2->Get(thread, index4) == obj4Class.GetTaggedValue());
1075     uint32_t index6 = ProtoChangeDetails::Cast(protoDetails6.GetTaggedObject())->GetRegisterIndex();
1076     EXPECT_TRUE(listeners2->Get(thread, index6) == obj6Class.GetTaggedValue());
1077 
1078     EXPECT_TRUE(listeners1->GetEnd() == 1U);
1079     EXPECT_TRUE(listeners2->GetEnd() == 2U);
1080 }
1081 
HWTEST_F_L0(JSObjectTest,NoticeThroughChain)1082 HWTEST_F_L0(JSObjectTest, NoticeThroughChain)
1083 {
1084     JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
1085     JSHandle<JSObject> obj1 = JSObject::ObjectCreate(thread, nullHandle);
1086     JSHandle<JSObject> obj2 = JSObject::ObjectCreate(thread, obj1);
1087     JSHandle<JSObject> obj3 = JSObject::ObjectCreate(thread, obj2);
1088     JSHandle<JSObject> obj4 = JSObject::ObjectCreate(thread, obj2);
1089     JSHandle<JSObject> obj5 = JSObject::ObjectCreate(thread, obj4);
1090     JSHandle<JSObject> obj6 = JSObject::ObjectCreate(thread, obj2);
1091     JSHandle<JSObject> obj7 = JSObject::ObjectCreate(thread, obj6);
1092 
1093     JSHandle<JSTaggedValue> obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key1"));
1094     JSHandle<JSTaggedValue> obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2"));
1095     JSHandle<JSTaggedValue> obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key3"));
1096     JSHandle<JSTaggedValue> obj4Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key4"));
1097     JSHandle<JSTaggedValue> obj5Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key5"));
1098     JSHandle<JSTaggedValue> obj6Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key6"));
1099     JSHandle<JSTaggedValue> obj7Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key7"));
1100 
1101     JSHandle<JSTaggedValue> obj1Value(thread, JSTaggedValue(1));
1102     JSHandle<JSTaggedValue> obj2Value(thread, JSTaggedValue(2));
1103     JSHandle<JSTaggedValue> obj3Value(thread, JSTaggedValue(3));
1104     JSHandle<JSTaggedValue> obj4Value(thread, JSTaggedValue(4));
1105     JSHandle<JSTaggedValue> obj5Value(thread, JSTaggedValue(5));
1106     JSHandle<JSTaggedValue> obj6Value(thread, JSTaggedValue(6));
1107     JSHandle<JSTaggedValue> obj7Value(thread, JSTaggedValue(7));
1108 
1109     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), obj1Key, obj1Value);
1110     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), obj2Key, obj2Value);
1111     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj3), obj3Key, obj3Value);
1112     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj4), obj4Key, obj4Value);
1113     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj5), obj5Key, obj5Value);
1114     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj6), obj6Key, obj6Value);
1115     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj7), obj7Key, obj7Value);
1116 
1117     JSHandle<JSHClass> obj1Class(thread, obj1->GetJSHClass());
1118     JSHandle<JSHClass> obj2Class(thread, obj2->GetJSHClass());
1119     JSHandle<JSHClass> obj3Class(thread, obj3->GetJSHClass());
1120     JSHandle<JSHClass> obj4Class(thread, obj4->GetJSHClass());
1121     JSHandle<JSHClass> obj5Class(thread, obj5->GetJSHClass());
1122     JSHandle<JSHClass> obj6Class(thread, obj6->GetJSHClass());
1123     JSHandle<JSHClass> obj7Class(thread, obj7->GetJSHClass());
1124 
1125     JSHClass::EnableProtoChangeMarker(thread, obj3Class);
1126     JSHClass::EnableProtoChangeMarker(thread, obj7Class);
1127     JSHClass::EnableProtoChangeMarker(thread, obj5Class);
1128 
1129     JSHClass::NoticeThroughChain(thread, obj2Class);
1130     JSHClass::UnregisterOnProtoChain(thread, obj2Class);
1131     JSTaggedValue protoDetails1 = obj1Class->GetProtoChangeDetails(thread);
1132     EXPECT_TRUE(protoDetails1.IsProtoChangeDetails());
1133     JSTaggedValue listeners1Value =
1134         ProtoChangeDetails::Cast(protoDetails1.GetTaggedObject())->GetChangeListener(thread);
1135     EXPECT_TRUE(listeners1Value != JSTaggedValue(0));
1136     JSHandle<ChangeListener> listeners1(thread, listeners1Value.GetTaggedObject());
1137     uint32_t holeIndex = ChangeListener::CheckHole(thread, listeners1);
1138     EXPECT_TRUE(holeIndex == 0U);
1139 
1140     JSTaggedValue protoDetails2 = obj2Class->GetProtoChangeDetails(thread);
1141     EXPECT_TRUE(protoDetails2.IsProtoChangeDetails());
1142     JSTaggedValue listeners2Value =
1143         ProtoChangeDetails::Cast(protoDetails2.GetTaggedObject())->GetChangeListener(thread);
1144     EXPECT_TRUE(listeners2Value != JSTaggedValue(0));
1145     uint32_t index2 = ProtoChangeDetails::Cast(protoDetails2.GetTaggedObject())->GetRegisterIndex();
1146     EXPECT_TRUE(listeners1->Get(thread, index2).IsHole());
1147 
1148     JSTaggedValue obj6Marker = obj6Class->GetProtoChangeMarker(thread);
1149     EXPECT_TRUE(obj6Marker.IsProtoChangeMarker());
1150     bool hasChanged6 = ProtoChangeMarker::Cast(obj6Marker.GetTaggedObject())->GetHasChanged();
1151     EXPECT_TRUE(hasChanged6);
1152 
1153     JSTaggedValue obj4Marker = obj4Class->GetProtoChangeMarker(thread);
1154     EXPECT_TRUE(obj4Marker.IsProtoChangeMarker());
1155     bool hasChanged4 = ProtoChangeMarker::Cast(obj4Marker.GetTaggedObject())->GetHasChanged();
1156     EXPECT_TRUE(hasChanged4);
1157 }
1158 
HWTEST_F_L0(JSObjectTest,ChangeProtoAndNoticeTheChain)1159 HWTEST_F_L0(JSObjectTest, ChangeProtoAndNoticeTheChain)
1160 {
1161     JSHandle<JSObject> nullHandle(thread, JSTaggedValue::Null());
1162     JSHandle<JSObject> obj1 = JSObject::ObjectCreate(thread, nullHandle);
1163     JSHandle<JSObject> obj2 = JSObject::ObjectCreate(thread, obj1);
1164     JSHandle<JSObject> obj3 = JSObject::ObjectCreate(thread, obj1);
1165     JSHandle<JSObject> obj4 = JSObject::ObjectCreate(thread, obj2);
1166     JSHandle<JSObject> obj5 = JSObject::ObjectCreate(thread, obj4);
1167     JSHandle<JSObject> obj6 = JSObject::ObjectCreate(thread, obj2);
1168     JSHandle<JSObject> obj7 = JSObject::ObjectCreate(thread, obj6);
1169 
1170     JSHandle<JSTaggedValue> obj1Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key1"));
1171     JSHandle<JSTaggedValue> obj2Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key2"));
1172     JSHandle<JSTaggedValue> obj3Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key3"));
1173     JSHandle<JSTaggedValue> obj4Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key4"));
1174     JSHandle<JSTaggedValue> obj5Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key5"));
1175     JSHandle<JSTaggedValue> obj6Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key6"));
1176     JSHandle<JSTaggedValue> obj7Key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("key7"));
1177 
1178     JSHandle<JSTaggedValue> obj1Value(thread, JSTaggedValue(1));
1179     JSHandle<JSTaggedValue> obj2Value(thread, JSTaggedValue(2));
1180     JSHandle<JSTaggedValue> obj3Value(thread, JSTaggedValue(3));
1181     JSHandle<JSTaggedValue> obj4Value(thread, JSTaggedValue(4));
1182     JSHandle<JSTaggedValue> obj5Value(thread, JSTaggedValue(5));
1183     JSHandle<JSTaggedValue> obj6Value(thread, JSTaggedValue(6));
1184     JSHandle<JSTaggedValue> obj7Value(thread, JSTaggedValue(7));
1185 
1186     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj1), obj1Key, obj1Value);
1187     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj2), obj2Key, obj2Value);
1188     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj3), obj3Key, obj3Value);
1189     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj4), obj4Key, obj4Value);
1190     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj5), obj5Key, obj5Value);
1191     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj6), obj6Key, obj6Value);
1192     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(obj7), obj7Key, obj7Value);
1193 
1194     JSHandle<JSHClass> obj5Class(thread, obj5->GetJSHClass());
1195     JSHandle<JSHClass> obj7Class(thread, obj7->GetJSHClass());
1196 
1197     JSHClass::EnableProtoChangeMarker(thread, obj7Class);
1198     JSHClass::EnableProtoChangeMarker(thread, obj5Class);
1199 
1200     JSObject::SetPrototype(thread, obj2, JSHandle<JSTaggedValue>(obj3));
1201 
1202     JSHandle<JSHClass> obj1Class(thread, obj1->GetJSHClass());
1203     JSHandle<JSHClass> obj2Class(thread, obj2->GetJSHClass());
1204     JSHandle<JSHClass> obj3Class(thread, obj3->GetJSHClass());
1205     JSHandle<JSHClass> obj4Class(thread, obj4->GetJSHClass());
1206     JSHandle<JSHClass> obj6Class(thread, obj6->GetJSHClass());
1207 
1208     JSTaggedValue obj6Marker = obj6Class->GetProtoChangeMarker(thread);
1209     EXPECT_TRUE(obj6Marker.IsProtoChangeMarker());
1210     bool hasChanged6 = ProtoChangeMarker::Cast(obj6Marker.GetTaggedObject())->GetHasChanged();
1211     EXPECT_TRUE(hasChanged6);
1212 
1213     JSTaggedValue obj4Marker = obj4Class->GetProtoChangeMarker(thread);
1214     EXPECT_TRUE(obj4Marker.IsProtoChangeMarker());
1215     bool hasChanged4 = ProtoChangeMarker::Cast(obj4Marker.GetTaggedObject())->GetHasChanged();
1216     EXPECT_TRUE(hasChanged4);
1217 
1218     JSTaggedValue protoDetails1 = obj1Class->GetProtoChangeDetails(thread);
1219     EXPECT_TRUE(protoDetails1.IsProtoChangeDetails());
1220     JSTaggedValue protoDetails2 = obj2Class->GetProtoChangeDetails(thread);
1221     EXPECT_TRUE(protoDetails2.IsProtoChangeDetails());
1222     JSTaggedValue protoDetails3 = obj3Class->GetProtoChangeDetails(thread);
1223     EXPECT_TRUE(protoDetails3.IsProtoChangeDetails());
1224     JSTaggedValue protoDetails4 = obj4Class->GetProtoChangeDetails(thread);
1225     EXPECT_TRUE(protoDetails4.IsProtoChangeDetails());
1226     JSTaggedValue protoDetails6 = obj6Class->GetProtoChangeDetails(thread);
1227     EXPECT_TRUE(protoDetails6.IsProtoChangeDetails());
1228 
1229     JSTaggedValue listeners1 = ProtoChangeDetails::Cast(protoDetails1.GetTaggedObject())->GetChangeListener(thread);
1230     EXPECT_TRUE(listeners1 != JSTaggedValue(0));
1231     JSTaggedValue listeners2 = ProtoChangeDetails::Cast(protoDetails2.GetTaggedObject())->GetChangeListener(thread);
1232     EXPECT_TRUE(listeners2 != JSTaggedValue(0));
1233     JSTaggedValue listeners3 = ProtoChangeDetails::Cast(protoDetails3.GetTaggedObject())->GetChangeListener(thread);
1234     EXPECT_TRUE(listeners3 != JSTaggedValue(0));
1235 
1236     uint32_t index2 = ProtoChangeDetails::Cast(protoDetails2.GetTaggedObject())->GetRegisterIndex();
1237     uint32_t index3 = ProtoChangeDetails::Cast(protoDetails3.GetTaggedObject())->GetRegisterIndex();
1238     uint32_t index4 = ProtoChangeDetails::Cast(protoDetails4.GetTaggedObject())->GetRegisterIndex();
1239     uint32_t index6 = ProtoChangeDetails::Cast(protoDetails6.GetTaggedObject())->GetRegisterIndex();
1240 
1241     JSTaggedValue result2 = ChangeListener::Cast(listeners3.GetTaggedObject())->Get(thread, index2);
1242     JSTaggedValue result3 = ChangeListener::Cast(listeners1.GetTaggedObject())->Get(thread, index3);
1243     JSTaggedValue result4 = ChangeListener::Cast(listeners2.GetTaggedObject())->Get(thread, index4);
1244     JSTaggedValue result6 = ChangeListener::Cast(listeners2.GetTaggedObject())->Get(thread, index6);
1245 
1246     EXPECT_TRUE(result2 == obj2Class.GetTaggedValue());
1247     EXPECT_TRUE(result3 == obj3Class.GetTaggedValue());
1248     EXPECT_TRUE(result4 == obj4Class.GetTaggedValue());
1249     EXPECT_TRUE(result6 == obj6Class.GetTaggedValue());
1250 }
1251 
HWTEST_F_L0(JSObjectTest,NativePointerField)1252 HWTEST_F_L0(JSObjectTest, NativePointerField)
1253 {
1254     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1255     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
1256     JSHandle<JSObject> obj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
1257     ECMAObject::SetHash(thread, 87, JSHandle<ECMAObject>::Cast(obj));
1258     EXPECT_TRUE(obj->GetHash(thread) == 87);
1259 
1260     ECMAObject::SetNativePointerFieldCount(thread, obj, 1);
1261     char array[] = "Hello World!";
1262     ECMAObject::SetNativePointerField(thread, obj, 0, array, nullptr, nullptr);
1263     int32_t count = obj->GetNativePointerFieldCount(thread);
1264     EXPECT_TRUE(count == 1);
1265     void *pointer = obj->GetNativePointerField(thread, 0);
1266     EXPECT_TRUE(pointer == array);
1267 }
1268 
CreateTestHClass(JSThread * thread)1269 static JSHandle<JSHClass> CreateTestHClass(JSThread *thread)
1270 {
1271     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
1272     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1273     JSHandle<JSTaggedValue> objectFuncPrototype = globalEnv->GetObjectFunctionPrototype();
1274     JSHandle<JSHClass> hclass = factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, objectFuncPrototype);
1275     return hclass;
1276 }
1277 
HWTEST_F_L0(JSObjectTest,UpdateWeakTransitions)1278 HWTEST_F_L0(JSObjectTest, UpdateWeakTransitions)
1279 {
1280     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1281     EcmaVM *vm = thread->GetEcmaVM();
1282     PropertyAttributes attr = PropertyAttributes::Default();
1283 
1284     // Initialize three objects by hc0
1285     JSHandle<JSHClass> hc0 = CreateTestHClass(thread);
1286     JSMutableHandle<JSHClass> hca(thread, JSTaggedValue::Undefined());
1287     JSMutableHandle<JSHClass> hcb(thread, JSTaggedValue::Undefined());
1288     [[maybe_unused]] JSHandle<JSObject> obj0 = factory->NewJSObject(hc0);  // need it to ensure hc0 not be collected
1289     JSHandle<JSObject> obj1 = factory->NewJSObject(hc0);
1290     JSHandle<JSObject> obj2 = factory->NewJSObject(hc0);
1291 
1292     JSHandle<JSTaggedValue> keyA(factory->NewFromASCII("a"));
1293     JSHandle<JSTaggedValue> keyB(factory->NewFromASCII("b"));
1294 
1295     {
1296         // need a new handle scope to ensure no scope refers hc1, hc2.
1297         [[maybe_unused]] EcmaHandleScope handleScope(thread);
1298 
1299         //                               / hc1 (obj1)
1300         // occur transition,  hc0 (obj0)
1301         //                               \ hc2 (obj2)
1302         JSObject::SetProperty(thread, obj1, keyA, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)));
1303         JSObject::SetProperty(thread, obj2, keyB, JSHandle<JSTaggedValue>(thread, JSTaggedValue(2)));
1304 
1305         EXPECT_TRUE(hc0->GetTransitions(thread).IsTaggedArray());
1306         EXPECT_EQ(hc0->FindTransitions(thread, keyA.GetTaggedValue(), attr.GetTaggedValue(), Representation::NONE),
1307             obj1->GetClass());
1308         EXPECT_EQ(hc0->FindTransitions(thread, keyB.GetTaggedValue(), attr.GetTaggedValue(), Representation::NONE),
1309             obj2->GetClass());
1310         hca.Update(JSTaggedValue(obj1->GetClass()));
1311         hcb.Update(JSTaggedValue(obj2->GetClass()));
1312 
1313         //            / hc1 --> hc3 (obj1)
1314         // hc0 (obj0)
1315         //            \ hc2 --> hc4 (obj2)
1316         JSObject::SetProperty(thread, obj1, keyB, JSHandle<JSTaggedValue>(thread, JSTaggedValue(3)));
1317         JSObject::SetProperty(thread, obj2, keyA, JSHandle<JSTaggedValue>(thread, JSTaggedValue(4)));
1318     }
1319 
1320     // collect hc1, hc2
1321     vm->CollectGarbage(TriggerGCType::FULL_GC);
1322 
1323     EXPECT_EQ(hc0->FindTransitions(thread, keyA.GetTaggedValue(), attr.GetTaggedValue(), Representation::NONE),
1324         hca.GetObject<JSHClass>());
1325     EXPECT_EQ(hc0->FindTransitions(thread, keyB.GetTaggedValue(), attr.GetTaggedValue(), Representation::NONE),
1326         hcb.GetObject<JSHClass>());
1327 
1328     JSHandle<JSObject> obj3 = factory->NewJSObject(hc0);
1329     JSHandle<JSObject> obj4 = factory->NewJSObject(hc0);
1330 
1331     //                                  / hc5 (obj3)
1332     // re-occur transition,  hc0 (obj0)
1333     //                                  \ hc6 (obj4)
1334     JSObject::SetProperty(thread, obj3, keyA, JSHandle<JSTaggedValue>(thread, JSTaggedValue(5)));
1335     JSObject::SetProperty(thread, obj4, keyB, JSHandle<JSTaggedValue>(thread, JSTaggedValue(6)));
1336 
1337     EXPECT_TRUE(hc0->GetTransitions(thread).IsTaggedArray());
1338     EXPECT_EQ(hc0->FindTransitions(thread, keyA.GetTaggedValue(), attr.GetTaggedValue(), Representation::NONE),
1339         obj3->GetClass());
1340     EXPECT_EQ(hc0->FindTransitions(thread, keyB.GetTaggedValue(), attr.GetTaggedValue(), Representation::NONE),
1341         obj4->GetClass());
1342     EXPECT_EQ(obj3->GetClass(), hca.GetObject<JSHClass>());
1343     EXPECT_EQ(obj4->GetClass(), hcb.GetObject<JSHClass>());
1344 }
1345 
HWTEST_F_L0(JSObjectTest,CreateObjectFromProperties)1346 HWTEST_F_L0(JSObjectTest, CreateObjectFromProperties)
1347 {
1348     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1349     JSHandle<TaggedArray> properties = factory->NewTaggedArray(2060); // 2060: array length
1350 
1351     JSHandle<EcmaString> key1(factory->NewFromASCII("aa"));
1352     JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
1353 
1354     for (int i = 0; i < 1030; i++) {
1355         JSHandle<EcmaString> key2(factory->NewFromASCII(std::to_string(i)));
1356         JSHandle<EcmaString> key3 =
1357             JSHandle<EcmaString>(thread, EcmaStringAccessor::Concat(thread->GetEcmaVM(), key1, key2));
1358         properties->Set(thread, 2 * i, key3.GetTaggedValue());
1359         properties->Set(thread, 2 * i + 1, value1.GetTaggedValue());
1360     }
1361 
1362     JSHandle<JSObject> newObj = JSObject::CreateObjectFromProperties(thread, properties);
1363     Heap *heap = const_cast<Heap *>(thread->GetEcmaVM()->GetHeap());
1364     heap->GetSweeper()->EnsureAllTaskFinished();
1365     Verification(heap).VerifyAll();
1366     auto sHeap = SharedHeap::GetInstance();
1367     sHeap->WaitGCFinished(thread);
1368     ecmascript::SuspendAllScope suspendScope(thread);
1369     SharedHeapVerification(sHeap, VerifyKind::VERIFY_PRE_SHARED_GC).VerifyAll();
1370     EXPECT_TRUE(newObj->GetClass()->IsDictionaryMode());
1371 }
1372 }  // namespace panda::test
1373