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