• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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