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
HWTEST_F_L0(ObjectOperatorTest,SetAttr)32 HWTEST_F_L0(ObjectOperatorTest, SetAttr)
33 {
34 JSHandle<JSTaggedValue> handleValue1(thread, JSTaggedValue(1));
35 JSHandle<JSTaggedValue> handleValue2(thread, JSTaggedValue(2));
36
37 ObjectOperator objectOperator1(thread, handleValue1);
38 ObjectOperator objectOperator2(thread, handleValue2);
39 uint32_t handleAttr1 = 2;
40
41 objectOperator1.SetAttr(handleAttr1);
42 EXPECT_EQ(objectOperator1.GetAttr().GetPropertyMetaData(), 2);
43 EXPECT_FALSE(objectOperator1.IsPrimitiveAttr());
44
45 PropertyAttributes handleAttr2(JSTaggedValue(0));
46 objectOperator2.SetAttr(handleAttr2);
47 EXPECT_TRUE(objectOperator2.IsPrimitiveAttr());
48 }
49
HWTEST_F_L0(ObjectOperatorTest,SetFastMode)50 HWTEST_F_L0(ObjectOperatorTest, SetFastMode)
51 {
52 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
53 ObjectOperator objectOperator(thread, handleValue);
54
55 EXPECT_FALSE(objectOperator.IsFastMode());
56 objectOperator.SetFastMode(false);
57 EXPECT_FALSE(objectOperator.IsFastMode());
58
59 objectOperator.SetFastMode(true);
60 EXPECT_TRUE(objectOperator.IsFastMode());
61 }
62
HWTEST_F_L0(ObjectOperatorTest,SetIsOnPrototype)63 HWTEST_F_L0(ObjectOperatorTest, SetIsOnPrototype)
64 {
65 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
66 ObjectOperator objectOperator(thread, handleValue);
67
68 EXPECT_TRUE(objectOperator.IsOnPrototype());
69 objectOperator.SetIsOnPrototype(true);
70 EXPECT_TRUE(objectOperator.IsOnPrototype());
71
72 objectOperator.SetIsOnPrototype(false);
73 EXPECT_FALSE(objectOperator.IsOnPrototype());
74 }
75
HWTEST_F_L0(ObjectOperatorTest,SetHasReceiver)76 HWTEST_F_L0(ObjectOperatorTest, SetHasReceiver)
77 {
78 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
79 ObjectOperator objectOperator(thread, handleValue);
80
81 EXPECT_FALSE(objectOperator.HasReceiver());
82 objectOperator.SetHasReceiver(true);
83 EXPECT_TRUE(objectOperator.HasReceiver());
84
85 objectOperator.SetHasReceiver(false);
86 EXPECT_FALSE(objectOperator.HasReceiver());
87 }
88
HWTEST_F_L0(ObjectOperatorTest,SetIsTransition)89 HWTEST_F_L0(ObjectOperatorTest, SetIsTransition)
90 {
91 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
92 ObjectOperator objectOperator(thread, handleValue);
93
94 EXPECT_FALSE(objectOperator.IsTransition());
95 objectOperator.SetIsTransition(true);
96 EXPECT_TRUE(objectOperator.IsTransition());
97
98 objectOperator.SetIsTransition(false);
99 EXPECT_FALSE(objectOperator.IsTransition());
100 }
101
HWTEST_F_L0(ObjectOperatorTest,SetIndex)102 HWTEST_F_L0(ObjectOperatorTest, SetIndex)
103 {
104 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
105 ObjectOperator objectOperator(thread, handleValue);
106
107 uint32_t index = 1;
108 objectOperator.SetIndex(index);
109 EXPECT_EQ(objectOperator.GetIndex(), 1U);
110 EXPECT_TRUE(objectOperator.IsFound());
111
112 objectOperator.SetIndex(ObjectOperator::NOT_FOUND_INDEX);
113 EXPECT_FALSE(objectOperator.IsFound());
114 }
115
HWTEST_F_L0(ObjectOperatorTest,SetValue)116 HWTEST_F_L0(ObjectOperatorTest, SetValue)
117 {
118 JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(1));
119 JSHandle<JSTaggedValue> handleValue1(thread, JSTaggedValue(2));
120 JSHandle<JSTaggedValue> handleValue2(thread, JSTaggedValue(3));
121 ObjectOperator objectOperator(thread, handleKey);
122
123 EXPECT_TRUE(objectOperator.GetValue().IsUndefined());
124 objectOperator.SetValue(handleValue1.GetTaggedValue());
125 EXPECT_EQ(objectOperator.GetValue().GetInt(), 2);
126
127 objectOperator.SetValue(handleValue2.GetTaggedValue());
128 EXPECT_EQ(objectOperator.GetValue().GetInt(), 3);
129 }
130
HWTEST_F_L0(ObjectOperatorTest,SetAsDefaultAttr)131 HWTEST_F_L0(ObjectOperatorTest, SetAsDefaultAttr)
132 {
133 JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(1));
134 ObjectOperator objectOperator(thread, handleKey);
135 objectOperator.SetAsDefaultAttr();
136 EXPECT_EQ(objectOperator.GetIndex(), ObjectOperator::NOT_FOUND_INDEX);
137 EXPECT_TRUE(objectOperator.GetValue().IsUndefined());
138 EXPECT_FALSE(objectOperator.IsFastMode());
139 EXPECT_FALSE(objectOperator.IsTransition());
140 EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), 7);
141 }
142
HWTEST_F_L0(ObjectOperatorTest,GetHolder)143 HWTEST_F_L0(ObjectOperatorTest, GetHolder)
144 {
145 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
146
147 JSHandle<JSObject> handleHolder = factory->NewEmptyJSObject();
148 JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(1));
149 ObjectOperator objectOperator(thread, handleHolder, handleKey);
150
151 EXPECT_TRUE(objectOperator.HasHolder());
152 EXPECT_TRUE(objectOperator.GetHolder().GetTaggedValue().IsECMAObject());
153 }
154
HWTEST_F_L0(ObjectOperatorTest,GetReceiver)155 HWTEST_F_L0(ObjectOperatorTest, GetReceiver)
156 {
157 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
158
159 JSHandle<EcmaString> handleNameString = factory->NewFromASCII("name");
160 JSHandle<JSTaggedValue> handleReceiver(thread, JSTaggedValue(1));
161
162 ObjectOperator objectOperator(thread, handleReceiver.GetTaggedValue(), handleNameString.GetTaggedValue());
163 EXPECT_EQ(objectOperator.GetReceiver()->GetInt(), 1);
164 }
165
HWTEST_F_L0(ObjectOperatorTest,GetElementIndex)166 HWTEST_F_L0(ObjectOperatorTest, GetElementIndex)
167 {
168 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
169
170 JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
171 JSHandle<JSTaggedValue> handleKey2(thread, JSTaggedValue(2.0));
172 JSHandle<JSTaggedValue> handleKey3(factory->NewFromASCII("2"));
173
174 ObjectOperator objectOperator1(thread, handleKey1);
175 ObjectOperator objectOperator2(thread, handleKey2);
176 ObjectOperator objectOperator3(thread, handleKey3);
177
178 EXPECT_EQ(objectOperator1.GetElementIndex(), 1U);
179 EXPECT_EQ(objectOperator2.GetElementIndex(), 2U);
180 EXPECT_EQ(objectOperator3.GetElementIndex(), 2U);
181 }
182
HWTEST_F_L0(ObjectOperatorTest,GetKey)183 HWTEST_F_L0(ObjectOperatorTest, GetKey)
184 {
185 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
186
187 JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
188 JSHandle<JSTaggedValue> handleKey2(factory->NewFromASCII("name"));
189
190 ObjectOperator objectOperator1(thread, handleKey1);
191 ObjectOperator objectOperator2(thread, handleKey2);
192
193 EXPECT_TRUE(objectOperator1.GetKey()->IsUndefined());
194 EXPECT_TRUE(objectOperator1.IsElement());
195
196 EXPECT_FALSE(objectOperator2.GetKey()->IsUndefined());
197 EXPECT_FALSE(objectOperator2.IsElement());
198 }
199
HWTEST_F_L0(ObjectOperatorTest,GetThread)200 HWTEST_F_L0(ObjectOperatorTest, GetThread)
201 {
202 JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(1));
203 ObjectOperator objectOperator(thread, handleKey);
204 EXPECT_TRUE(objectOperator.GetThread() != nullptr);
205 }
206
TestDefinedGetter(EcmaRuntimeCallInfo * argv)207 JSTaggedValue TestDefinedGetter([[maybe_unused]] EcmaRuntimeCallInfo *argv)
208 {
209 // 12 : test case
210 return JSTaggedValue(12);
211 }
212
TestDefinedSetter(EcmaRuntimeCallInfo * argv)213 JSTaggedValue TestDefinedSetter([[maybe_unused]] EcmaRuntimeCallInfo *argv)
214 {
215 // 12 : test case
216 return JSTaggedValue(12);
217 }
218
JSObjectTestCreate(JSThread * thread)219 static JSFunction *JSObjectTestCreate(JSThread *thread)
220 {
221 JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
222 return globalEnv->GetObjectFunction().GetObject<JSFunction>();
223 }
224
HWTEST_F_L0(ObjectOperatorTest,ToPropertyDescriptor)225 HWTEST_F_L0(ObjectOperatorTest, ToPropertyDescriptor)
226 {
227 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
228 JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("property"));
229 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(1));
230 JSHandle<AccessorData> handleAccessor = factory->NewAccessorData();
231 JSHandle<AccessorData> handleInternalAccessor =
232 factory->NewInternalAccessor(nullptr, reinterpret_cast<void *>(TestDefinedGetter));
233 JSHandle<JSTaggedValue> handleHolder(factory->NewEmptyJSObject());
234
235 PropertyDescriptor handleDesc(thread);
236 handleDesc.SetGetter(handleValue);
237 handleDesc.SetSetter(handleValue);
238 PropertyDescriptor handleDesc1(thread);
239 handleDesc1.SetWritable(true);
240 PropertyDescriptor handleDesc2(thread);
241 handleDesc2.SetConfigurable(true);
242 handleDesc2.SetEnumerable(true);
243 PropertyDescriptor handleDesc3(thread);
244 PropertyAttributes handleAttr(handleDesc);
245
246 ObjectOperator objectOperator(thread, handleHolder, handleKey);
247 objectOperator.SetIndex(1);
248 // object is not IsAccessorDescriptor
249 objectOperator.ToPropertyDescriptor(handleDesc1);
250 EXPECT_TRUE(!handleDesc1.IsWritable());
251 EXPECT_TRUE(handleDesc1.GetValue()->IsUndefined());
252 // object is IsAccessorDescriptor
253 objectOperator.SetAttr(handleAttr);
254 objectOperator.SetValue(handleAccessor.GetTaggedValue());
255 objectOperator.ToPropertyDescriptor(handleDesc2);
256 EXPECT_FALSE(handleDesc2.IsEnumerable());
257 EXPECT_FALSE(handleDesc2.IsConfigurable());
258 EXPECT_TRUE(handleDesc2.GetGetter()->IsUndefined());
259 EXPECT_TRUE(handleDesc2.GetSetter()->IsUndefined());
260
261 objectOperator.SetValue(handleInternalAccessor.GetTaggedValue());
262 objectOperator.ToPropertyDescriptor(handleDesc3);
263 EXPECT_EQ(handleDesc3.GetValue()->GetInt(), 12);
264 }
265
HWTEST_F_L0(ObjectOperatorTest,handleKey)266 HWTEST_F_L0(ObjectOperatorTest, handleKey)
267 {
268 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
269
270 JSHandle<JSTaggedValue> handleString(factory->NewFromASCII("key"));
271 JSHandle<JSTaggedValue> handleObject(factory->NewEmptyJSObject());
272 JSHandle<JSTaggedValue> handleSymbol(factory->NewJSSymbol());
273 JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(-1));
274 JSHandle<JSTaggedValue> handleKey2(thread, JSTaggedValue(-1.11));
275 JSHandle<JSTaggedValue> handleKey3(thread, handleString.GetTaggedValue());
276 JSHandle<JSTaggedValue> handleKey4(thread, handleSymbol.GetTaggedValue());
277 JSHandle<JSTaggedValue> handleKey5(thread, handleObject.GetTaggedValue());
278 JSHandle<JSTaggedValue> handleKey6(thread, JSTaggedValue(1.11));
279
280 ObjectOperator objectOperator1(thread, handleKey1);
281 ObjectOperator objectOperator2(thread, handleKey2);
282 ObjectOperator objectOperator3(thread, handleKey3);
283 ObjectOperator objectOperator4(thread, handleKey4);
284 ObjectOperator objectOperator5(thread, handleKey5);
285 ObjectOperator objectOperator6(thread, handleKey6);
286
287 JSHandle<EcmaString> handleEcmaStrTo1(objectOperator1.GetKey());
288 EXPECT_STREQ("-1", EcmaStringAccessor(handleEcmaStrTo1).ToCString(thread).c_str());
289
290 JSHandle<EcmaString> handleEcmaStrTo2(objectOperator2.GetKey());
291 EXPECT_STREQ("-1.11", EcmaStringAccessor(handleEcmaStrTo2).ToCString(thread).c_str());
292
293 EcmaString *str1 = EcmaString::Cast(objectOperator3.GetKey()->GetTaggedObject());
294 EXPECT_TRUE(EcmaStringAccessor(str1).IsInternString());
295
296 EXPECT_TRUE(objectOperator4.GetKey()->IsSymbol());
297
298 EcmaString *str2 = EcmaString::Cast(objectOperator5.GetKey()->GetTaggedObject());
299 EXPECT_TRUE(EcmaStringAccessor(str2).IsInternString());
300
301 JSHandle<EcmaString> handleEcmaStrTo3(objectOperator6.GetKey());
302 EXPECT_STREQ("1.11", EcmaStringAccessor(handleEcmaStrTo3).ToCString(thread).c_str());
303 }
304
HWTEST_F_L0(ObjectOperatorTest,FastGetValue)305 HWTEST_F_L0(ObjectOperatorTest, FastGetValue)
306 {
307 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
308 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
309
310 JSHandle<EcmaString> handleNameString = factory->NewFromASCII("name");
311 JSHandle<AccessorData> handleAccessorData = factory->NewAccessorData();
312 JSHandle<JSTaggedValue> handleReceiver(thread, JSTaggedValue(123));
313 JSHandle<JSTaggedValue> handleValue1(factory->NewPropertyBox(handleReceiver));
314 JSHandle<JSTaggedValue> handleValue2(handleAccessorData);
315 JSHandle<JSTaggedValue> handleValue3(thread, JSTaggedValue(1));
316
317 ObjectOperator objectOperator1(thread, handleValue3);
318 objectOperator1.SetIndex(1);
319 objectOperator1.SetValue(handleValue1.GetTaggedValue());
320 EXPECT_EQ(objectOperator1.FastGetValue()->GetInt(), 123);
321
322 // op for fast path
323 ObjectOperator objectOperator2(thread, handleReceiver.GetTaggedValue(), handleNameString.GetTaggedValue());
324 objectOperator2.SetIndex(1);
325 objectOperator2.SetValue(handleValue2.GetTaggedValue());
326 PropertyDescriptor handleDesc(thread);
327 handleDesc.SetGetter(handleValue2);
328 handleDesc.SetSetter(handleValue2);
329 objectOperator2.SetAttr(PropertyAttributes(handleDesc));
330 EXPECT_TRUE(objectOperator2.FastGetValue()->IsUndefined());
331
332 JSHandle<JSFunction> handleGetter = factory->NewJSFunction(env, reinterpret_cast<void *>(TestDefinedGetter));
333 handleAccessorData->SetGetter(thread, handleGetter.GetTaggedValue());
334 EXPECT_EQ(objectOperator2.FastGetValue()->GetInt(), 12);
335 }
336
HWTEST_F_L0(ObjectOperatorTest,ReLookupPropertyInReceiver_001)337 HWTEST_F_L0(ObjectOperatorTest, ReLookupPropertyInReceiver_001)
338 {
339 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
340 JSHandle<JSTaggedValue> undefined = thread->GlobalConstants()->GetHandledUndefined();
341 JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
342 JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(2));
343 JSHandle<JSTaggedValue> handleName(factory->NewFromASCII("123"));
344 JSHandle<JSTaggedValue> handleHolder(factory->NewFromASCII("12"));
345 JSHandle<JSTaggedValue> handleReceiver(factory->NewJSString(handleName, undefined));
346 // Receiver is string
347 ObjectOperator objectOperator1(thread, handleHolder, handleReceiver, handleKey);
348 objectOperator1.ReLookupPropertyInReceiver();
349 EXPECT_EQ(objectOperator1.GetIndex(), 2U);
350 EXPECT_TRUE(objectOperator1.GetValue().IsString());
351 EXPECT_EQ(objectOperator1.GetAttr().GetPropertyMetaData(), 2);
352 EXPECT_TRUE(objectOperator1.IsFastMode());
353 // Receiver is not DictionaryMode
354 JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
355 for (int i = 0; i < 3; i++) {
356 JSHandle<JSTaggedValue> newKey(thread, JSTaggedValue(i));
357 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), newKey, newKey);
358 }
359 ObjectOperator objectOperator2(thread, handleHolder, JSHandle<JSTaggedValue>(handleObject), handleKey);
360 objectOperator2.ReLookupPropertyInReceiver();
361 EXPECT_EQ(objectOperator2.GetIndex(), 2U);
362 EXPECT_EQ(objectOperator2.GetValue().GetInt(), 2);
363 EXPECT_EQ(objectOperator2.GetAttr().GetPropertyMetaData(), 7);
364 EXPECT_TRUE(objectOperator2.IsFastMode());
365 // Receiver is DictionaryMode
366 JSObject::DeleteProperty(thread, (handleObject), handleKey);
367 ObjectOperator objectOperator3(thread, handleHolder, JSHandle<JSTaggedValue>(handleObject), handleKey);
368 objectOperator3.ReLookupPropertyInReceiver(); // no key find
369 EXPECT_EQ(objectOperator3.GetIndex(), ObjectOperator::NOT_FOUND_INDEX);
370 EXPECT_TRUE(objectOperator3.GetValue().IsUndefined());
371 EXPECT_EQ(objectOperator3.GetAttr().GetPropertyMetaData(), 0);
372 EXPECT_FALSE(objectOperator3.IsFastMode());
373 }
374
HWTEST_F_L0(ObjectOperatorTest,ReLookupPropertyInReceiver_002)375 HWTEST_F_L0(ObjectOperatorTest, ReLookupPropertyInReceiver_002)
376 {
377 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
378 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
379 JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
380 JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(0));
381 JSHandle<JSTaggedValue> handleKey2(thread, JSTaggedValue(1));
382 JSHandle<JSTaggedValue> handleHolder(factory->NewFromASCII("12"));
383 JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
384 JSHandle<JSObject> handleReceiver(globalObj);
385 PropertyAttributes handleAttr(4);
386 // Receiver is JSGlobalObject(no properties)
387 ObjectOperator objectOperator1(thread, handleHolder, JSHandle<JSTaggedValue>(handleReceiver), handleKey);
388 objectOperator1.ReLookupPropertyInReceiver();
389 EXPECT_EQ(objectOperator1.GetIndex(), ObjectOperator::NOT_FOUND_INDEX);
390 EXPECT_TRUE(objectOperator1.GetValue().IsUndefined());
391 EXPECT_EQ(objectOperator1.GetAttr().GetPropertyMetaData(), 0);
392 EXPECT_FALSE(objectOperator1.IsFastMode());
393 // Receiver is JSGlobalObject(properties)
394 JSMutableHandle<GlobalDictionary> receiverDict(thread, handleReceiver->GetProperties(thread));
395 JSHandle<GlobalDictionary> handleDict = GlobalDictionary::Create(thread, 4); // numberofElements = 4
396 receiverDict.Update(handleDict.GetTaggedValue());
397 JSHandle<PropertyBox> cellHandle = factory->NewPropertyBox(handleKey);
398 cellHandle->SetValue(thread, JSTaggedValue(4));
399 JSHandle<GlobalDictionary> handleProperties =
400 GlobalDictionary::PutIfAbsent(thread, receiverDict, handleKey, JSHandle<JSTaggedValue>(cellHandle), handleAttr);
401 handleReceiver->SetProperties(thread, handleProperties.GetTaggedValue());
402 int keyEntry = handleProperties->FindEntry(thread, handleKey.GetTaggedValue());
403 ObjectOperator objectOperator2(thread, handleHolder, JSHandle<JSTaggedValue>(handleReceiver), handleKey);
404 objectOperator2.ReLookupPropertyInReceiver();
405 EXPECT_EQ(objectOperator2.GetIndex(), static_cast<uint32_t>(keyEntry));
406 EXPECT_TRUE(objectOperator2.GetValue().IsPropertyBox());
407 EXPECT_EQ(objectOperator2.GetAttr().GetPropertyMetaData(), handleAttr.GetPropertyMetaData());
408 EXPECT_TRUE(objectOperator2.IsFastMode());
409 }
410
HWTEST_F_L0(ObjectOperatorTest,ReLookupPropertyInReceiver_003)411 HWTEST_F_L0(ObjectOperatorTest, ReLookupPropertyInReceiver_003)
412 {
413 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
414 JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
415 JSHandle<JSTaggedValue> handleHolder(factory->NewFromASCII("12"));
416 JSHandle<JSTaggedValue> handleKey(factory->NewFromASCII("key"));
417 JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
418 JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
419 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey, handleKey1);
420 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey1, handleKey1);
421 // Receiver is not DictionaryMode
422 ObjectOperator objectOperator1(thread, handleHolder, JSHandle<JSTaggedValue>(handleObject), handleKey);
423 objectOperator1.ReLookupPropertyInReceiver();
424 EXPECT_EQ(objectOperator1.GetIndex(), 0U);
425 EXPECT_EQ(objectOperator1.GetValue().GetInt(), 1);
426 EXPECT_EQ(objectOperator1.GetAttr().GetPropertyMetaData(), 7); // default attribute
427 EXPECT_TRUE(objectOperator1.IsFastMode());
428 // Receiver is DictionaryMode
429 JSObject::DeleteProperty(thread, (handleObject), handleKey);
430 ObjectOperator objectOperator2(thread, handleHolder, JSHandle<JSTaggedValue>(handleObject), handleKey);
431 objectOperator2.ReLookupPropertyInReceiver();
432 EXPECT_EQ(objectOperator2.GetIndex(), ObjectOperator::NOT_FOUND_INDEX);
433 EXPECT_TRUE(objectOperator2.GetValue().IsUndefined());
434 EXPECT_EQ(objectOperator2.GetAttr().GetPropertyMetaData(), 0); // default attribute
435 EXPECT_FALSE(objectOperator2.IsFastMode());
436 }
437
HWTEST_F_L0(ObjectOperatorTest,LookupProperty_001)438 HWTEST_F_L0(ObjectOperatorTest, LookupProperty_001)
439 {
440 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
441 JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(1));
442 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(2));
443 JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
444 JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
445 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey, handleValue);
446 JSHandle<JSObject> handleObject1 = JSObject::ObjectCreate(thread, handleObject);
447
448 ObjectOperator objectOperator(thread, handleObject1, handleKey);
449 // lookup for key is element
450 objectOperator.LookupProperty();
451 EXPECT_TRUE(objectOperator.IsOnPrototype());
452 EXPECT_EQ(objectOperator.GetIndex(), 1U);
453 EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), 7);
454 EXPECT_EQ(objectOperator.GetValue().GetInt(), 2);
455 EXPECT_TRUE(objectOperator.IsFastMode());
456 }
457
HWTEST_F_L0(ObjectOperatorTest,LookupProperty_002)458 HWTEST_F_L0(ObjectOperatorTest, LookupProperty_002)
459 {
460 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
461 JSHandle<JSTaggedValue> handleKey1(thread, JSTaggedValue(1));
462 JSHandle<JSTaggedValue> handleValue1(thread, JSTaggedValue(1));
463 JSHandle<JSTaggedValue> handleKey2(factory->NewFromASCII("key2"));
464 JSHandle<JSTaggedValue> handleValue2(thread, JSTaggedValue(2));
465 JSHandle<JSTaggedValue> objFunc(thread, JSObjectTestCreate(thread));
466 JSHandle<JSObject> handleObject = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFunc), objFunc);
467 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey1, handleValue1);
468 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleObject), handleKey2, handleValue2);
469 JSHandle<JSObject> handleObject1 = JSObject::ObjectCreate(thread, handleObject);
470 ObjectOperator objectOperator(thread, handleObject1, handleKey2);
471 // lookup for key is not element
472 objectOperator.LookupProperty();
473 EXPECT_TRUE(objectOperator.IsOnPrototype());
474 EXPECT_EQ(objectOperator.GetIndex(), 0U);
475 EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), 7);
476 EXPECT_EQ(objectOperator.GetValue().GetInt(), 2);
477 EXPECT_TRUE(objectOperator.IsFastMode());
478 }
479
HWTEST_F_L0(ObjectOperatorTest,GlobalLookupProperty)480 HWTEST_F_L0(ObjectOperatorTest, GlobalLookupProperty)
481 {
482 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
483 JSHandle<JSTaggedValue> handleKey(thread, JSTaggedValue(1));
484 JSHandle<JSTaggedValue> handleValue(thread, JSTaggedValue(2));
485 JSHandle<JSTaggedValue> globalObj = env->GetJSGlobalObject();
486 JSHandle<JSObject> handleGlobalObject(globalObj);
487 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(handleGlobalObject), handleKey, handleValue);
488 JSHandle<JSObject> handleObject = JSObject::ObjectCreate(thread, handleGlobalObject);
489 JSHandle<JSTaggedValue> handleGlobalObj(JSHandle<JSGlobalObject>::Cast(handleObject));
490
491 ObjectOperator objectOperator(thread, handleGlobalObj, handleKey);
492 objectOperator.GlobalLookupProperty();
493 EXPECT_TRUE(objectOperator.IsOnPrototype());
494 EXPECT_EQ(objectOperator.GetIndex(), 1U);
495 EXPECT_EQ(objectOperator.GetAttr().GetPropertyMetaData(), 7);
496 EXPECT_EQ(objectOperator.GetValue().GetInt(), 2);
497 EXPECT_TRUE(objectOperator.IsFastMode());
498 }
499 } // namespace panda::test
500