1 /*
2  * Copyright (c) 2024 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 #ifndef TEST_COMMON_H
16 #define TEST_COMMON_H
17 #include "ecmascript/builtins/builtins_regexp.h"
18 #include "ecmascript/containers/containers_private.h"
19 #include "ecmascript/global_env.h"
20 #include "ecmascript/object_factory.h"
21 #include "ecmascript/tests/test_helper.h"
22 namespace panda::test {
23 using namespace panda;
24 using namespace panda::ecmascript;
25 using namespace panda::ecmascript::containers;
26 using ecmascript::base::BuiltinsBase;
27 using BuiltinsRegExp = builtins::BuiltinsRegExp;
28 
29 class TestCommon {
30 public:
CreateContainerTaggedValue(JSThread *thread, ContainerTag tag)31     static JSTaggedValue CreateContainerTaggedValue(JSThread *thread, ContainerTag tag)
32     {
33         ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
34         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
35 
36         JSHandle<JSTaggedValue> globalObject = env->GetJSGlobalObject();
37         JSHandle<JSTaggedValue> key(factory->NewFromASCII("ArkPrivate"));
38         JSHandle<JSTaggedValue> value =
39             JSObject::GetProperty(thread, JSHandle<JSTaggedValue>(globalObject), key).GetValue();
40 
41         auto objCallInfo =
42             TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue::Undefined(), 6);  // 6 means the value
43         objCallInfo->SetFunction(JSTaggedValue::Undefined());
44         objCallInfo->SetThis(value.GetTaggedValue());
45         objCallInfo->SetCallArg(0, JSTaggedValue(static_cast<int>(tag)));
46 
47         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, objCallInfo);
48         JSTaggedValue result = ContainersPrivate::Load(objCallInfo);
49         TestHelper::TearDownFrame(thread, prev);
50         return result;
51     }
52 
CreateJSRegexpByPatternAndFlags(JSThread *thread, const JSHandle<EcmaString> &pattern, const JSHandle<EcmaString> &flags)53     static JSTaggedValue CreateJSRegexpByPatternAndFlags(JSThread *thread, const JSHandle<EcmaString> &pattern,
54                                                          const JSHandle<EcmaString> &flags)
55     {
56         JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
57         JSHandle<JSFunction> regexp(env->GetRegExpFunction());
58         JSHandle<JSObject> globalObject(thread, env->GetGlobalObject());
59         // 8 : test case
60         auto ecmaRuntimeCallInfo = TestHelper::CreateEcmaRuntimeCallInfo(thread, JSTaggedValue(*regexp), 8);
61         ecmaRuntimeCallInfo->SetFunction(regexp.GetTaggedValue());
62         ecmaRuntimeCallInfo->SetThis(globalObject.GetTaggedValue());
63         ecmaRuntimeCallInfo->SetCallArg(0, pattern.GetTaggedValue());
64         ecmaRuntimeCallInfo->SetCallArg(1, flags.GetTaggedValue());
65 
66         [[maybe_unused]] auto prev = TestHelper::SetupFrame(thread, ecmaRuntimeCallInfo);
67         // call RegExpConstructor method
68         JSTaggedValue result = BuiltinsRegExp::RegExpConstructor(ecmaRuntimeCallInfo);
69         TestHelper::TearDownFrame(thread, prev);
70         return result;
71     }
72 
TestCompareFunction(EcmaRuntimeCallInfo *argv)73     static JSTaggedValue TestCompareFunction(EcmaRuntimeCallInfo *argv)
74     {
75         JSThread *thread = argv->GetThread();
76         JSHandle<JSTaggedValue> valueX = BuiltinsBase::GetCallArg(argv, 0);
77         JSHandle<JSTaggedValue> valueY = BuiltinsBase::GetCallArg(argv, 1);
78 
79         if (valueX->IsString() && valueY->IsString()) {
80             auto xHandle = JSHandle<EcmaString>(valueX);
81             auto yHandle = JSHandle<EcmaString>(valueY);
82             int result = EcmaStringAccessor::Compare(thread->GetEcmaVM(), xHandle, yHandle);
83             if (result < 0) {
84                 return JSTaggedValue(1);
85             }
86             if (result == 0) {
87                 return JSTaggedValue(0);
88             }
89             return JSTaggedValue(-1);
90         }
91 
92         if (valueX->IsNumber() && valueY->IsString()) {
93             return JSTaggedValue(1);
94         }
95         if (valueX->IsString() && valueY->IsNumber()) {
96             return JSTaggedValue(-1);
97         }
98 
99         ComparisonResult res = ComparisonResult::UNDEFINED;
100         if (valueX->IsNumber() && valueY->IsNumber()) {
101             res = JSTaggedValue::StrictNumberCompare(valueY->GetNumber(), valueX->GetNumber());
102         } else {
103             res = JSTaggedValue::Compare(thread, valueY, valueX);
104         }
105         return res == ComparisonResult::GREAT ? JSTaggedValue(1)
106                                               : (res == ComparisonResult::LESS ? JSTaggedValue(-1) : JSTaggedValue(0));
107     }
108 };
109 };  // namespace panda::test
110 
111 #endif
112