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_function.h"
17 #include "ecmascript/builtins/builtins_boolean.h"
18
19 #include "ecmascript/ecma_runtime_call_info.h"
20 #include "ecmascript/ecma_string.h"
21 #include "ecmascript/ecma_vm.h"
22 #include "ecmascript/global_env.h"
23 #include "ecmascript/js_array.h"
24 #include "ecmascript/js_function.h"
25 #include "ecmascript/js_object-inl.h"
26
27 #include "ecmascript/object_factory.h"
28 #include "ecmascript/tagged_array-inl.h"
29 #include "ecmascript/tests/test_helper.h"
30
31 using namespace panda::ecmascript;
32 using namespace panda::ecmascript::builtins;
33 using BuiltinsBase = panda::ecmascript::base::BuiltinsBase;
34 using JSArray = panda::ecmascript::JSArray;
35
36 namespace panda::test {
37 class BuiltinsFunctionTest : public testing::Test {
38 public:
SetUpTestCase()39 static void SetUpTestCase()
40 {
41 GTEST_LOG_(INFO) << "SetUpTestCase";
42 }
43
TearDownTestCase()44 static void TearDownTestCase()
45 {
46 GTEST_LOG_(INFO) << "TearDownCase";
47 }
48
SetUp()49 void SetUp() override
50 {
51 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
52 }
53
TearDown()54 void TearDown() override
55 {
56 TestHelper::DestroyEcmaVMWithScope(instance, scope);
57 }
58
59 EcmaVM *instance {nullptr};
60 EcmaHandleScope *scope {nullptr};
61 JSThread *thread {nullptr};
62 };
63
64 // native function for test apply and call
TestFunctionApplyAndCall(EcmaRuntimeCallInfo * argv)65 JSTaggedValue TestFunctionApplyAndCall(EcmaRuntimeCallInfo *argv)
66 {
67 JSThread *thread = argv->GetThread();
68 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
69
70 int result = 0;
71 for (uint32_t index = 0; index < argv->GetArgsNumber(); ++index) {
72 result += BuiltinsBase::GetCallArg(argv, index)->GetInt();
73 }
74 JSHandle<JSTaggedValue> thisValue(BuiltinsBase::GetThis(argv));
75
76 JSTaggedValue testA =
77 JSObject::GetProperty(thread, thisValue,
78 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_a")))
79 .GetValue()
80 .GetTaggedValue();
81 JSTaggedValue testB =
82 JSObject::GetProperty(thread, thisValue,
83 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_b")))
84 .GetValue()
85 .GetTaggedValue();
86
87 result = result + testA.GetInt() + testB.GetInt();
88 return BuiltinsBase::GetTaggedInt(result);
89 }
90
91 // func.apply(thisArg)
HWTEST_F_L0(BuiltinsFunctionTest,FunctionPrototypeApply)92 HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeApply)
93 {
94 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
95
96 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
97 // ecma 19.2.3.1: func
98 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestFunctionApplyAndCall));
99
100 // ecma 19.2.3.1: thisArg
101 JSHandle<JSObject> thisArg(thread, env->GetGlobalObject());
102 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArg),
103 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_a")),
104 JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)));
105 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArg),
106 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_b")),
107 JSHandle<JSTaggedValue>(thread, JSTaggedValue(2)));
108
109 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
110 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
111 ecmaRuntimeCallInfo->SetThis(func.GetTaggedValue());
112 ecmaRuntimeCallInfo->SetCallArg(0, (thisArg.GetTaggedValue()));
113
114 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
115 JSTaggedValue result = BuiltinsFunction::FunctionPrototypeApply(ecmaRuntimeCallInfo);
116
117 ASSERT_EQ(result.GetRawData(), JSTaggedValue(3).GetRawData());
118
119 JSObject::DeleteProperty(thread, (thisArg),
120 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_a")));
121 JSObject::DeleteProperty(thread, (thisArg),
122 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_b")));
123 }
124
125 // func.apply(thisArg, argArray)
HWTEST_F_L0(BuiltinsFunctionTest,FunctionPrototypeApply1)126 HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeApply1)
127 {
128 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
129
130 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
131
132 // ecma 19.2.3.1: func
133 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestFunctionApplyAndCall));
134
135 // ecma 19.2.3.1: thisArg
136 JSHandle<JSObject> thisArg(thread, env->GetGlobalObject());
137 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArg),
138 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_a")),
139 JSHandle<JSTaggedValue>(thread, JSTaggedValue(10)));
140 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArg),
141 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_b")),
142 JSHandle<JSTaggedValue>(thread, JSTaggedValue(20)));
143
144 // ecma 19.2.3.1: argArray
145 JSHandle<JSObject> array(JSArray::ArrayCreate(thread, JSTaggedNumber(2)));
146 PropertyDescriptor desc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(30)));
147 JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(0)), desc);
148
149 PropertyDescriptor desc1(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(40)));
150 JSArray::DefineOwnProperty(thread, array, JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)), desc1);
151
152 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 8);
153 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
154 ecmaRuntimeCallInfo->SetThis(func.GetTaggedValue());
155 ecmaRuntimeCallInfo->SetCallArg(0, (thisArg.GetTaggedValue()));
156 ecmaRuntimeCallInfo->SetCallArg(1, array.GetTaggedValue());
157
158 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
159 JSTaggedValue result = BuiltinsFunction::FunctionPrototypeApply(ecmaRuntimeCallInfo);
160
161 ASSERT_EQ(result.GetRawData(), JSTaggedValue(100).GetRawData());
162
163 JSObject::DeleteProperty(thread, (thisArg),
164 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_a")));
165 JSObject::DeleteProperty(thread, (thisArg),
166 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_b")));
167 }
168
169 // target.bind(thisArg)
HWTEST_F_L0(BuiltinsFunctionTest,FunctionPrototypeBind)170 HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind)
171 {
172 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
173
174 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
175
176 JSHandle<JSFunction> target = factory->NewJSFunction(env);
177 JSFunction::SetFunctionName(thread, JSHandle<JSFunctionBase>(target),
178 JSHandle<JSTaggedValue>(factory->NewFromASCII("target")),
179 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
180 JSFunction::SetFunctionLength(thread, target, JSTaggedValue(2));
181
182 JSHandle<JSObject> thisArg(thread, env->GetGlobalObject());
183
184 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
185 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
186 ecmaRuntimeCallInfo->SetThis(target.GetTaggedValue());
187 ecmaRuntimeCallInfo->SetCallArg(0, (thisArg.GetTaggedValue()));
188
189 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
190 JSTaggedValue result = BuiltinsFunction::FunctionPrototypeBind(ecmaRuntimeCallInfo);
191
192 ASSERT_TRUE(result.IsECMAObject());
193
194 JSHandle<JSBoundFunction> resultFunc(thread, reinterpret_cast<TaggedObject *>(result.GetRawData()));
195 // test BoundTarget
196 ASSERT_EQ(resultFunc->GetBoundTarget(), target.GetTaggedValue());
197 // test BoundThis
198 ASSERT_EQ(resultFunc->GetBoundThis(), thisArg.GetTaggedValue());
199 // test BoundArguments
200 JSHandle<TaggedArray> array(thread, resultFunc->GetBoundArguments());
201 ASSERT_EQ(array->GetLength(), 0U);
202 // test name property
203 auto globalConst = thread->GlobalConstants();
204 JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
205 JSHandle<JSTaggedValue> resultFuncHandle(thread, *resultFunc);
206 JSHandle<EcmaString> resultName(JSObject::GetProperty(thread, resultFuncHandle, nameKey).GetValue());
207 JSHandle<EcmaString> boundTarget = factory->NewFromASCII("bound target");
208 ASSERT_EQ(EcmaStringAccessor::Compare(*resultName, *boundTarget), 0);
209 // test length property
210 JSHandle<JSTaggedValue> lengthKey = globalConst->GetHandledLengthString();
211 JSHandle<JSTaggedValue> resultLength(JSObject::GetProperty(thread, resultFuncHandle, lengthKey).GetValue());
212 ASSERT_EQ(JSTaggedValue::ToNumber(thread, resultLength).GetNumber(), 2.0);
213 }
214
215 // target.bind(thisArg, 123, "helloworld")
HWTEST_F_L0(BuiltinsFunctionTest,FunctionPrototypeBind1)216 HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind1)
217 {
218 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
219
220 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
221
222 JSHandle<JSFunction> target = factory->NewJSFunction(env);
223 JSFunction::SetFunctionName(thread, JSHandle<JSFunctionBase>(target),
224 JSHandle<JSTaggedValue>(factory->NewFromASCII("target1")),
225 JSHandle<JSTaggedValue>(thread, JSTaggedValue::Undefined()));
226 JSFunction::SetFunctionLength(thread, target, JSTaggedValue(5));
227
228 JSHandle<JSObject> thisArg(thread, env->GetGlobalObject());
229 JSHandle<EcmaString> str = factory->NewFromASCII("helloworld");
230
231 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
232 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
233 ecmaRuntimeCallInfo->SetThis(target.GetTaggedValue());
234 ecmaRuntimeCallInfo->SetCallArg(0, thisArg.GetTaggedValue());
235 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(123)));
236 ecmaRuntimeCallInfo->SetCallArg(2, str.GetTaggedValue());
237
238 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
239 JSTaggedValue result = BuiltinsFunction::FunctionPrototypeBind(ecmaRuntimeCallInfo);
240
241 ASSERT_TRUE(result.IsECMAObject());
242
243 JSHandle<JSBoundFunction> resultFunc(thread, reinterpret_cast<TaggedObject *>(result.GetRawData()));
244 // test BoundTarget
245 ASSERT_EQ(resultFunc->GetBoundTarget(), target.GetTaggedValue());
246 // test BoundThis
247 ASSERT_EQ(resultFunc->GetBoundThis(), thisArg.GetTaggedValue());
248 // test BoundArguments
249 JSHandle<TaggedArray> array(thread, resultFunc->GetBoundArguments());
250 ASSERT_EQ(array->GetLength(), 2U);
251 JSTaggedValue elem = array->Get(0);
252 JSTaggedValue elem1 = array->Get(1);
253 ASSERT_EQ(elem.GetRawData(), JSTaggedValue(123).GetRawData());
254
255 ASSERT_EQ(elem1.GetRawData(), str.GetTaggedType());
256 ASSERT_TRUE(elem1.IsString());
257 // test name property
258 auto globalConst = thread->GlobalConstants();
259 JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
260 JSHandle<JSTaggedValue> resultFuncHandle(thread, *resultFunc);
261 JSHandle<EcmaString> resultName(JSObject::GetProperty(thread, resultFuncHandle, nameKey).GetValue());
262 JSHandle<EcmaString> rulerName = factory->NewFromASCII("bound target1");
263 ASSERT_EQ(EcmaStringAccessor::Compare(*resultName, *rulerName), 0);
264 // test length property
265 JSHandle<JSTaggedValue> lengthKey = globalConst->GetHandledLengthString();
266 JSHandle<JSTaggedValue> resultLength(JSObject::GetProperty(thread, resultFuncHandle, lengthKey).GetValue());
267 // target.length is 5, (...args) length is 2
268 ASSERT_EQ(JSTaggedValue::ToNumber(thread, resultLength).GetNumber(), 3.0);
269 }
270
271 // target.bind(thisArg, 123, "helloworld") set target_name = EmptyString()
HWTEST_F_L0(BuiltinsFunctionTest,FunctionPrototypeBind2)272 HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeBind2)
273 {
274 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
275
276 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
277
278 JSHandle<JSFunction> target = factory->NewJSFunction(env);
279 PropertyDescriptor nameDesc(thread, JSHandle<JSTaggedValue>(thread, JSTaggedValue(123)), false, false, true);
280 JSTaggedValue::DefinePropertyOrThrow(thread, JSHandle<JSTaggedValue>(target),
281 thread->GlobalConstants()->GetHandledNameString(), nameDesc);
282 JSFunction::SetFunctionLength(thread, target, JSTaggedValue(5));
283
284 JSHandle<JSObject> thisArg(thread, env->GetGlobalObject());
285 JSHandle<EcmaString> str = factory->NewFromASCII("helloworld");
286
287 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 10);
288 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
289 ecmaRuntimeCallInfo->SetThis(target.GetTaggedValue());
290 ecmaRuntimeCallInfo->SetCallArg(0, (thisArg.GetTaggedValue()));
291 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(123)));
292 ecmaRuntimeCallInfo->SetCallArg(2, str.GetTaggedValue());
293
294 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
295 JSTaggedValue result = BuiltinsFunction::FunctionPrototypeBind(ecmaRuntimeCallInfo);
296
297 ASSERT_TRUE(result.IsECMAObject());
298
299 JSHandle<JSBoundFunction> resultFunc(thread, reinterpret_cast<TaggedObject *>(result.GetRawData()));
300 // test BoundTarget
301 ASSERT_EQ(resultFunc->GetBoundTarget(), target.GetTaggedValue());
302 // test BoundThis
303 ASSERT_EQ(resultFunc->GetBoundThis(), thisArg.GetTaggedValue());
304 // test BoundArguments
305 JSHandle<TaggedArray> array(thread, resultFunc->GetBoundArguments());
306 ASSERT_EQ(array->GetLength(), 2U);
307 JSTaggedValue elem = array->Get(0);
308 JSTaggedValue elem1 = array->Get(1);
309 ASSERT_EQ(elem.GetRawData(), JSTaggedValue(123).GetRawData());
310
311 ASSERT_EQ(elem1.GetRawData(), str.GetTaggedType());
312 ASSERT_TRUE(elem1.IsString());
313 // test name property
314 auto globalConst = thread->GlobalConstants();
315 JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
316 JSHandle<JSTaggedValue> resultFuncHandle(resultFunc);
317 JSHandle<EcmaString> resultName(JSObject::GetProperty(thread, resultFuncHandle, nameKey).GetValue());
318 JSHandle<EcmaString> rulerName = factory->NewFromASCII("bound ");
319 ASSERT_EQ(EcmaStringAccessor::Compare(*resultName, *rulerName), 0);
320 // test length property
321 JSHandle<JSTaggedValue> lengthKey = globalConst->GetHandledLengthString();
322 JSHandle<JSTaggedValue> resultLength(JSObject::GetProperty(thread, resultFuncHandle, lengthKey).GetValue());
323 // target.length is 5, (...args) length is 2
324 ASSERT_EQ(JSTaggedValue::ToNumber(thread, resultLength).GetNumber(), 3.0);
325 }
326
327 // func.call(thisArg)
HWTEST_F_L0(BuiltinsFunctionTest,FunctionPrototypeCall)328 HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeCall)
329 {
330 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
331
332 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
333
334 // ecma 19.2.3.3: func
335 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestFunctionApplyAndCall));
336
337 // ecma 19.2.3.3: thisArg
338 JSHandle<JSObject> thisArg(thread, env->GetGlobalObject());
339 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArg),
340 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_a")),
341 JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)));
342 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArg),
343 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_b")),
344 JSHandle<JSTaggedValue>(thread, JSTaggedValue(2)));
345
346 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
347 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
348 ecmaRuntimeCallInfo->SetThis(func.GetTaggedValue());
349 ecmaRuntimeCallInfo->SetCallArg(0, (thisArg.GetTaggedValue()));
350
351 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
352 JSTaggedValue result = BuiltinsFunction::FunctionPrototypeCall(ecmaRuntimeCallInfo);
353
354 ASSERT_EQ(result.GetRawData(), JSTaggedValue(3).GetRawData());
355
356 JSObject::DeleteProperty(thread, (thisArg),
357 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_a")));
358 JSObject::DeleteProperty(thread, (thisArg),
359 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_b")));
360 }
361
362 // func.call(thisArg, 123, 456, 789)
HWTEST_F_L0(BuiltinsFunctionTest,FunctionPrototypeCall1)363 HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeCall1)
364 {
365 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
366
367 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
368
369 // ecma 19.2.3.3: func
370 JSHandle<JSFunction> func = factory->NewJSFunction(env, reinterpret_cast<void *>(TestFunctionApplyAndCall));
371
372 // ecma 19.2.3.3: thisArg
373 JSHandle<JSObject> thisArg(thread, env->GetGlobalObject());
374 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArg),
375 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_a")),
376 JSHandle<JSTaggedValue>(thread, JSTaggedValue(1)));
377 JSObject::SetProperty(thread, JSHandle<JSTaggedValue>(thisArg),
378 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_b")),
379 JSHandle<JSTaggedValue>(thread, JSTaggedValue(2)));
380
381 // func thisArg ...args
382 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 12);
383 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
384 ecmaRuntimeCallInfo->SetThis(func.GetTaggedValue());
385 ecmaRuntimeCallInfo->SetCallArg(0, (thisArg.GetTaggedValue()));
386 ecmaRuntimeCallInfo->SetCallArg(1, JSTaggedValue(static_cast<int32_t>(123)));
387 ecmaRuntimeCallInfo->SetCallArg(2, JSTaggedValue(static_cast<int32_t>(456)));
388 ecmaRuntimeCallInfo->SetCallArg(3, JSTaggedValue(static_cast<int32_t>(789)));
389
390 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
391 JSTaggedValue result = BuiltinsFunction::FunctionPrototypeCall(ecmaRuntimeCallInfo);
392
393 ASSERT_EQ(result.GetRawData(), JSTaggedValue(1371).GetRawData());
394
395 JSObject::DeleteProperty(thread, (thisArg),
396 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_a")));
397 JSObject::DeleteProperty(thread, (thisArg),
398 JSHandle<JSTaggedValue>(factory->NewFromASCII("test_builtins_function_b")));
399 }
400
HWTEST_F_L0(BuiltinsFunctionTest,FunctionPrototypeHasInstance)401 HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeHasInstance)
402 {
403 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
404
405 JSHandle<JSFunction> booleanCtor(env->GetBooleanFunction());
406
407 auto ecmaRuntimeCallInfo1 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*booleanCtor), 6);
408 ecmaRuntimeCallInfo1->SetFunction(booleanCtor.GetTaggedValue());
409 ecmaRuntimeCallInfo1->SetThis(JSTaggedValue::Undefined());
410 ecmaRuntimeCallInfo1->SetCallArg(0, JSTaggedValue(static_cast<int32_t>(123)));
411
412 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo1);
413 JSTaggedValue result = BuiltinsBoolean::BooleanConstructor(ecmaRuntimeCallInfo1);
414 TestHelper::TearDownFrame(thread, prev);
415
416 JSHandle<JSObject> booleanInstance(thread, result);
417
418 auto ecmaRuntimeCallInfo2 = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);
419 ecmaRuntimeCallInfo2->SetFunction(JSTaggedValue::Undefined());
420 ecmaRuntimeCallInfo2->SetThis(booleanCtor.GetTaggedValue());
421 ecmaRuntimeCallInfo2->SetCallArg(0, booleanInstance.GetTaggedValue());
422
423 prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo2);
424 EXPECT_TRUE(BuiltinsFunction::FunctionPrototypeHasInstance(ecmaRuntimeCallInfo2).GetRawData());
425 TestHelper::TearDownFrame(thread, prev);
426 }
427
428 /**
429 * @tc.name: FunctionPrototypeToString
430 * @tc.desc: Create msgs through "CreateEcmaRuntimeCallInfo" function, Set ArgsNumber and CallArg, then call
431 * the "FunctionPrototypeToString" function to get the result of Function.prototype.call.toString().
432 * @tc.type: FUNC
433 * @tc.require: issueI5INW1
434 */
HWTEST_F_L0(BuiltinsFunctionTest,FunctionPrototypeToString)435 HWTEST_F_L0(BuiltinsFunctionTest, FunctionPrototypeToString)
436 {
437 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
438 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
439 CString key = "call";
440 JSHandle<JSTaggedValue> keyString(factory->NewFromUtf8(key));
441
442 JSHandle<JSFunction> func = factory->NewJSFunction(
443 env, reinterpret_cast<void *>(BuiltinsFunction::FunctionPrototypeCall));
444 JSHandle<JSFunctionBase> baseFunction(func);
445 JSHandle<JSTaggedValue> handleUndefine(thread, JSTaggedValue::Undefined());
446 JSFunction::SetFunctionName(thread, baseFunction, keyString, handleUndefine);
447
448 auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 4);
449 ecmaRuntimeCallInfo->SetFunction(JSTaggedValue::Undefined());
450 ecmaRuntimeCallInfo->SetThis(func.GetTaggedValue());
451
452 [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
453 JSTaggedValue result = BuiltinsFunction::FunctionPrototypeToString(ecmaRuntimeCallInfo);
454 ASSERT_TRUE(result.IsString());
455 JSHandle<EcmaString> resultHandle(thread, reinterpret_cast<EcmaString *>(result.GetRawData()));
456 JSTaggedValue test = factory->NewFromASCII("function call() { [native code] }").GetTaggedValue();
457 ASSERT_EQ(EcmaStringAccessor::Compare(*resultHandle, reinterpret_cast<EcmaString *>(test.GetRawData())), 0);
458 }
459 } // namespace panda::test
460