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