14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci#include "ecmascript/compiler/gate_accessor.h"
164514f5e3Sopenharmony_ci#include "ecmascript/compiler/share_opcodes.h"
174514f5e3Sopenharmony_ci#include "ecmascript/compiler/verifier.h"
184514f5e3Sopenharmony_ci#include "ecmascript/compiler/typed_bytecode_lowering.h"
194514f5e3Sopenharmony_ci#include "ecmascript/compiler/typed_hcr_lowering.h"
204514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h"
214514f5e3Sopenharmony_ci#include "ecmascript/elements.h"
224514f5e3Sopenharmony_ci#include "ecmascript/mem/concurrent_marker.h"
234514f5e3Sopenharmony_ci#include "ecmascript/mem/native_area_allocator.h"
244514f5e3Sopenharmony_ci#include "ecmascript/tests/test_helper.h"
254514f5e3Sopenharmony_ci#include "gtest/gtest.h"
264514f5e3Sopenharmony_ci#include <cstddef>
274514f5e3Sopenharmony_ci
284514f5e3Sopenharmony_cinamespace panda::test {
294514f5e3Sopenharmony_ciclass MetaDataEqualTests : public testing::Test {};
304514f5e3Sopenharmony_ci
314514f5e3Sopenharmony_ciusing ecmascript::kungfu::Circuit;
324514f5e3Sopenharmony_ciusing ecmascript::kungfu::CircuitBuilder;
334514f5e3Sopenharmony_ciusing ecmascript::kungfu::EcmaOpcode;
344514f5e3Sopenharmony_ciusing ecmascript::kungfu::ElementsKind;
354514f5e3Sopenharmony_ciusing ecmascript::kungfu::Environment;
364514f5e3Sopenharmony_ciusing ecmascript::kungfu::GateAccessor;
374514f5e3Sopenharmony_ciusing ecmascript::kungfu::GateMetaData;
384514f5e3Sopenharmony_ciusing ecmascript::kungfu::GateType;
394514f5e3Sopenharmony_ciusing ecmascript::kungfu::JSBytecodeMetaData;
404514f5e3Sopenharmony_ciusing ecmascript::kungfu::MachineType;
414514f5e3Sopenharmony_ciusing ecmascript::kungfu::PGOTypeRef;
424514f5e3Sopenharmony_ciusing ecmascript::kungfu::PGOSampleType;
434514f5e3Sopenharmony_ciusing ecmascript::kungfu::TypedBinOp;
444514f5e3Sopenharmony_ciusing ecmascript::kungfu::TypedCallTargetCheckOp;
454514f5e3Sopenharmony_ciusing ecmascript::kungfu::ParamType;
464514f5e3Sopenharmony_ciusing ecmascript::kungfu::TypedCallTargetCheckAccessor;
474514f5e3Sopenharmony_ci
484514f5e3Sopenharmony_ciHWTEST_F_L0(MetaDataEqualTests, StringMetaDataEqualTest)
494514f5e3Sopenharmony_ci{
504514f5e3Sopenharmony_ci    // construct a circuit
514514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
524514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
534514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
544514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
554514f5e3Sopenharmony_ci    CircuitBuilder builder(&circuit);
564514f5e3Sopenharmony_ci    Environment env(0, &builder);
574514f5e3Sopenharmony_ci    builder.SetEnvironment(&env);
584514f5e3Sopenharmony_ci
594514f5e3Sopenharmony_ci    auto stringGate1 = circuit.GetConstantStringGate(MachineType::ARCH, "test1", GateType::NJSValue());
604514f5e3Sopenharmony_ci
614514f5e3Sopenharmony_ci
624514f5e3Sopenharmony_ci    auto stringGate2 = circuit.GetConstantStringGate(MachineType::ARCH, "test2", GateType::NJSValue());
634514f5e3Sopenharmony_ci
644514f5e3Sopenharmony_ci    EXPECT_FALSE(acc.MetaDataValueEqu(stringGate1, stringGate2));
654514f5e3Sopenharmony_ci
664514f5e3Sopenharmony_ci    auto stringGate3 = circuit.GetConstantStringGate(MachineType::ARCH, "test1", GateType::NJSValue());
674514f5e3Sopenharmony_ci
684514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(stringGate1, stringGate3));
694514f5e3Sopenharmony_ci}
704514f5e3Sopenharmony_ci
714514f5e3Sopenharmony_ciHWTEST_F_L0(MetaDataEqualTests, ConstantMetaDataEqualTest)
724514f5e3Sopenharmony_ci{
734514f5e3Sopenharmony_ci    // construct a circuit
744514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
754514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
764514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
774514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
784514f5e3Sopenharmony_ci    CircuitBuilder builder(&circuit);
794514f5e3Sopenharmony_ci    Environment env(0, &builder);
804514f5e3Sopenharmony_ci    builder.SetEnvironment(&env);
814514f5e3Sopenharmony_ci
824514f5e3Sopenharmony_ci
834514f5e3Sopenharmony_ci    auto constantValue1 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue());
844514f5e3Sopenharmony_ci
854514f5e3Sopenharmony_ci    auto constantValue2 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue());
864514f5e3Sopenharmony_ci
874514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(constantValue1, constantValue2));
884514f5e3Sopenharmony_ci
894514f5e3Sopenharmony_ci    auto constantValue3 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue());
904514f5e3Sopenharmony_ci
914514f5e3Sopenharmony_ci    auto constantValue4 = circuit.GetConstantGate(MachineType::I64, 3, GateType::NJSValue());
924514f5e3Sopenharmony_ci
934514f5e3Sopenharmony_ci    EXPECT_FALSE(acc.MetaDataValueEqu(constantValue3, constantValue4));
944514f5e3Sopenharmony_ci
954514f5e3Sopenharmony_ci
964514f5e3Sopenharmony_ci    // MetaData is equal, but Gate is not equal
974514f5e3Sopenharmony_ci    auto constantValue5 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue());
984514f5e3Sopenharmony_ci
994514f5e3Sopenharmony_ci    auto constantValue6 = circuit.GetConstantGate(MachineType::I32, 2, GateType::NJSValue());
1004514f5e3Sopenharmony_ci
1014514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(constantValue5, constantValue6));
1024514f5e3Sopenharmony_ci
1034514f5e3Sopenharmony_ci    // MetaData is equal, but Gate is not equal
1044514f5e3Sopenharmony_ci    auto ConstGateNJSValue2 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue());
1054514f5e3Sopenharmony_ci
1064514f5e3Sopenharmony_ci    auto ConstGateUndefined =
1074514f5e3Sopenharmony_ci        circuit.GetConstantGate(MachineType::I64, JSTaggedValue::VALUE_UNDEFINED, GateType::UndefinedType());
1084514f5e3Sopenharmony_ci
1094514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(ConstGateNJSValue2, ConstGateUndefined));
1104514f5e3Sopenharmony_ci}
1114514f5e3Sopenharmony_ci
1124514f5e3Sopenharmony_ciHWTEST_F_L0(MetaDataEqualTests, TypeErrorMetaDataEqualTest)
1134514f5e3Sopenharmony_ci{
1144514f5e3Sopenharmony_ci    // construct a circuit
1154514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
1164514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
1174514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
1184514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
1194514f5e3Sopenharmony_ci    CircuitBuilder builder(&circuit);
1204514f5e3Sopenharmony_ci    Environment env(0, &builder);
1214514f5e3Sopenharmony_ci    builder.SetEnvironment(&env);
1224514f5e3Sopenharmony_ci
1234514f5e3Sopenharmony_ci    auto constantValue1 = circuit.GetConstantGate(MachineType::I64, 2, GateType::NJSValue());
1244514f5e3Sopenharmony_ci    auto stringGate1 = circuit.GetConstantStringGate(MachineType::ARCH, "test1", GateType::NJSValue());
1254514f5e3Sopenharmony_ci    EXPECT_FALSE(acc.MetaDataValueEqu(constantValue1, stringGate1));
1264514f5e3Sopenharmony_ci    EXPECT_FALSE(acc.MetaDataValueEqu(stringGate1, constantValue1));
1274514f5e3Sopenharmony_ci}
1284514f5e3Sopenharmony_ci
1294514f5e3Sopenharmony_ciHWTEST_F_L0(MetaDataEqualTests, HCRMetaDataEqualTest)
1304514f5e3Sopenharmony_ci{
1314514f5e3Sopenharmony_ci    // construct a circuit
1324514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
1334514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
1344514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
1354514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
1364514f5e3Sopenharmony_ci    CircuitBuilder builder(&circuit);
1374514f5e3Sopenharmony_ci    Environment env(0, &builder);
1384514f5e3Sopenharmony_ci    builder.SetEnvironment(&env);
1394514f5e3Sopenharmony_ci
1404514f5e3Sopenharmony_ci    // JSBytecodeMetaData
1414514f5e3Sopenharmony_ci    auto meta = circuit.JSBytecode(0, 0, EcmaOpcode::JEQZ_IMM8, 0, 0, true, false);
1424514f5e3Sopenharmony_ci    auto gate =
1434514f5e3Sopenharmony_ci        circuit.NewGate(meta, MachineType::I64, {Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType());
1444514f5e3Sopenharmony_ci    auto meta2 = circuit.JSBytecode(0, 0, EcmaOpcode::JEQZ_IMM8, 0, 0, true, false);
1454514f5e3Sopenharmony_ci    auto gate2 =
1464514f5e3Sopenharmony_ci        circuit.NewGate(meta2, MachineType::I64, {Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType());
1474514f5e3Sopenharmony_ci
1484514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(gate, gate2));
1494514f5e3Sopenharmony_ci
1504514f5e3Sopenharmony_ci    static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta))->SetElementsKind(ElementsKind::NUMBER);
1514514f5e3Sopenharmony_ci    static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta2))->SetElementsKind(ElementsKind::NUMBER);
1524514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(gate, gate2));
1534514f5e3Sopenharmony_ci
1544514f5e3Sopenharmony_ci    PGOSampleType type = PGOSampleType::CreateProfileType(0, 0);
1554514f5e3Sopenharmony_ci    PGOSampleType type2 = PGOSampleType::CreateProfileType(0, 0);
1564514f5e3Sopenharmony_ci    static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta))
1574514f5e3Sopenharmony_ci        ->SetType(PGOTypeRef(static_cast<const PGOSampleType *>(&type)));
1584514f5e3Sopenharmony_ci    static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta2))
1594514f5e3Sopenharmony_ci        ->SetType(PGOTypeRef(static_cast<const PGOSampleType *>(&type2)));
1604514f5e3Sopenharmony_ci    EXPECT_FALSE(acc.MetaDataValueEqu(gate, gate2));
1614514f5e3Sopenharmony_ci
1624514f5e3Sopenharmony_ci    PGOSampleType type3 = PGOSampleType::CreateProfileType(0, 1);
1634514f5e3Sopenharmony_ci    static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta))
1644514f5e3Sopenharmony_ci        ->SetType(PGOTypeRef(static_cast<const PGOSampleType *>(&type)));
1654514f5e3Sopenharmony_ci    static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta2))
1664514f5e3Sopenharmony_ci        ->SetType(PGOTypeRef(static_cast<const PGOSampleType *>(&type3)));
1674514f5e3Sopenharmony_ci    EXPECT_FALSE(acc.MetaDataValueEqu(gate, gate2));
1684514f5e3Sopenharmony_ci
1694514f5e3Sopenharmony_ci    static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta))->SetElementsKind(ElementsKind::NUMBER);
1704514f5e3Sopenharmony_ci    static_cast<JSBytecodeMetaData *>(const_cast<GateMetaData *>(meta2))->SetElementsKind(ElementsKind::HOLE_NUMBER);
1714514f5e3Sopenharmony_ci    EXPECT_FALSE(acc.MetaDataValueEqu(gate, gate2));
1724514f5e3Sopenharmony_ci}
1734514f5e3Sopenharmony_ci
1744514f5e3Sopenharmony_ciHWTEST_F_L0(MetaDataEqualTests, MCRMetaDataEqualTest)
1754514f5e3Sopenharmony_ci{
1764514f5e3Sopenharmony_ci    // construct a circuit
1774514f5e3Sopenharmony_ci    ecmascript::NativeAreaAllocator allocator;
1784514f5e3Sopenharmony_ci    Circuit circuit(&allocator);
1794514f5e3Sopenharmony_ci    ecmascript::Chunk chunk(&allocator);
1804514f5e3Sopenharmony_ci    GateAccessor acc(&circuit);
1814514f5e3Sopenharmony_ci    CircuitBuilder builder(&circuit);
1824514f5e3Sopenharmony_ci    Environment env(0, &builder);
1834514f5e3Sopenharmony_ci    builder.SetEnvironment(&env);
1844514f5e3Sopenharmony_ci
1854514f5e3Sopenharmony_ci    // TypedCallMetaData
1864514f5e3Sopenharmony_ci    auto callGate =
1874514f5e3Sopenharmony_ci        circuit.NewGate(circuit.TypedCall(0, 0, true), MachineType::I64,
1884514f5e3Sopenharmony_ci                        {Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType());
1894514f5e3Sopenharmony_ci
1904514f5e3Sopenharmony_ci    auto callGate2 =
1914514f5e3Sopenharmony_ci        circuit.NewGate(circuit.TypedCall(0, 0, true), MachineType::I64,
1924514f5e3Sopenharmony_ci                        {Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate()}, GateType::AnyType());
1934514f5e3Sopenharmony_ci
1944514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(callGate, callGate2));
1954514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(callGate2, callGate));
1964514f5e3Sopenharmony_ci
1974514f5e3Sopenharmony_ci    // TypedCallTargetCheckMetaData
1984514f5e3Sopenharmony_ci    auto callGate3 =
1994514f5e3Sopenharmony_ci        circuit.NewGate(circuit.TypedCallTargetCheckOp(
2004514f5e3Sopenharmony_ci            TypedCallTargetCheckAccessor::ToValue(TypedCallTargetCheckOp::JSCALLTHIS_FAST)), MachineType::I64,
2014514f5e3Sopenharmony_ci            {Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate()},
2024514f5e3Sopenharmony_ci            GateType::AnyType());
2034514f5e3Sopenharmony_ci    auto callGate4 =
2044514f5e3Sopenharmony_ci        circuit.NewGate(circuit.TypedCallTargetCheckOp(
2054514f5e3Sopenharmony_ci            TypedCallTargetCheckAccessor::ToValue(TypedCallTargetCheckOp::JSCALLTHIS_FAST)), MachineType::I64,
2064514f5e3Sopenharmony_ci            {Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate()},
2074514f5e3Sopenharmony_ci            GateType::AnyType());
2084514f5e3Sopenharmony_ci
2094514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(callGate3, callGate4));
2104514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(callGate4, callGate3));
2114514f5e3Sopenharmony_ci
2124514f5e3Sopenharmony_ci    // TypedBinaryMetaData
2134514f5e3Sopenharmony_ci    uint64_t valueForType5 = ecmascript::kungfu::TypedBinaryAccessor::ToValue(ParamType::IntType(),
2144514f5e3Sopenharmony_ci                                                                              TypedBinOp::TYPED_ADD);
2154514f5e3Sopenharmony_ci    auto callGate5 = circuit.NewGate(
2164514f5e3Sopenharmony_ci        circuit.TypedBinaryOp(valueForType5),
2174514f5e3Sopenharmony_ci        MachineType::I64, { Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate() },
2184514f5e3Sopenharmony_ci        GateType::AnyType());
2194514f5e3Sopenharmony_ci
2204514f5e3Sopenharmony_ci    // TypedBinaryMetaData
2214514f5e3Sopenharmony_ci    uint64_t valueForType6 = ecmascript::kungfu::TypedBinaryAccessor::ToValue(ParamType::IntType(),
2224514f5e3Sopenharmony_ci                                                                              TypedBinOp::TYPED_ADD);
2234514f5e3Sopenharmony_ci    auto callGate6 = circuit.NewGate(
2244514f5e3Sopenharmony_ci        circuit.TypedBinaryOp(valueForType6),
2254514f5e3Sopenharmony_ci        MachineType::I64, { Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate(), Circuit::NullGate() },
2264514f5e3Sopenharmony_ci        GateType::AnyType());
2274514f5e3Sopenharmony_ci
2284514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(callGate5, callGate6));
2294514f5e3Sopenharmony_ci    EXPECT_TRUE(acc.MetaDataValueEqu(callGate6, callGate5));
2304514f5e3Sopenharmony_ci}
2314514f5e3Sopenharmony_ci
2324514f5e3Sopenharmony_ci
2334514f5e3Sopenharmony_ci} // namespace panda::test
234