• 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(thread).GetTaggedObject());
65     int resultEntry = resultDict->FindEntry(thread, JSTaggedValue(index));
66     int resultAttrValue = resultDict->GetAttributes(thread, 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(thread));
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(thread, handleKey.GetTaggedValue());
103     objectOperator.SetIndex(resultEntry);
104 
105     EXPECT_TRUE(objectOperator.WriteDataProperty(handleGlobalObject, handleDesc));
106     auto resultDict = GlobalDictionary::Cast(handleGlobalObject->GetProperties(thread).GetTaggedObject());
107     EXPECT_EQ(resultDict->GetAttributes(thread, objectOperator.GetIndex()).GetPropertyMetaData(), 4);
108     EXPECT_TRUE(resultDict->GetAttributes(thread, objectOperator.GetIndex()).IsConfigurable());
109 
110     EXPECT_EQ(resultDict->GetAttributes(thread, resultEntry).GetBoxType(), PropertyBoxType::MUTABLE);
111     EXPECT_EQ(resultDict->GetValue(thread, 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(thread).GetTaggedObject());
135     int resultEntry = resultDict->FindEntry(thread, handleKey.GetTaggedValue());
136     EXPECT_TRUE(resultDict->GetValue(thread, resultEntry).IsAccessorData());
137     EXPECT_EQ(resultDict->GetAttributes(thread, 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(thread).GetInt(), 2);
149     EXPECT_TRUE(resultAccessorData->GetSetter(thread).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(thread).GetTaggedObject());
177     int resultEntry = resultDict->FindEntry(thread, JSTaggedValue(static_cast<uint32_t>(elementIndex)));
178     EXPECT_EQ(resultDict->GetKey(thread, resultEntry).GetInt(), elementIndex);
179     EXPECT_EQ(resultDict->GetValue(thread, 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(thread).GetTaggedObject());
201     EXPECT_EQ(resultArray->Get(thread, 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(thread).GetTaggedObject());
211     int resultEntry = resultDict->FindEntry(thread, JSTaggedValue(static_cast<uint32_t>(elementIndex)));
212     EXPECT_EQ(resultDict->GetKey(thread, resultEntry).GetInt(), elementIndex);
213     EXPECT_TRUE(resultDict->GetValue(thread, 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     uint32_t index = 1; // key value
276     uint32_t index2 = 102400;
277     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
278     JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
279     JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
280     JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(102400));
281     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(2));
282     PropertyAttributes handleAttr(index);
283 
284     // object is not DictionaryMode
285     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
286     JSHandle<JSObject> handleObject1 =
287         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
288     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject1), handleKey0, handleKey0);
289     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject1), handleKey1, handleKey1);
290     TaggedArray *handleElements = TaggedArray::Cast(handleObject1->GetElements(thread).GetTaggedObject());
291     EXPECT_EQ(handleElements->Get(thread, index).GetInt(), 1);
292 
293     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject1), handleKey, handleKey);
294     ObjectOperator objectOperator1(thread, JSHandle<JSTaggedValue>(handleObject1), index2);
295     objectOperator1.DeletePropertyInHolder();
296 
297     TaggedArray *resultElements = TaggedArray::Cast(handleObject1->GetElements(thread).GetTaggedObject());
298     EXPECT_EQ(resultElements->Get(thread, index).GetInt(), 1);
299     auto resultDict1 = NumberDictionary::Cast(handleObject1->GetElements(thread).GetTaggedObject());
300     EXPECT_TRUE(resultDict1->IsDictionaryMode());
301     EXPECT_TRUE(JSObject::GetProperty(thread, handleObject1, handleKey).GetValue()->IsUndefined());
302     // object is DictionaryMode
303     JSHandle<JSObject> handleObject2 =
304         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
305     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject2), handleKey0, handleKey0);
306     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject2), handleKey1, handleKey1);
307     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject2), handleKey, handleKey);
308 
309     JSObject::DeleteProperty(thread, (handleObject2), handleKey1);
310     ObjectOperator objectOperator2(thread, JSHandle<JSTaggedValue>(handleObject2), index - 1);
311     objectOperator2.DeletePropertyInHolder();
312     auto resultDict2 = NumberDictionary::Cast(handleObject2->GetElements(thread).GetTaggedObject());
313     EXPECT_TRUE(resultDict2->GetKey(thread, index - 1U).IsUndefined());
314     EXPECT_TRUE(resultDict2->GetValue(thread, index - 1U).IsUndefined());
315     EXPECT_TRUE(JSObject::GetProperty(thread, handleObject2, handleKey0).GetValue()->IsUndefined());
316     EXPECT_TRUE(JSObject::GetProperty(thread, handleObject2, handleKey1).GetValue()->IsUndefined());
317 }
318 
HWTEST_F_L0(ObjectOperatorTest,Property_DeleteElement2)319 HWTEST_F_L0(ObjectOperatorTest, Property_DeleteElement2)
320 {
321     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
322     JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
323     JSHandle<JSObject> handleGlobalObject(globalObj);
324     JSHandle<NumberDictionary> handleDict = NumberDictionary::Create(thread, 4);
325     handleGlobalObject->SetElements(thread, handleDict.GetTaggedValue());
326     handleGlobalObject->GetClass()->SetIsDictionaryElement(true);
327     for (int i = 0; i < 10; i++) {
328         JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(i));
329         JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(i));
330         JSObject::SetProperty(thread, globalObj, handleKey, handleValue);
331         JSObject::DeleteProperty(thread, handleGlobalObject, handleKey);
332     }
333     auto resultDict = NumberDictionary::Cast(handleGlobalObject->GetElements(thread).GetTaggedObject());
334     EXPECT_EQ(resultDict->Size(), 4);
335 }
336 
HWTEST_F_L0(ObjectOperatorTest,Property_DeleteProperty)337 HWTEST_F_L0(ObjectOperatorTest, Property_DeleteProperty)
338 {
339     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
340     JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
341     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
342     JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
343     JSHandle<JSTaggedValue> handleKey0(thread, JSTaggedValue(0));
344     JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
345     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(33));
346     // object is JSGlobalObject
347     JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
348     JSHandle<JSObject> handleGlobalObject(globalObj);
349     JSMutableHandle<GlobalDictionary> globalDict(thread, handleGlobalObject->GetProperties(thread));
350     JSHandle<GlobalDictionary> handleDict = GlobalDictionary::Create(thread, 4);
351     globalDict.Update(handleDict.GetTaggedValue());
352     JSHandle<PropertyBox> cellHandle = factory->NewPropertyBox(handleKey);
353     cellHandle->SetValue(thread, handleValue.GetTaggedValue());
354     JSHandle<GlobalDictionary> handleProperties = GlobalDictionary::PutIfAbsent(
355         thread, globalDict, handleKey, JSHandle<JSTaggedValue>(cellHandle), PropertyAttributes(12));
356     handleGlobalObject->SetProperties(thread, handleProperties.GetTaggedValue());
357     ObjectOperator objectOperator1(thread, handleGlobalObject, handleKey);
358 
359     objectOperator1.DeletePropertyInHolder();
360     auto resultDict = GlobalDictionary::Cast(handleGlobalObject->GetProperties(thread).GetTaggedObject());
361     // key not found
362     EXPECT_EQ(resultDict->FindEntry(thread, handleKey.GetTaggedValue()), -1);
363     EXPECT_EQ(resultDict->GetAttributes(thread, objectOperator1.GetIndex()).GetValue(), 0U);
364     // object is not DictionaryMode
365     JSHandle<JSObject> handleObject =
366         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
367     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey, handleKey1);
368     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey0, handleKey0);
369     JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey1, handleKey1);
370     ObjectOperator objectOperator2(thread, handleObject, handleKey);
371     objectOperator2.DeletePropertyInHolder();
372     auto resultDict1 = NameDictionary::Cast(handleObject->GetProperties(thread).GetTaggedObject());
373     // key not found
374     EXPECT_EQ(resultDict1->FindEntry(thread, handleKey.GetTaggedValue()), -1);
375 }
376 
HWTEST_F_L0(ObjectOperatorTest,Define_SetterAndGettetr)377 HWTEST_F_L0(ObjectOperatorTest, Define_SetterAndGettetr)
378 {
379     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
380     JSHandle<AccessorData> handleAccessorData = factory->NewAccessorData();
381     JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(0));
382     JSHandle<JSTaggedValue> handleValue1(thread, JSTaggedValue(2));
383     JSHandle<EcmaString> handleKey(factory->NewFromASCII("value"));
384     JSHandle<JSTaggedValue> handleKey1(factory->NewFromASCII("key"));
385     JSHandle<JSTaggedValue> handleKey2(factory->NewFromASCII("value1"));
386     // object is not DictionaryMode
387     JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
388     JSHandle<JSObject> handleObject =
389         factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
390     for (int i = 0; i < 10; i++) {
391         JSHandle<JSTaggedValue> newValue(thread, JSTaggedValue(i));
392         JSHandle<EcmaString> newString =
393             factory->ConcatFromString(handleKey, JSTaggedValue::ToString(thread, newValue));
394         JSHandle<JSTaggedValue> newKey(thread, newString.GetTaggedValue());
395         JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newValue);
396     }
397     // object is not Element
398     ObjectOperator objectOperator(thread, handleObject, handleKey1);
399     objectOperator.SetIndex(1);
400     objectOperator.SetValue(handleAccessorData.GetTaggedValue());
401     PropertyDescriptor handleDesc(thread, handleValue);
402     handleDesc.SetSetter(handleValue);
403     handleDesc.SetGetter(handleValue);
404     objectOperator.SetAttr(PropertyAttributes(handleDesc));
405     objectOperator.DefineSetter(handleValue1);
406     objectOperator.DefineGetter(handleValue);
407 
408     JSHandle<JSObject> resultObj1(objectOperator.GetReceiver());
409     TaggedArray *properties = TaggedArray::Cast(resultObj1->GetProperties(thread).GetTaggedObject());
410     JSHandle<AccessorData> resultAccessorData1(thread, properties->Get(thread, objectOperator.GetIndex()));
411     EXPECT_EQ(resultAccessorData1->GetGetter(thread).GetInt(), 0);
412     EXPECT_EQ(resultAccessorData1->GetSetter(thread).GetInt(), 2);
413     // object is DictionaryMode
414     JSObject::DeleteProperty(thread, handleObject, handleKey2);
415     objectOperator.DefineSetter(handleValue);
416     objectOperator.DefineGetter(handleValue1);
417     JSHandle<JSObject> resultObj2(objectOperator.GetReceiver());
418     auto resultDict = NameDictionary::Cast(resultObj2->GetProperties(thread).GetTaggedObject());
419     JSHandle<AccessorData> resultAccessorData2(thread, resultDict->GetValue(thread, objectOperator.GetIndex()));
420     EXPECT_EQ(resultAccessorData2->GetGetter(thread).GetInt(), 2);
421     EXPECT_EQ(resultAccessorData2->GetSetter(thread).GetInt(), 0);
422 }
423 } // namespace panda::test