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 26using namespace panda::ecmascript; 27 28namespace panda::test { 29class ObjectOperatorTest : public BaseTestWithScope<false> { 30}; 31 32static JSFunction *JSObjectTestCreate(JSThread *thread) 33{ 34 JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); 35 return globalEnv->GetObjectFunction().GetObject<JSFunction>(); 36} 37 38JSTaggedValue TestDefinedSetter([[maybe_unused]] EcmaRuntimeCallInfo *argv) 39{ 40 // 12 : test case 41 return JSTaggedValue(12); 42} 43 44HWTEST_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 76HWTEST_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 114HWTEST_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 152HWTEST_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 182HWTEST_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 216HWTEST_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 238HWTEST_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 273HWTEST_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 313HWTEST_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 < 10; 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 331HWTEST_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 371HWTEST_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