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