• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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/object_operator.h"
17 #include "ecmascript/ecma_string.h"
18 #include "ecmascript/global_env.h"
19 #include "ecmascript/global_dictionary-inl.h"
20 #include "ecmascript/js_array.h"
21 #include "ecmascript/property_attributes.h"
22 #include "ecmascript/tagged_array.h"
23 #include "ecmascript/tagged_dictionary.h"
24 #include "ecmascript/tests/test_helper.h"
25 
26 using namespace panda::ecmascript;
27 
28 namespace panda::test {
29 class ObjectOperatorTest : public BaseTestWithScope<false> {
30 };
31 
JSObjectTestCreate(JSThread * thread)32 static JSFunction *JSObjectTestCreate(JSThread *thread)
33 {
34     JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
35     return globalEnv->GetObjectFunction().GetObject<JSFunction>();
36 }
37 
TestDefinedSetter(EcmaRuntimeCallInfo * argv)38 JSTaggedValue TestDefinedSetter([[maybe_unused]] EcmaRuntimeCallInfo *argv)
39 {
40     // 12 : test case
41     return JSTaggedValue(12);
42 }
43 
HWTEST_F_L0(ObjectOperatorTest,WriteDataProperty_001)44 HWTEST_F_L0(ObjectOperatorTest, WriteDataProperty_001)
45 {
46     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
47     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
48     JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(2));
49     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(4));
50     uint32_t index = 1;
51     PropertyDescriptor handleDesc(thread);
52     ObjectOperator objectOperator(thread, handleKey);
53     PropertyAttributes handleAttr(4);
54     handleDesc.SetConfigurable(true); // Desc Set Configurable
55     objectOperator.SetAttr(PropertyAttributes(3));
56     objectOperator.SetIndex(index);
57     // object class is not DictionaryElement and object is Element
58     JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
59     for (int i = 0; i < 3; i++) {
60         JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
61         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newKey);
62     }
63     EXPECT_TRUE(objectOperator.WriteDataProperty(handleObject, handleDesc));
64     auto resultDict = NumberDictionary::Cast(handleObject->GetElements().GetTaggedObject());
65     int resultEntry = resultDict->FindEntry(JSTaggedValue(index));
66     int resultAttrValue = resultDict->GetAttributes(resultEntry).GetPropertyMetaData();
67 
68     EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), resultAttrValue);
69     EXPECT_EQ(objectOperator.GetAttr().GetDictionaryOrder(), 1U);
70     EXPECT_TRUE(objectOperator.GetAttr().IsConfigurable());
71     EXPECT_EQ(objectOperator.GetIndex(), static_cast<uint32_t>(resultEntry));
72     EXPECT_FALSE(objectOperator.IsFastMode());
73     EXPECT_TRUE(objectOperator.IsTransition());
74 }
75 
HWTEST_F_L0(ObjectOperatorTest,WriteDataProperty_002)76 HWTEST_F_L0(ObjectOperatorTest, WriteDataProperty_002)
77 {
78     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
79     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
80     JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
81     JSHandle<JSTaggedValue> handleValue1(thread, JSTaggedValue(1));
82     JSHandle<JSTaggedValue> handleValue2(thread, JSTaggedValue(2));
83     JSHandle<PropertyBox> cellHandle1 = factory->NewPropertyBox(handleValue1);
84     JSHandle<PropertyBox> cellHandle2 = factory->NewPropertyBox(handleValue2);
85     PropertyDescriptor handleDesc(thread);
86     handleDesc.SetConfigurable(true);
87     PropertyAttributes handleAttr(2);
88     handleAttr.SetConfigurable(true);
89     // object is JSGlobalObject and not Element
90     JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
91     JSHandle<JSObject> handleGlobalObject(globalObj);
92     ObjectOperator objectOperator(thread, handleGlobalObject, handleKey);
93 
94     JSMutableHandle<GlobalDictionary> globalDict(thread, handleGlobalObject->GetProperties());
95     JSHandle<GlobalDictionary> handleDict = GlobalDictionary::Create(thread, 4);
96     globalDict.Update(handleDict.GetTaggedValue());
97     JSHandle<GlobalDictionary> handleProperties = GlobalDictionary::PutIfAbsent(
98         thread, globalDict, handleKey, JSHandle<JSTaggedValue>(cellHandle1), PropertyAttributes(4));
99     handleProperties->SetAttributes(thread, handleAttr.GetDictionaryOrder(), handleAttr);
100     handleProperties->SetValue(thread, handleAttr.GetDictionaryOrder(), cellHandle2.GetTaggedValue());
101     handleGlobalObject->SetProperties(thread, handleProperties.GetTaggedValue());
102     int resultEntry = handleProperties->FindEntry(handleKey.GetTaggedValue());
103     objectOperator.SetIndex(resultEntry);
104 
105     EXPECT_TRUE(objectOperator.WriteDataProperty(handleGlobalObject, handleDesc));
106     auto resultDict = GlobalDictionary::Cast(handleGlobalObject->GetProperties().GetTaggedObject());
107     EXPECT_EQ(resultDict->GetAttributes(objectOperator.GetIndex()).GetPropertyMetaData(), 4);
108     EXPECT_TRUE(resultDict->GetAttributes(objectOperator.GetIndex()).IsConfigurable());
109 
110     EXPECT_EQ(resultDict->GetAttributes(resultEntry).GetBoxType(), PropertyBoxType::MUTABLE);
111     EXPECT_EQ(resultDict->GetValue(resultEntry).GetInt(), 1);
112 }
113 
HWTEST_F_L0(ObjectOperatorTest,WriteDataProperty_003)114 HWTEST_F_L0(ObjectOperatorTest, WriteDataProperty_003)
115 {
116     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
117     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
118     JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
119     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(2));
120     PropertyDescriptor handleDesc(thread, handleValue);
121     handleDesc.SetSetter(handleValue); // Desc is AccessorDescriptor
122     handleDesc.SetGetter(handleValue);
123     // object is not DictionaryMode and not Element
124     JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
125     for (int i = 0; i < 3; i++) {
126         JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
127         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newKey);
128     }
129     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey, handleValue);
130     ObjectOperator objectOperator1(thread, handleKey);
131     objectOperator1.SetAttr(PropertyAttributes(1));
132 
133     EXPECT_TRUE(objectOperator1.WriteDataProperty(handleObject, handleDesc));
134     auto resultDict = NameDictionary::Cast(handleObject->GetProperties().GetTaggedObject());
135     int resultEntry = resultDict->FindEntry(handleKey.GetTaggedValue());
136     EXPECT_TRUE(resultDict->GetValue(resultEntry).IsAccessorData());
137     EXPECT_EQ(resultDict->GetAttributes(resultEntry).GetValue(), objectOperator1.GetAttr().GetValue());
138     // object is DictionaryMode and not Element
139     JSObject::DeleteProperty(thread, (handleObject), handleKey);
140     JSHandle<JSTaggedValue> handleSetter(factory->NewJSNativePointer(reinterpret_cast<void *>(TestDefinedSetter)));
141     JSHandle<AccessorData> handleAccessorData = factory->NewAccessorData();
142     handleDesc.SetSetter(handleSetter);
143     ObjectOperator objectOperator2(thread, handleKey);
144     objectOperator2.SetAttr(PropertyAttributes(handleDesc));
145     objectOperator2.SetValue(handleAccessorData.GetTaggedValue());
146     EXPECT_TRUE(objectOperator2.WriteDataProperty(handleObject, handleDesc));
147     JSHandle<AccessorData> resultAccessorData(thread, objectOperator2.GetValue());
148     EXPECT_EQ(resultAccessorData->GetGetter().GetInt(), 2);
149     EXPECT_TRUE(resultAccessorData->GetSetter().IsJSNativePointer());
150 }
151 
HWTEST_F_L0(ObjectOperatorTest,Property_Add_001)152 HWTEST_F_L0(ObjectOperatorTest, Property_Add_001)
153 {
154     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
155     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
156     JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(2));
157     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(3));
158     int32_t elementIndex = 2;
159     PropertyAttributes handleAttr(elementIndex);
160     // object is JSArray and Element
161     JSHandle<JSArray> handleArr = factory->NewJSArray();
162     handleArr->SetArrayLength(thread, (elementIndex - 1));
163     JSHandle<JSTaggedValue> handleArrObj(thread, handleArr.GetTaggedValue());
164     ObjectOperator objectOperator1(thread, handleArrObj, elementIndex);
165     EXPECT_TRUE(objectOperator1.AddProperty(JSHandle<JSObject>(handleArrObj), handleValue, handleAttr));
166     EXPECT_EQ(handleArr->GetArrayLength(), 3U); // (elementIndex - 1) + 2
167     // object is DictionaryElement and Element
168     JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
169     for (int i = 0; i < 3; i++) {
170         JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
171         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newKey);
172     }
173     JSObject::DeleteProperty(thread, (handleObject), handleKey); // Delete key2
174     ObjectOperator objectOperator2(thread, JSHandle<JSTaggedValue>(handleObject), elementIndex);
175     EXPECT_TRUE(objectOperator2.AddProperty(handleObject, handleValue, handleAttr));
176     auto resultDict = NumberDictionary::Cast(handleObject->GetElements().GetTaggedObject());
177     int resultEntry = resultDict->FindEntry(JSTaggedValue(static_cast<uint32_t>(elementIndex)));
178     EXPECT_EQ(resultDict->GetKey(resultEntry).GetInt(), elementIndex);
179     EXPECT_EQ(resultDict->GetValue(resultEntry).GetInt(), 3);
180 }
181 
HWTEST_F_L0(ObjectOperatorTest,Property_Add_002)182 HWTEST_F_L0(ObjectOperatorTest, Property_Add_002)
183 {
184     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
185     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
186     JSHandle<JSTaggedValue> handleString(factory->NewFromASCII("key"));
187     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(3));
188     int32_t elementIndex = 4;
189     PropertyAttributes handleDefaultAttr(elementIndex);
190     PropertyAttributes handleAttr(elementIndex);
191     handleDefaultAttr.SetDefaultAttributes();
192     // object is not DictionaryMode and DefaultAttr
193     JSHandle<JSObject> handleObject1 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
194     for (int i = 0; i < 3; i++) {
195         JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
196         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject1), newKey, newKey);
197     }
198     ObjectOperator objectOperator(thread, JSHandle<JSTaggedValue>(handleObject1), elementIndex);
199     EXPECT_TRUE(objectOperator.AddProperty(handleObject1, handleValue, handleDefaultAttr));
200     TaggedArray *resultArray = TaggedArray::Cast(handleObject1->GetElements().GetTaggedObject());
201     EXPECT_EQ(resultArray->Get(elementIndex).GetInt(), 3);
202     EXPECT_EQ(resultArray->GetLength(), 7U);
203     // object is not DictionaryMode and not DefaultAttr
204     JSHandle<JSObject> handleObject2 = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
205     for (int i = 0; i < 4; i++) {
206         JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
207         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject2), newKey, newKey);
208     }
209     EXPECT_TRUE(objectOperator.AddProperty(handleObject2, handleString, handleAttr));
210     auto resultDict = NumberDictionary::Cast(handleObject2->GetElements().GetTaggedObject());
211     int resultEntry = resultDict->FindEntry(JSTaggedValue(static_cast<uint32_t>(elementIndex)));
212     EXPECT_EQ(resultDict->GetKey(resultEntry).GetInt(), elementIndex);
213     EXPECT_TRUE(resultDict->GetValue(resultEntry).IsString());
214 }
215 
HWTEST_F_L0(ObjectOperatorTest,Property_Add_003)216 HWTEST_F_L0(ObjectOperatorTest, Property_Add_003)
217 {
218     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
219     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
220     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
221     JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
222     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(4));
223     int32_t handleAttrOffset = 4;
224     PropertyAttributes handleAttr(handleAttrOffset);
225     handleAttr.SetOffset(handleAttrOffset);
226     // object is JSGlobalObject and not Element
227     JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
228     JSHandle<JSObject> handleGlobalObject(globalObj); // no properties
229     ObjectOperator objectOperator(thread, handleGlobalObject, handleKey);
230     EXPECT_TRUE(objectOperator.AddProperty(handleGlobalObject, handleValue, handleAttr));
231     EXPECT_EQ(objectOperator.GetAttr().GetBoxType(), PropertyBoxType::CONSTANT);
232     EXPECT_EQ(objectOperator.FastGetValue()->GetInt(), 4);
233     EXPECT_EQ(objectOperator.GetIndex(), 0U);
234     EXPECT_TRUE(objectOperator.IsFastMode());
235     EXPECT_FALSE(objectOperator.IsTransition());
236 }
237 
HWTEST_F_L0(ObjectOperatorTest,Property_Add_004)238 HWTEST_F_L0(ObjectOperatorTest, Property_Add_004)
239 {
240     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
241     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
242     JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
243     JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
244     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(4));
245     JSHandle<JSTaggedValue> handledUndefinedVal(thread, JSTaggedValue::Undefined());
246     int32_t handleAttrOffset = 4;
247     PropertyAttributes handleAttr(handleAttrOffset);
248     handleAttr.SetOffset(handleAttrOffset);
249     // object is not DictionaryMode and not Element
250     JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
251     for (int i = 0; i < 4; i++) {
252         JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
253         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newKey);
254     }
255     EXPECT_EQ(handleObject->GetJSHClass()->GetInlinedProperties(), 4U);
256     ObjectOperator objectOperator(thread, handleObject, handleKey);
257     EXPECT_TRUE(objectOperator.AddProperty(handleObject, handleValue, handleAttr));
258     EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), 4);
259     EXPECT_EQ(objectOperator.GetValue().GetInt(), 4);
260     EXPECT_EQ(objectOperator.GetIndex(), 0U); // 0 = 4 - 4
261     EXPECT_TRUE(objectOperator.IsFastMode());
262     EXPECT_TRUE(objectOperator.IsTransition());
263     // object is DictionaryMode and not Element
264     JSObject::DeleteProperty(thread, (handleObject), handleKey);
265     EXPECT_TRUE(objectOperator.AddProperty(handleObject, handledUndefinedVal, handleAttr));
266     EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), 4);
267     EXPECT_TRUE(objectOperator.GetValue().IsUndefined());
268     EXPECT_EQ(objectOperator.GetIndex(), 0U);
269     EXPECT_FALSE(objectOperator.IsFastMode());
270     EXPECT_FALSE(objectOperator.IsTransition());
271 }
272 
HWTEST_F_L0(ObjectOperatorTest,Property_DeleteElement1)273 HWTEST_F_L0(ObjectOperatorTest, Property_DeleteElement1)
274 {
275     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
276     JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
277     JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
278     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(2));
279     uint32_t index = 1; // key value
280     PropertyAttributes handleAttr(index);
281 
282     // object is not DictionaryMode
283     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
284     JSHandle<JSObject> handleObject1 =
285         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
286     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject1), handleKey0, handleKey0);
287     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject1), handleKey1, handleKey1);
288     TaggedArray *handleElements = TaggedArray::Cast(handleObject1->GetElements().GetTaggedObject());
289     EXPECT_EQ(handleElements->Get(index).GetInt(), 1);
290 
291     ObjectOperator objectOperator1(thread, JSHandle<JSTaggedValue>(handleObject1), index);
292     objectOperator1.DeletePropertyInHolder();
293     TaggedArray *resultElements = TaggedArray::Cast(handleObject1->GetElements().GetTaggedObject());
294     EXPECT_EQ(resultElements->Get(index).GetInt(), 0);
295     auto resultDict1 = NumberDictionary::Cast(handleObject1->GetElements().GetTaggedObject());
296     EXPECT_TRUE(resultDict1->IsDictionaryMode());
297     EXPECT_TRUE(JSObject::GetProperty(thread, handleObject1, handleKey1).GetValue()->IsUndefined());
298     // object is DictionaryMode
299     JSHandle<JSObject> handleObject2 =
300         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
301     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject2), handleKey0, handleKey0);
302     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject2), handleKey1, handleKey1);
303     JSObject::DeleteProperty(thread, (handleObject2), handleKey1);
304     ObjectOperator objectOperator2(thread, JSHandle<JSTaggedValue>(handleObject2), index - 1);
305     objectOperator2.DeletePropertyInHolder();
306     auto resultDict2 = NumberDictionary::Cast(handleObject2->GetElements().GetTaggedObject());
307     EXPECT_TRUE(resultDict2->GetKey(index - 1U).IsUndefined());
308     EXPECT_TRUE(resultDict2->GetValue(index - 1U).IsUndefined());
309     EXPECT_TRUE(JSObject::GetProperty(thread, handleObject2, handleKey0).GetValue()->IsUndefined());
310     EXPECT_TRUE(JSObject::GetProperty(thread, handleObject2, handleKey1).GetValue()->IsUndefined());
311 }
312 
HWTEST_F_L0(ObjectOperatorTest,Property_DeleteElement2)313 HWTEST_F_L0(ObjectOperatorTest, Property_DeleteElement2)
314 {
315     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
316     JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
317     JSHandle<JSObject> handleGlobalObject(globalObj);
318     JSHandle<NumberDictionary> handleDict = NumberDictionary::Create(thread, 4);
319     handleGlobalObject->SetElements(thread, handleDict.GetTaggedValue());
320     handleGlobalObject->GetClass()->SetIsDictionaryElement(true);
321     for (int i = 0; i < 10000; i++) {
322         JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(i));
323         JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(i));
324         JSObject::SetProperty(thread, globalObj, handleKey, handleValue);
325         JSObject::DeleteProperty(thread, handleGlobalObject, handleKey);
326     }
327     auto resultDict = NumberDictionary::Cast(handleGlobalObject->GetElements().GetTaggedObject());
328     EXPECT_EQ(resultDict->Size(), 4);
329 }
330 
HWTEST_F_L0(ObjectOperatorTest,Property_DeleteProperty)331 HWTEST_F_L0(ObjectOperatorTest, Property_DeleteProperty)
332 {
333     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
334     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
335     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
336     JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
337     JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
338     JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
339     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(33));
340     // object is JSGlobalObject
341     JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
342     JSHandle<JSObject> handleGlobalObject(globalObj);
343     JSMutableHandle<GlobalDictionary> globalDict(thread, handleGlobalObject->GetProperties());
344     JSHandle<GlobalDictionary> handleDict = GlobalDictionary::Create(thread, 4);
345     globalDict.Update(handleDict.GetTaggedValue());
346     JSHandle<PropertyBox> cellHandle = factory->NewPropertyBox(handleKey);
347     cellHandle->SetValue(thread, handleValue.GetTaggedValue());
348     JSHandle<GlobalDictionary> handleProperties = GlobalDictionary::PutIfAbsent(
349         thread, globalDict, handleKey, JSHandle<JSTaggedValue>(cellHandle), PropertyAttributes(12));
350     handleGlobalObject->SetProperties(thread, handleProperties.GetTaggedValue());
351     ObjectOperator objectOperator1(thread, handleGlobalObject, handleKey);
352 
353     objectOperator1.DeletePropertyInHolder();
354     auto resultDict = GlobalDictionary::Cast(handleGlobalObject->GetProperties().GetTaggedObject());
355     // key not found
356     EXPECT_EQ(resultDict->FindEntry(handleKey.GetTaggedValue()), -1);
357     EXPECT_EQ(resultDict->GetAttributes(objectOperator1.GetIndex()).GetValue(), 0U);
358     // object is not DictionaryMode
359     JSHandle<JSObject> handleObject =
360         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
361     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey, handleKey1);
362     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey0, handleKey0);
363     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey1, handleKey1);
364     ObjectOperator objectOperator2(thread, handleObject, handleKey);
365     objectOperator2.DeletePropertyInHolder();
366     auto resultDict1 = NameDictionary::Cast(handleObject->GetProperties().GetTaggedObject());
367     // key not found
368     EXPECT_EQ(resultDict1->FindEntry(handleKey.GetTaggedValue()), -1);
369 }
370 
HWTEST_F_L0(ObjectOperatorTest,Define_SetterAndGettetr)371 HWTEST_F_L0(ObjectOperatorTest, Define_SetterAndGettetr)
372 {
373     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
374     JSHandle<AccessorData> handleAccessorData = factory->NewAccessorData();
375     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(0));
376     JSHandle<JSTaggedValue> handleValue1(thread, JSTaggedValue(2));
377     JSHandle<EcmaString> handleKey(factory->NewFromASCII("value"));
378     JSHandle<JSTaggedValue> handleKey1(factory->NewFromASCII("key"));
379     JSHandle<JSTaggedValue> handleKey2(factory->NewFromASCII("value1"));
380     // object is not DictionaryMode
381     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
382     JSHandle<JSObject> handleObject =
383         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
384     for (int i = 0; i < 10; i++) {
385         JSHandle<JSTaggedValue> newValue(thread, JSTaggedValue(i));
386         JSHandle<EcmaString> newString =
387             factory->ConcatFromString(handleKey, JSTaggedValue::ToString(thread, newValue));
388         JSHandle<JSTaggedValue> newKey(thread, newString.GetTaggedValue());
389         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newValue);
390     }
391     // object is not Element
392     ObjectOperator objectOperator(thread, handleObject, handleKey1);
393     objectOperator.SetIndex(1);
394     objectOperator.SetValue(handleAccessorData.GetTaggedValue());
395     PropertyDescriptor handleDesc(thread, handleValue);
396     handleDesc.SetSetter(handleValue);
397     handleDesc.SetGetter(handleValue);
398     objectOperator.SetAttr(PropertyAttributes(handleDesc));
399     objectOperator.DefineSetter(handleValue1);
400     objectOperator.DefineGetter(handleValue);
401 
402     JSHandle<JSObject> resultObj1(objectOperator.GetReceiver());
403     TaggedArray *properties = TaggedArray::Cast(resultObj1->GetProperties().GetTaggedObject());
404     JSHandle<AccessorData> resultAccessorData1(thread, properties->Get(objectOperator.GetIndex()));
405     EXPECT_EQ(resultAccessorData1->GetGetter().GetInt(), 0);
406     EXPECT_EQ(resultAccessorData1->GetSetter().GetInt(), 2);
407     // object is DictionaryMode
408     JSObject::DeleteProperty(thread, handleObject, handleKey2);
409     objectOperator.DefineSetter(handleValue);
410     objectOperator.DefineGetter(handleValue1);
411     JSHandle<JSObject> resultObj2(objectOperator.GetReceiver());
412     auto resultDict = NameDictionary::Cast(resultObj2->GetProperties().GetTaggedObject());
413     JSHandle<AccessorData> resultAccessorData2(thread, resultDict->GetValue(objectOperator.GetIndex()));
414     EXPECT_EQ(resultAccessorData2->GetGetter().GetInt(), 2);
415     EXPECT_EQ(resultAccessorData2->GetSetter().GetInt(), 0);
416 }
417 } // namespace panda::test