1 /*
2 * Copyright (c) 2021 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/builtins/builtins_object.h"
17
18 #include "ecmascript/ecma_runtime_call_info.h"
19 #include "ecmascript/ecma_string.h"
20 #include "ecmascript/ecma_vm.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/js_array.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_object-inl.h"
25 #include "ecmascript/js_primitive_ref.h"
26 #include "ecmascript/js_tagged_value-inl.h"
27 #include "ecmascript/js_thread.h"
28 #include "ecmascript/object_factory.h"
29 #include "ecmascript/tests/test_helper.h"
30
31 using namespace panda::ecmascript;
32 using namespace panda::ecmascript::builtins;
33
34 namespace panda::test {
35 class BuiltinsObjectTest : public testing::Test {
36 public:
SetUpTestCase()37 static void SetUpTestCase()
38 {
39 GTEST_LOG_(INFO) << "SetUpTestCase";
40 }
41
TearDownTestCase()42 static void TearDownTestCase()
43 {
44 GTEST_LOG_(INFO) << "TearDownCase";
45 }
46
SetUp()47 void SetUp() override
48 {
49 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
50 }
51
TearDown()52 void TearDown() override
53 {
54 TestHelper::DestroyEcmaVMWithScope(instance, scope);
55 }
56
57 EcmaVM *instance {nullptr};
58 EcmaHandleScope *scope {nullptr};
59 JSThread *thread {nullptr};
60 };
61
CreateBuiltinJSObject(JSThread * thread,const CString keyCStr)62 JSTaggedValue CreateBuiltinJSObject(JSThread *thread, const CString keyCStr)
63 {
64 EcmaVM *ecmaVM = thread->GetEcmaVM();
65 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
66 JSHandle<JSTaggedValue> objFun = globalEnv->GetObjectFunction();
67 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
68
69 JSHandle<JSTaggedValue> obj(factory->NewJSObjectByConstructor(JSHandle<JSFunction>(objFun), objFun));
70 JSHandle<JSTaggedValue> key(factory->NewFromASCII(&keyCStr[0]));
71 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
72 JSObject::SetProperty(thread, obj, key, value);
73 return obj.GetTaggedValue();
74 }
75
BuiltinsObjectTestCreate(JSThread * thread)76 JSFunction *BuiltinsObjectTestCreate(JSThread *thread)
77 {
78 EcmaVM *ecmaVM = thread->GetEcmaVM();
79 JSHandle<GlobalEnv> globalEnv = ecmaVM->GetGlobalEnv();
80 return globalEnv->GetObjectFunction().GetObject<JSFunction>();
81 }
82
TestNewJSObject(JSThread * thread,const JSHandle<JSHClass> & hclass)83 JSObject *TestNewJSObject(JSThread *thread, const JSHandle<JSHClass> &hclass)
84 {
85 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
86 JSObject *obj = JSObject::Cast(factory->NewObject(hclass));
87
88 obj->SetElements(thread, factory->EmptyArray().GetTaggedValue(), SKIP_BARRIER);
89 return obj;
90 }
91
92 // 19.1.1.1Object ( [ value ] )
HWTEST_F_L0(BuiltinsObjectTest,ObjectConstructor)93 HWTEST_F_L0(BuiltinsObjectTest, ObjectConstructor)
94 {
95 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
96 JSHandle<JSFunction> objectFunc(thread, BuiltinsObjectTestCreate(thread));
97 JSHandle<GlobalEnv> globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
98 JSHandle<JSFunction> objFun(globalEnv->GetObjectFunction());
99
100 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
101 objCallInfo->SetFunction(JSTaggedValue::Undefined());
102 objCallInfo->SetThis(JSTaggedValue::Undefined());
103
104 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
105 JSTaggedValue result = BuiltinsObject::ObjectConstructor(objCallInfo);
106 TestHelper::TearDownFrame(thread, prev);
107
108 ASSERT_TRUE(result.IsECMAObject());
109 JSHandle<JSObject> jtHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(result.GetRawData())));
110 JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(jtHandle));
111 JSTaggedValue funcProto = objectFunc->GetFunctionPrototype();
112 ASSERT_EQ(resultProto, funcProto);
113 ASSERT_TRUE(jtHandle->IsExtensible());
114
115 // num_args = 0
116 JSHandle<JSObject> object =
117 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
118 object->GetJSHClass()->SetCallable(true);
119 auto tgObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*object), 4);
120 tgObjCallInfo->SetFunction(JSTaggedValue(*objFun));
121 tgObjCallInfo->SetThis(JSTaggedValue::Undefined());
122 tgObjCallInfo->SetNewTarget(JSTaggedValue(*objFun));
123
124 prev = TestHelper::SetupFrame(thread, tgObjCallInfo);
125 JSTaggedValue resultTg = BuiltinsObject::ObjectConstructor(tgObjCallInfo);
126 TestHelper::TearDownFrame(thread, prev);
127 ASSERT_TRUE(resultTg.IsObject());
128 JSHandle<JSObject> jtHandleTg(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(resultTg.GetRawData())));
129 JSTaggedValue resultProtoTg = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(jtHandleTg));
130 JSTaggedValue funcProtoTg = objectFunc->GetFunctionPrototype();
131 ASSERT_EQ(resultProtoTg, funcProtoTg);
132 ASSERT_TRUE(jtHandleTg->IsExtensible());
133
134 // value is null
135 JSHandle<JSObject> objectVn =
136 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
137 objectVn->GetJSHClass()->SetCallable(true);
138 auto vnObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*objectVn), 6);
139 vnObjCallInfo->SetFunction(JSTaggedValue(*objFun));
140 vnObjCallInfo->SetThis(JSTaggedValue::Undefined());
141 vnObjCallInfo->SetCallArg(0, JSTaggedValue::Null());
142 vnObjCallInfo->SetNewTarget(JSTaggedValue(*objFun));
143
144 prev = TestHelper::SetupFrame(thread, vnObjCallInfo);
145 JSTaggedValue resultVn = BuiltinsObject::ObjectConstructor(vnObjCallInfo);
146 TestHelper::TearDownFrame(thread, prev);
147
148 ASSERT_TRUE(resultVn.IsObject());
149 JSHandle<JSObject> jtHandleVn(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(resultVn.GetRawData())));
150 JSTaggedValue resultProtoVn = JSTaggedValue::GetPrototype(thread, JSHandle<JSTaggedValue>(jtHandleVn));
151 JSTaggedValue funcProtoVn = objectFunc->GetFunctionPrototype();
152 ASSERT_EQ(resultProtoVn, funcProtoVn);
153 ASSERT_TRUE(jtHandleVn->IsExtensible());
154 }
155
156 // 19.1.2.1Object.assign ( target, ...sources )
HWTEST_F_L0(BuiltinsObjectTest,Assign)157 HWTEST_F_L0(BuiltinsObjectTest, Assign)
158 {
159 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
160 JSHandle<JSObject> objHandle1 =
161 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
162 JSHandle<JSObject> objHandle2 =
163 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
164
165 JSHandle<JSTaggedValue> key1(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
166 JSHandle<JSTaggedValue> value1(thread, JSTaggedValue(1));
167 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle1), key1, value1);
168 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(objHandle1), key1).GetValue()->GetInt(), 1);
169
170 JSHandle<JSTaggedValue> key2(thread->GetEcmaVM()->GetFactory()->NewFromASCII("y"));
171 JSHandle<JSTaggedValue> value2(thread, JSTaggedValue(2));
172 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle2), key2, value2);
173 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(objHandle2), key2).GetValue()->GetInt(), 2);
174
175 auto assignObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
176 assignObjCallInfo->SetFunction(JSTaggedValue::Undefined());
177 assignObjCallInfo->SetThis(JSTaggedValue::Undefined());
178 assignObjCallInfo->SetCallArg(0, objHandle1.GetTaggedValue());
179 assignObjCallInfo->SetCallArg(1, objHandle2.GetTaggedValue());
180
181 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, assignObjCallInfo);
182 JSTaggedValue result = BuiltinsObject::Assign(assignObjCallInfo);
183 TestHelper::TearDownFrame(thread, prev);
184
185 ASSERT_TRUE(result.IsECMAObject());
186 JSHandle<JSTaggedValue> jtHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(result.GetRawData())));
187 EXPECT_EQ(JSObject::GetProperty(thread, jtHandle, key1).GetValue()->GetInt(), 1);
188 EXPECT_EQ(JSObject::GetProperty(thread, jtHandle, key2).GetValue()->GetInt(), 2);
189 }
190
191 // 19.1.2.2Object.create ( O [ , Properties ] )
HWTEST_F_L0(BuiltinsObjectTest,Create)192 HWTEST_F_L0(BuiltinsObjectTest, Create)
193 {
194 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
195 JSHandle<JSFunction> objectFunc(thread, BuiltinsObjectTestCreate(thread));
196 JSHandle<JSTaggedValue> funcProto(thread, objectFunc->GetFunctionPrototype());
197
198 // no prop
199 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
200 objCallInfo->SetFunction(JSTaggedValue::Undefined());
201 objCallInfo->SetThis(JSTaggedValue::Undefined());
202 objCallInfo->SetCallArg(0, funcProto.GetTaggedValue());
203
204 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
205 JSTaggedValue result = BuiltinsObject::Create(objCallInfo);
206 TestHelper::TearDownFrame(thread, prev);
207
208 ASSERT_TRUE(result.IsECMAObject());
209 JSHandle<JSTaggedValue> jtHandle(thread, result);
210 JSTaggedValue resultProto = JSTaggedValue::GetPrototype(thread, jtHandle);
211 ASSERT_EQ(resultProto, funcProto.GetTaggedValue());
212
213 // has prop
214 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("prop"));
215 JSHandle<JSObject> objHandle =
216 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
217 EXPECT_TRUE(*objHandle != nullptr);
218
219 PropertyDescriptor desc(thread);
220 desc.SetWritable(false);
221 JSHandle<JSObject> descHandle(JSObject::FromPropertyDescriptor(thread, desc));
222
223 PropertyDescriptor descNw(thread, JSHandle<JSTaggedValue>::Cast(descHandle), true, true, true);
224 JSObject::DefineOwnProperty(thread, objHandle, key, descNw);
225
226 auto hpObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
227 hpObjCallInfo->SetFunction(JSTaggedValue::Undefined());
228 hpObjCallInfo->SetThis(JSTaggedValue::Undefined());
229 hpObjCallInfo->SetCallArg(0, funcProto.GetTaggedValue());
230 hpObjCallInfo->SetCallArg(1, objHandle.GetTaggedValue());
231
232 prev = TestHelper::SetupFrame(thread, hpObjCallInfo);
233 JSTaggedValue resultHp = BuiltinsObject::Create(hpObjCallInfo);
234 TestHelper::TearDownFrame(thread, prev);
235
236 ASSERT_TRUE(resultHp.IsObject());
237 PropertyDescriptor descRes(thread);
238 bool success = JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, resultHp), key, descRes);
239 EXPECT_TRUE(success);
240 EXPECT_TRUE(!descRes.IsWritable());
241
242 // undefined
243 auto unCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
244 unCallInfo->SetFunction(JSTaggedValue::Undefined());
245 unCallInfo->SetThis(JSTaggedValue::Undefined());
246 unCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
247
248 prev = TestHelper::SetupFrame(thread, unCallInfo);
249 JSTaggedValue resultUn = BuiltinsObject::Create(unCallInfo);
250 TestHelper::TearDownFrame(thread, prev);
251 ASSERT_EQ(resultUn.GetRawData(), JSTaggedValue::VALUE_EXCEPTION);
252 }
253
254 // 19.1.2.3Object.defineProperties ( O, Properties )
HWTEST_F_L0(BuiltinsObjectTest,DefineProperties)255 HWTEST_F_L0(BuiltinsObjectTest, DefineProperties)
256 {
257 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
258 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
259 JSHandle<JSFunction> objFunc(env->GetObjectFunction());
260 JSHandle<JSObject> objHandle =
261 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
262 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("prop"));
263 JSHandle<JSObject> jsobjHandle =
264 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
265
266 PropertyDescriptor desc(thread);
267 desc.SetWritable(false);
268 JSHandle<JSObject> descHandle(JSObject::FromPropertyDescriptor(thread, desc));
269
270 PropertyDescriptor descNw(thread, JSHandle<JSTaggedValue>::Cast(descHandle), true, true, true);
271 JSObject::DefineOwnProperty(thread, jsobjHandle, key, descNw);
272
273 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
274 objCallInfo->SetFunction(JSTaggedValue::Undefined());
275 objCallInfo->SetThis(JSTaggedValue::Undefined());
276 objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
277 objCallInfo->SetCallArg(1, jsobjHandle.GetTaggedValue());
278
279 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
280 JSTaggedValue result = BuiltinsObject::DefineProperties(objCallInfo);
281 TestHelper::TearDownFrame(thread, prev);
282
283 ASSERT_TRUE(result.IsECMAObject());
284 JSTaggedValue res(reinterpret_cast<TaggedObject *>(result.GetRawData()));
285 PropertyDescriptor descRes(thread);
286 JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, res), key, descRes);
287 EXPECT_TRUE(!descRes.IsWritable());
288 }
289
290 // 19.1.2.4Object.defineProperty ( O, P, Attributes )
HWTEST_F_L0(BuiltinsObjectTest,DefineProperty)291 HWTEST_F_L0(BuiltinsObjectTest, DefineProperty)
292 {
293 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
294
295 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
296 JSHandle<JSFunction> objFunc(env->GetObjectFunction());
297 JSHandle<JSObject> attHandle =
298 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
299 JSHandle<JSObject> objHandle =
300 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
301
302 PropertyDescriptor desc(thread);
303 desc.SetWritable(true);
304 JSHandle<JSTaggedValue> writableStr = thread->GlobalConstants()->GetHandledWritableString();
305 JSHandle<JSTaggedValue> writable(thread, JSTaggedValue(desc.IsWritable()));
306 JSObject::CreateDataProperty(thread, attHandle, writableStr, writable);
307
308 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
309
310 PropertyDescriptor descNw(thread);
311 JSObject::GetOwnProperty(thread, objHandle, key, descNw);
312 EXPECT_TRUE(!descNw.HasWritable());
313
314 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
315 objCallInfo->SetFunction(JSTaggedValue::Undefined());
316 objCallInfo->SetThis(JSTaggedValue::Undefined());
317 objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
318 objCallInfo->SetCallArg(1, key.GetTaggedValue());
319 objCallInfo->SetCallArg(2, attHandle.GetTaggedValue());
320
321 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
322 JSTaggedValue result = BuiltinsObject::DefineProperty(objCallInfo);
323 TestHelper::TearDownFrame(thread, prev);
324
325 ASSERT_TRUE(result.IsECMAObject());
326 JSTaggedValue res(reinterpret_cast<TaggedObject *>(result.GetRawData()));
327 PropertyDescriptor descRes(thread);
328 JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, res), key, descRes);
329 EXPECT_TRUE(descRes.HasWritable());
330 }
331
332 // 19.1.2.5Object.freeze ( O )
HWTEST_F_L0(BuiltinsObjectTest,Freeze)333 HWTEST_F_L0(BuiltinsObjectTest, Freeze)
334 {
335 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
336 // An object is extensible by default, so it is also non-frozen.
337 JSHandle<JSObject> emptyObj =
338 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
339 emptyObj->GetJSHClass()->SetExtensible(true);
340 auto nofreezeObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
341 nofreezeObjCallInfo->SetFunction(JSTaggedValue::Undefined());
342 nofreezeObjCallInfo->SetThis(JSTaggedValue::Undefined());
343 nofreezeObjCallInfo->SetCallArg(0, emptyObj.GetTaggedValue());
344
345 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, nofreezeObjCallInfo);
346 JSTaggedValue result = BuiltinsObject::IsFrozen(nofreezeObjCallInfo);
347
348 ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
349
350 BuiltinsObject::Freeze(nofreezeObjCallInfo);
351 JSTaggedValue resultIs = BuiltinsObject::IsFrozen(nofreezeObjCallInfo);
352 TestHelper::TearDownFrame(thread, prev);
353 ASSERT_EQ(resultIs.GetRawData(), JSTaggedValue::True().GetRawData());
354 }
355
356 // 19.1.2.6 Object.getOwnPropertyDescriptor ( O, P )
HWTEST_F_L0(BuiltinsObjectTest,GetOwnPropertyDescriptor)357 HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertyDescriptor)
358 {
359 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
360 JSHandle<JSObject> objHandle =
361 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
362
363 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
364
365 PropertyDescriptor descEnum(thread);
366 descEnum.SetWritable(true);
367 JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(objHandle), key, descEnum);
368
369 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
370 objCallInfo->SetFunction(JSTaggedValue::Undefined());
371 objCallInfo->SetThis(JSTaggedValue::Undefined());
372 objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
373 objCallInfo->SetCallArg(1, key.GetTaggedValue());
374
375 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
376 JSTaggedValue result = BuiltinsObject::GetOwnPropertyDescriptor(objCallInfo);
377 TestHelper::TearDownFrame(thread, prev);
378
379 ASSERT_TRUE(result.IsECMAObject());
380
381 JSHandle<JSTaggedValue> writableStr = thread->GlobalConstants()->GetHandledWritableString();
382 JSTaggedValue jt(reinterpret_cast<TaggedObject *>(result.GetRawData()));
383 PropertyDescriptor desc(thread);
384 JSObject::GetOwnProperty(thread, JSHandle<JSObject>(thread, jt), writableStr, desc);
385 ASSERT_TRUE(JSTaggedValue::SameValue(desc.GetValue().GetTaggedValue(), JSTaggedValue(true)));
386 }
387
388 // 19.1.2.7 Object.getOwnPropertyNames ( O )
HWTEST_F_L0(BuiltinsObjectTest,GetOwnPropertyNames)389 HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertyNames)
390 {
391 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
392 JSHandle<JSObject> objHandle =
393 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
394
395 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
396 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
397 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle), key, value);
398
399 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
400 objCallInfo->SetFunction(JSTaggedValue::Undefined());
401 objCallInfo->SetThis(JSTaggedValue::Undefined());
402 objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
403
404 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
405 JSTaggedValue result = BuiltinsObject::GetOwnPropertyNames(objCallInfo);
406 TestHelper::TearDownFrame(thread, prev);
407
408 ASSERT_TRUE(result.IsECMAObject());
409 }
410
411 // 19.1.2.8 Object.getOwnPropertySymbols ( O )
HWTEST_F_L0(BuiltinsObjectTest,GetOwnPropertySymbols)412 HWTEST_F_L0(BuiltinsObjectTest, GetOwnPropertySymbols)
413 {
414 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
415 JSHandle<JSObject> objHandle =
416 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
417 JSHandle<JSSymbol> symbolKey = thread->GetEcmaVM()->GetFactory()->NewJSSymbol();
418 JSHandle<JSTaggedValue> key(symbolKey);
419 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
420 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(objHandle), key, value);
421 thread->ClearException();
422
423 auto objCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
424 objCallInfo->SetFunction(JSTaggedValue::Undefined());
425 objCallInfo->SetThis(JSTaggedValue::Undefined());
426 objCallInfo->SetCallArg(0, objHandle.GetTaggedValue());
427
428 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
429 JSTaggedValue result = BuiltinsObject::GetOwnPropertySymbols(objCallInfo);
430 TestHelper::TearDownFrame(thread, prev);
431
432 ASSERT_TRUE(result.IsECMAObject());
433 }
434
435 // 19.1.2.10 Object.is ( value1, value2 )
HWTEST_F_L0(BuiltinsObjectTest,Is)436 HWTEST_F_L0(BuiltinsObjectTest, Is)
437 {
438 // js object compare
439 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
440
441 JSHandle<JSObject> obj1 =
442 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
443 JSHandle<JSObject> obj2 =
444 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
445
446 auto objCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
447 objCallInfo1->SetFunction(JSTaggedValue::Undefined());
448 objCallInfo1->SetThis(JSTaggedValue::Undefined());
449 objCallInfo1->SetCallArg(0, obj1.GetTaggedValue());
450 objCallInfo1->SetCallArg(1, obj2.GetTaggedValue());
451
452 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo1);
453 JSTaggedValue objResult1 = BuiltinsObject::Is(objCallInfo1);
454 TestHelper::TearDownFrame(thread, prev);
455
456 ASSERT_EQ(objResult1.GetRawData(), JSTaggedValue::False().GetRawData());
457
458 objCallInfo1->SetCallArg(1, obj1.GetTaggedValue());
459 JSTaggedValue objResult2 = BuiltinsObject::Is(objCallInfo1);
460 ASSERT_EQ(objResult2.GetRawData(), JSTaggedValue::True().GetRawData());
461
462 // string compare
463 JSHandle<EcmaString> testStrValue1 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("helloworld");
464 JSHandle<EcmaString> testStrValue2 = thread->GetEcmaVM()->GetFactory()->NewFromASCII("helloworld");
465
466 auto strCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
467 strCallInfo->SetFunction(JSTaggedValue::Undefined());
468 strCallInfo->SetThis(JSTaggedValue::Undefined());
469 strCallInfo->SetCallArg(0, testStrValue1.GetTaggedValue());
470 strCallInfo->SetCallArg(1, testStrValue2.GetTaggedValue());
471
472 prev = TestHelper::SetupFrame(thread, strCallInfo);
473 JSTaggedValue strResult = BuiltinsObject::Is(strCallInfo);
474 TestHelper::TearDownFrame(thread, prev);
475
476 ASSERT_EQ(strResult.GetRawData(), JSTaggedValue::True().GetRawData());
477
478 // bool compare
479 auto boolCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
480 boolCallInfo->SetFunction(JSTaggedValue::Undefined());
481 boolCallInfo->SetThis(JSTaggedValue::Undefined());
482 boolCallInfo->SetCallArg(0, JSTaggedValue::True());
483 boolCallInfo->SetCallArg(1, JSTaggedValue::False());
484
485 prev = TestHelper::SetupFrame(thread, boolCallInfo);
486 JSTaggedValue boolResult = BuiltinsObject::Is(boolCallInfo);
487 TestHelper::TearDownFrame(thread, prev);
488
489 ASSERT_EQ(boolResult.GetRawData(), JSTaggedValue::False().GetRawData());
490
491 // number compare
492 auto numCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
493 numCallInfo->SetFunction(JSTaggedValue::Undefined());
494 numCallInfo->SetThis(JSTaggedValue::Undefined());
495 numCallInfo->SetCallArg(0, JSTaggedValue(static_cast<double>(0)));
496 numCallInfo->SetCallArg(1, JSTaggedValue(-0.0));
497
498 prev = TestHelper::SetupFrame(thread, numCallInfo);
499 JSTaggedValue numResult = BuiltinsObject::Is(numCallInfo);
500 TestHelper::TearDownFrame(thread, prev);
501
502 ASSERT_EQ(numResult.GetRawData(), JSTaggedValue::False().GetRawData());
503
504 // undefined or null compare
505 auto nullCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
506 nullCallInfo->SetFunction(JSTaggedValue::Undefined());
507 nullCallInfo->SetThis(JSTaggedValue::Undefined());
508 nullCallInfo->SetCallArg(0, JSTaggedValue::Null());
509 nullCallInfo->SetCallArg(1, JSTaggedValue::Null());
510
511 prev = TestHelper::SetupFrame(thread, nullCallInfo);
512 JSTaggedValue nullResult = BuiltinsObject::Is(nullCallInfo);
513 TestHelper::TearDownFrame(thread, prev);
514
515 ASSERT_EQ(nullResult.GetRawData(), JSTaggedValue::True().GetRawData());
516
517 auto undefineCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
518 undefineCallInfo->SetFunction(JSTaggedValue::Undefined());
519 undefineCallInfo->SetThis(JSTaggedValue::Undefined());
520 undefineCallInfo->SetCallArg(0, JSTaggedValue::Undefined());
521 undefineCallInfo->SetCallArg(1, JSTaggedValue::Undefined());
522
523 prev = TestHelper::SetupFrame(thread, undefineCallInfo);
524 JSTaggedValue undefineResult = BuiltinsObject::Is(undefineCallInfo);
525 TestHelper::TearDownFrame(thread, prev);
526
527 ASSERT_EQ(undefineResult.GetRawData(), JSTaggedValue::True().GetRawData());
528 }
529
530 // 19.1.2.11 Object.isExtensible ( O )
HWTEST_F_L0(BuiltinsObjectTest,IsExtensible)531 HWTEST_F_L0(BuiltinsObjectTest, IsExtensible)
532 {
533 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
534
535 // New objects can be extended by default.
536 JSHandle<JSObject> emptyObj =
537 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
538 emptyObj->GetJSHClass()->SetExtensible(true);
539 auto emptyObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
540 emptyObjCallInfo->SetFunction(JSTaggedValue::Undefined());
541 emptyObjCallInfo->SetThis(JSTaggedValue::Undefined());
542 emptyObjCallInfo->SetCallArg(0, emptyObj.GetTaggedValue());
543
544 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
545 JSTaggedValue result = BuiltinsObject::IsExtensible(emptyObjCallInfo);
546 TestHelper::TearDownFrame(thread, prev);
547
548 ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
549
550 emptyObj->GetJSHClass()->SetExtensible(false);
551 JSTaggedValue result2 = BuiltinsObject::IsExtensible(emptyObjCallInfo);
552 ASSERT_EQ(result2.GetRawData(), JSTaggedValue::False().GetRawData());
553 }
554
555 // 19.1.2.12 Object.isFrozen ( O )
HWTEST_F_L0(BuiltinsObjectTest,IsFrozen)556 HWTEST_F_L0(BuiltinsObjectTest, IsFrozen)
557 {
558 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
559 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
560 JSHandle<JSTaggedValue> value(thread, JSTaggedValue(1));
561
562 // An object is extensible by default, so it is also non-frozen.
563 JSHandle<JSObject> obj =
564 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>::Cast(function), function);
565 obj->GetJSHClass()->SetExtensible(true);
566 auto emptyObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
567 emptyObjCallInfo->SetFunction(JSTaggedValue::Undefined());
568 emptyObjCallInfo->SetThis(JSTaggedValue::Undefined());
569 emptyObjCallInfo->SetCallArg(0, obj.GetTaggedValue());
570
571 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
572 JSTaggedValue result = BuiltinsObject::IsFrozen(emptyObjCallInfo);
573 TestHelper::TearDownFrame(thread, prev);
574
575 ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
576
577 obj->GetJSHClass()->SetExtensible(false);
578 prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
579 JSTaggedValue resultNex = BuiltinsObject::IsFrozen(emptyObjCallInfo);
580 TestHelper::TearDownFrame(thread, prev);
581 ASSERT_EQ(resultNex.GetRawData(), JSTaggedValue::True().GetRawData());
582
583 PropertyDescriptor descEnum(thread);
584 descEnum.SetConfigurable(true);
585 descEnum.SetWritable(false);
586 obj->GetJSHClass()->SetExtensible(true);
587 JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, descEnum);
588 obj->GetJSHClass()->SetExtensible(false);
589 auto emptyObjCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
590 emptyObjCallInfo2->SetFunction(JSTaggedValue::Undefined());
591 emptyObjCallInfo2->SetThis(JSTaggedValue::Undefined());
592 emptyObjCallInfo2->SetCallArg(0, obj.GetTaggedValue());
593
594 prev = TestHelper::SetupFrame(thread, emptyObjCallInfo2);
595 JSTaggedValue resultNw = BuiltinsObject::IsFrozen(emptyObjCallInfo2);
596 TestHelper::TearDownFrame(thread, prev);
597
598 ASSERT_EQ(resultNw.GetRawData(), JSTaggedValue::False().GetRawData());
599
600 descEnum.SetConfigurable(false);
601 obj->GetJSHClass()->SetExtensible(true);
602 JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(obj), key, descEnum);
603 obj->GetJSHClass()->SetExtensible(false);
604 auto emptyObjCallInfo3 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
605 emptyObjCallInfo3->SetFunction(JSTaggedValue::Undefined());
606 emptyObjCallInfo3->SetThis(JSTaggedValue::Undefined());
607 emptyObjCallInfo3->SetCallArg(0, obj.GetTaggedValue());
608
609 prev = TestHelper::SetupFrame(thread, emptyObjCallInfo3);
610 JSTaggedValue resultNc = BuiltinsObject::IsFrozen(emptyObjCallInfo3);
611 TestHelper::TearDownFrame(thread, prev);
612
613 ASSERT_EQ(resultNc.GetRawData(), JSTaggedValue::True().GetRawData());
614 }
615
616 // 19.1.2.13 Object.isSealed ( O )
HWTEST_F_L0(BuiltinsObjectTest,IsSealed)617 HWTEST_F_L0(BuiltinsObjectTest, IsSealed)
618 {
619 JSHandle<JSTaggedValue> function(thread, BuiltinsObjectTestCreate(thread));
620
621 // An object is extensible by default, so it is also non-frozen.
622 JSHandle<JSObject> emptyObj =
623 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(function), function);
624 emptyObj->GetJSHClass()->SetExtensible(true);
625 auto emptyObjCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
626 emptyObjCallInfo->SetFunction(JSTaggedValue::Undefined());
627 emptyObjCallInfo->SetThis(JSTaggedValue::Undefined());
628 emptyObjCallInfo->SetCallArg(0, emptyObj.GetTaggedValue());
629
630 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, emptyObjCallInfo);
631 JSTaggedValue result = BuiltinsObject::IsSealed(emptyObjCallInfo);
632 TestHelper::TearDownFrame(thread, prev);
633
634 ASSERT_EQ(result.GetRawData(), JSTaggedValue::False().GetRawData());
635 }
636
637 // Object.keys(obj)
HWTEST_F_L0(BuiltinsObjectTest,Keys)638 HWTEST_F_L0(BuiltinsObjectTest, Keys)
639 {
640 JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
641 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
642 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
643 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
644 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
645
646 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
647 JSTaggedValue result = BuiltinsObject::Keys(ecmaRuntimeCallInfo);
648 TestHelper::TearDownFrame(thread, prev);
649
650 ASSERT_TRUE(result.IsECMAObject());
651 }
652
653 // Object.values(obj)
HWTEST_F_L0(BuiltinsObjectTest,Values)654 HWTEST_F_L0(BuiltinsObjectTest, Values)
655 {
656 JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
657 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
658 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
659 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
660 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
661
662 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
663 JSTaggedValue result = BuiltinsObject::Values(ecmaRuntimeCallInfo);
664 TestHelper::TearDownFrame(thread, prev);
665
666 ASSERT_TRUE(result.IsECMAObject());
667 }
668
669 // Object.preventExtensions(obj)
HWTEST_F_L0(BuiltinsObjectTest,PreventExtensions)670 HWTEST_F_L0(BuiltinsObjectTest, PreventExtensions)
671 {
672 JSHandle<JSObject> obj = JSHandle<JSObject>(thread, CreateBuiltinJSObject(thread, "x"));
673 obj->GetJSHClass()->SetExtensible(true);
674 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
675 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
676 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
677 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
678
679 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
680 JSTaggedValue result = BuiltinsObject::PreventExtensions(ecmaRuntimeCallInfo);
681 TestHelper::TearDownFrame(thread, prev);
682
683 ASSERT_TRUE(result.IsECMAObject());
684 JSTaggedValue jt(reinterpret_cast<TaggedObject *>(result.GetRawData()));
685 JSHandle<JSObject> jtHandle(thread, jt);
686 ASSERT_TRUE(!jtHandle->IsExtensible());
687 }
688
689 // Object.seal(obj)
HWTEST_F_L0(BuiltinsObjectTest,Seal)690 HWTEST_F_L0(BuiltinsObjectTest, Seal)
691 {
692 JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
693 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
694 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
695 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
696 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
697
698 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
699 JSTaggedValue result = BuiltinsObject::Seal(ecmaRuntimeCallInfo);
700
701 ASSERT_TRUE(result.IsECMAObject());
702 ASSERT_EQ(result.GetRawData(), obj->GetRawData());
703
704 // test isSealed().
705 JSTaggedValue res = BuiltinsObject::IsSealed(ecmaRuntimeCallInfo);
706 TestHelper::TearDownFrame(thread, prev);
707 ASSERT_EQ(res.GetRawData(), JSTaggedValue::True().GetRawData());
708 }
709
710 // Object.setPrototypeOf(obj, prototype)
HWTEST_F_L0(BuiltinsObjectTest,SetPrototypeOf)711 HWTEST_F_L0(BuiltinsObjectTest, SetPrototypeOf)
712 {
713 JSHandle<JSObject> obj(thread, CreateBuiltinJSObject(thread, "x"));
714 JSHandle<JSObject> objFather(thread, CreateBuiltinJSObject(thread, "y"));
715
716 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
717 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
718 ecmaRuntimeCallInfo->SetThis(JSTaggedValue::Undefined());
719 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
720 ecmaRuntimeCallInfo->SetCallArg(1, objFather.GetTaggedValue());
721
722 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
723 JSTaggedValue result = BuiltinsObject::SetPrototypeOf(ecmaRuntimeCallInfo);
724 TestHelper::TearDownFrame(thread, prev);
725
726 ASSERT_TRUE(result.IsECMAObject());
727 ASSERT_EQ(result.GetRawData(), obj.GetTaggedValue().GetRawData());
728
729 // test obj has property "y".
730 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("y"));
731 EXPECT_EQ(JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(obj), key).GetValue()->GetInt(), 1);
732 }
733
734 // obj.hasOwnProperty(prop)
HWTEST_F_L0(BuiltinsObjectTest,HasOwnProperty)735 HWTEST_F_L0(BuiltinsObjectTest, HasOwnProperty)
736 {
737 JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
738 CString keyCStr = "x";
739 JSHandle<EcmaString> keyString = thread->GetEcmaVM()->GetFactory()->NewFromASCII(&keyCStr[0]);
740 JSHandle<JSTaggedValue> key(keyString);
741
742 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
743 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
744 ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
745 ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
746
747 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
748 JSTaggedValue result = BuiltinsObject::HasOwnProperty(ecmaRuntimeCallInfo);
749 TestHelper::TearDownFrame(thread, prev);
750
751 ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
752 }
753
754 // prototypeObj.isPrototypeOf(object)
HWTEST_F_L0(BuiltinsObjectTest,IsPrototypeOfFalse)755 HWTEST_F_L0(BuiltinsObjectTest, IsPrototypeOfFalse)
756 {
757 JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
758 JSHandle<JSTaggedValue> objFather(thread, CreateBuiltinJSObject(thread, "y"));
759
760 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
761 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
762 ecmaRuntimeCallInfo->SetThis(objFather.GetTaggedValue());
763 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
764
765 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
766 JSTaggedValue result1 = BuiltinsObject::IsPrototypeOf(ecmaRuntimeCallInfo);
767 TestHelper::TearDownFrame(thread, prev);
768
769 ASSERT_EQ(result1.GetRawData(), JSTaggedValue::False().GetRawData());
770 }
771
HWTEST_F_L0(BuiltinsObjectTest,IsPrototypeOfTrue)772 HWTEST_F_L0(BuiltinsObjectTest, IsPrototypeOfTrue)
773 {
774 JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
775 JSHandle<JSTaggedValue> objFather(thread, CreateBuiltinJSObject(thread, "y"));
776
777 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
778 ecmaRuntimeCallInfo1->SetFunction(JSTaggedValue::Undefined());
779 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
780 ecmaRuntimeCallInfo1->SetCallArg(0, obj.GetTaggedValue());
781 ecmaRuntimeCallInfo1->SetCallArg(1, objFather.GetTaggedValue());
782
783 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
784 JSTaggedValue result1 = BuiltinsObject::SetPrototypeOf(ecmaRuntimeCallInfo1);
785 TestHelper::TearDownFrame(thread, prev);
786
787 ASSERT_TRUE(result1.IsObject());
788 ASSERT_EQ(result1.GetRawData(), obj->GetRawData());
789
790 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
791 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
792 ecmaRuntimeCallInfo2->SetThis(objFather.GetTaggedValue());
793 ecmaRuntimeCallInfo2->SetCallArg(0, obj.GetTaggedValue());
794
795 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
796 JSTaggedValue result2 = BuiltinsObject::IsPrototypeOf(ecmaRuntimeCallInfo2);
797 TestHelper::TearDownFrame(thread, prev);
798
799 ASSERT_EQ(result2.GetRawData(), JSTaggedValue::True().GetRawData());
800 }
801
802 // obj.propertyIsEnumerable(prop)
HWTEST_F_L0(BuiltinsObjectTest,PropertyIsEnumerable)803 HWTEST_F_L0(BuiltinsObjectTest, PropertyIsEnumerable)
804 {
805 JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
806 JSHandle<JSTaggedValue> key(thread->GetEcmaVM()->GetFactory()->NewFromASCII("x"));
807
808 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
809 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
810 ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
811 ecmaRuntimeCallInfo->SetCallArg(0, key.GetTaggedValue());
812
813 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
814 JSTaggedValue result = BuiltinsObject::PropertyIsEnumerable(ecmaRuntimeCallInfo);
815 TestHelper::TearDownFrame(thread, prev);
816
817 ASSERT_EQ(result.GetRawData(), JSTaggedValue::True().GetRawData());
818 }
819
820 // obj.toLocaleString()
HWTEST_F_L0(BuiltinsObjectTest,ToLocaleString)821 HWTEST_F_L0(BuiltinsObjectTest, ToLocaleString)
822 {
823 JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
824 JSHandle<JSFunction> calleeFunc = thread->GetEcmaVM()->GetFactory()->NewJSFunction(
825 thread->GetEcmaVM()->GetGlobalEnv(), reinterpret_cast<void *>(BuiltinsObject::ToString));
826 calleeFunc->GetClass()->SetCallable(true);
827 JSHandle<JSTaggedValue> calleeValue(calleeFunc);
828 JSHandle<JSTaggedValue> calleeKey(thread->GetEcmaVM()->GetFactory()->NewFromASCII("toString"));
829 JSObject::SetProperty(thread, obj, calleeKey, calleeValue);
830
831 JSHandle<EcmaString> resultValue = thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Object]");
832
833 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
834 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
835 ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
836 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
837
838 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
839 JSTaggedValue result = BuiltinsObject::ToLocaleString(ecmaRuntimeCallInfo);
840 TestHelper::TearDownFrame(thread, prev);
841
842 ASSERT_TRUE(result.IsString());
843 ASSERT_EQ(EcmaStringAccessor::Compare(*resultValue, reinterpret_cast<EcmaString *>(result.GetRawData())), 0);
844 }
845
846 // obj.toString()
HWTEST_F_L0(BuiltinsObjectTest,ToString)847 HWTEST_F_L0(BuiltinsObjectTest, ToString)
848 {
849 JSHandle<JSTaggedValue> obj = JSHandle<JSTaggedValue>(thread, CreateBuiltinJSObject(thread, "x"));
850
851 // object
852 JSHandle<EcmaString> resultValue = thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Object]");
853 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
854 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
855 ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
856
857 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
858 JSTaggedValue result = BuiltinsObject::ToString(ecmaRuntimeCallInfo);
859 TestHelper::TearDownFrame(thread, prev);
860
861 ASSERT_TRUE(result.IsString());
862 ASSERT_EQ(EcmaStringAccessor::Compare(*resultValue, reinterpret_cast<EcmaString *>(result.GetRawData())), 0);
863
864 // array
865 JSHandle<JSArray> arr = thread->GetEcmaVM()->GetFactory()->NewJSArray();
866 JSHandle<EcmaString> resultArrValue =
867 thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Array]");
868 auto arrEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
869 arrEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
870 arrEcmaRuntimeCallInfo->SetThis(arr.GetTaggedValue());
871
872 prev = TestHelper::SetupFrame(thread, arrEcmaRuntimeCallInfo);
873 JSTaggedValue resultArr = BuiltinsObject::ToString(arrEcmaRuntimeCallInfo);
874 TestHelper::TearDownFrame(thread, prev);
875
876 ASSERT_TRUE(resultArr.IsString());
877 ASSERT_EQ(EcmaStringAccessor::Compare(*resultArrValue, reinterpret_cast<EcmaString *>(resultArr.GetRawData())), 0);
878
879 // string
880 JSHandle<EcmaString> str = thread->GetEcmaVM()->GetFactory()->NewFromASCII("hello");
881 JSHandle<EcmaString> resultStrValue =
882 thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object String]");
883 auto strEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
884 strEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
885 strEcmaRuntimeCallInfo->SetThis(str.GetTaggedValue());
886
887 prev = TestHelper::SetupFrame(thread, strEcmaRuntimeCallInfo);
888 JSTaggedValue resultStr = BuiltinsObject::ToString(strEcmaRuntimeCallInfo);
889 TestHelper::TearDownFrame(thread, prev);
890
891 ASSERT_TRUE(resultStr.IsString());
892 ASSERT_EQ(EcmaStringAccessor::Compare(*resultStrValue, reinterpret_cast<EcmaString *>(resultStr.GetRawData())), 0);
893
894 // function
895 JSHandle<JSFunction> func = thread->GetEcmaVM()->GetFactory()->NewJSFunction(thread->GetEcmaVM()->GetGlobalEnv());
896 JSHandle<EcmaString> resultFuncValue =
897 thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Function]");
898 auto funcEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
899 funcEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
900 funcEcmaRuntimeCallInfo->SetThis(func.GetTaggedValue());
901
902 prev = TestHelper::SetupFrame(thread, funcEcmaRuntimeCallInfo);
903 JSTaggedValue resultFunc = BuiltinsObject::ToString(funcEcmaRuntimeCallInfo);
904 TestHelper::TearDownFrame(thread, prev);
905
906 ASSERT_TRUE(resultFunc.IsString());
907 ASSERT_EQ(EcmaStringAccessor::Compare(
908 *resultFuncValue, reinterpret_cast<EcmaString *>(resultFunc.GetRawData())), 0);
909
910 // error
911 auto ecmaVM = thread->GetEcmaVM();
912 JSHandle<GlobalEnv> env = ecmaVM->GetGlobalEnv();
913 JSHandle<JSTaggedValue> errorObject = env->GetErrorFunction();
914 JSHandle<JSObject> error =
915 thread->GetEcmaVM()->GetFactory()->NewJSObjectByConstructor(JSHandle<JSFunction>(errorObject), errorObject);
916 JSHandle<EcmaString> errorValue = thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Error]");
917 auto errorEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
918 errorEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
919 errorEcmaRuntimeCallInfo->SetThis(error.GetTaggedValue());
920
921 prev = TestHelper::SetupFrame(thread, errorEcmaRuntimeCallInfo);
922 JSTaggedValue resultError = BuiltinsObject::ToString(errorEcmaRuntimeCallInfo);
923 TestHelper::TearDownFrame(thread, prev);
924
925 ASSERT_TRUE(resultError.IsString());
926 ASSERT_EQ(EcmaStringAccessor::Compare(*errorValue, reinterpret_cast<EcmaString *>(resultError.GetRawData())), 0);
927
928 // boolean
929 JSHandle<JSTaggedValue> value(thread, JSTaggedValue::False());
930 JSHandle<JSFunction> booleanObject(env->GetBooleanFunction());
931 JSHandle<JSPrimitiveRef> boolean = thread->GetEcmaVM()->GetFactory()->NewJSPrimitiveRef(booleanObject, value);
932 JSHandle<EcmaString> resultBoolValue =
933 thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Boolean]");
934 auto boolEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
935 boolEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
936 boolEcmaRuntimeCallInfo->SetThis(boolean.GetTaggedValue());
937
938 prev = TestHelper::SetupFrame(thread, boolEcmaRuntimeCallInfo);
939 JSTaggedValue resultBool = BuiltinsObject::ToString(boolEcmaRuntimeCallInfo);
940 TestHelper::TearDownFrame(thread, prev);
941
942 ASSERT_TRUE(resultBool.IsString());
943 ASSERT_EQ(EcmaStringAccessor::Compare(
944 *resultBoolValue, reinterpret_cast<EcmaString *>(resultBool.GetRawData())), 0);
945
946 // number
947 JSHandle<EcmaString> resultNumValue =
948 thread->GetEcmaVM()->GetFactory()->NewFromASCII("[object Number]");
949 auto numEcmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
950 numEcmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
951 numEcmaRuntimeCallInfo->SetThis(JSTaggedValue(static_cast<double>(0)));
952
953 prev = TestHelper::SetupFrame(thread, numEcmaRuntimeCallInfo);
954 JSTaggedValue resultNum = BuiltinsObject::ToString(numEcmaRuntimeCallInfo);
955 TestHelper::TearDownFrame(thread, prev);
956
957 ASSERT_TRUE(resultNum.IsString());
958 ASSERT_EQ(EcmaStringAccessor::Compare(*resultNumValue, reinterpret_cast<EcmaString *>(resultNum.GetRawData())), 0);
959 }
960
961 // object.valueOf()
HWTEST_F_L0(BuiltinsObjectTest,ValueOf)962 HWTEST_F_L0(BuiltinsObjectTest, ValueOf)
963 {
964 JSHandle<JSTaggedValue> obj(thread, CreateBuiltinJSObject(thread, "x"));
965 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
966 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
967 ecmaRuntimeCallInfo->SetThis(obj.GetTaggedValue());
968 ecmaRuntimeCallInfo->SetCallArg(0, obj.GetTaggedValue());
969
970 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
971 JSTaggedValue result = BuiltinsObject::ValueOf(ecmaRuntimeCallInfo);
972 TestHelper::TearDownFrame(thread, prev);
973
974 ASSERT_TRUE(result.IsECMAObject());
975 }
976 } // namespace panda::test
977