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 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().GetTaggedObject());
291 EXPECT_EQ(handleElements->Get(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().GetTaggedObject());
298 EXPECT_EQ(resultElements->Get(index).GetInt(), 1);
299 auto resultDict1 = NumberDictionary::Cast(handleObject1->GetElements().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().GetTaggedObject());
313 EXPECT_TRUE(resultDict2->GetKey(index - 1U).IsUndefined());
314 EXPECT_TRUE(resultDict2->GetValue(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().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());
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().GetTaggedObject());
361 // key not found
362 EXPECT_EQ(resultDict->FindEntry(handleKey.GetTaggedValue()), -1);
363 EXPECT_EQ(resultDict->GetAttributes(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().GetTaggedObject());
373 // key not found
374 EXPECT_EQ(resultDict1->FindEntry(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().GetTaggedObject());
410 JSHandle<AccessorData> resultAccessorData1(thread, properties->Get(objectOperator.GetIndex()));
411 EXPECT_EQ(resultAccessorData1->GetGetter().GetInt(), 0);
412 EXPECT_EQ(resultAccessorData1->GetSetter().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().GetTaggedObject());
419 JSHandle<AccessorData> resultAccessorData2(thread, resultDict->GetValue(objectOperator.GetIndex()));
420 EXPECT_EQ(resultAccessorData2->GetGetter().GetInt(), 2);
421 EXPECT_EQ(resultAccessorData2->GetSetter().GetInt(), 0);
422 }
423 } // namespace panda::test