/* * Copyright (c) 2021-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "ecmascript/ecma_vm.h" #include "ecmascript/global_env_constants.h" #include "ecmascript/global_env_constants-inl.h" #include "ecmascript/ic/ic_binary_op.h" #include "ecmascript/interpreter/slow_runtime_stub.h" #include "ecmascript/object_factory.h" #include "ecmascript/tests/test_helper.h" using namespace panda::ecmascript; namespace panda::test { class ICBinaryOPTest : public testing::Test { public: static void SetUpTestCase() { GTEST_LOG_(INFO) << "SetUpTestCase"; } static void TearDownTestCase() { GTEST_LOG_(INFO) << "TearDownCase"; } void SetUp() override { TestHelper::CreateEcmaVMWithScope(ecmaVm, thread, scope); } void TearDown() override { TestHelper::DestroyEcmaVMWithScope(ecmaVm, scope); } EcmaHandleScope *scope {nullptr}; JSThread *thread {nullptr}; EcmaVM *ecmaVm = nullptr; }; HWTEST_F_L0(ICBinaryOPTest, AddWithTSType) { ObjectFactory *factory = thread->GetEcmaVM()->GetFactory(); JSHandle Str1 = factory->NewFromASCII("AddTest"); JSHandle Str2 = factory->NewFromASCII("IC"); JSHandle arg4 = factory->NewEmptyJSObject(); JSTaggedValue arg1Value(static_cast(2)); JSTaggedValue arg2Value(static_cast(3)); JSTaggedValue arg3Value(static_cast(9.5561)); JSHandle arg1(thread, arg1Value); JSHandle arg2(thread, arg2Value); JSHandle arg3(thread, arg3Value); JSTaggedValue resInSlowPath1 = SlowRuntimeStub::Add2(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue()); JSHandle slowHandle1(thread, resInSlowPath1); JSTaggedValue resInICPath1 = ICBinaryOP::AddWithTSType(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle1.GetTaggedValue(), resInICPath1); JSTaggedValue resInSlowPath2 = SlowRuntimeStub::Add2(thread, arg1.GetTaggedValue(), arg3.GetTaggedValue()); JSHandle slowHandle2(thread, resInSlowPath2); JSTaggedValue resInICPath2 = ICBinaryOP::AddWithTSType(thread, arg1.GetTaggedValue(), arg3.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle2.GetTaggedValue(), resInICPath2); JSTaggedValue resInSlowPath3 = SlowRuntimeStub::Add2(thread, Str1.GetTaggedValue(), Str2.GetTaggedValue()); JSHandle slowHandle3(thread, reinterpret_cast(resInSlowPath3.GetRawData())); JSTaggedValue resInICPath3 = ICBinaryOP::AddWithTSType(thread, Str1.GetTaggedValue(), Str2.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::STRING))); ASSERT_TRUE(resInICPath3.IsString()); EXPECT_EQ(EcmaStringAccessor::Compare(ecmaVm, slowHandle3, JSHandle(thread, resInICPath3)), 0); JSTaggedValue resInSlowPath4 = SlowRuntimeStub::Add2(thread, JSTaggedValue::Undefined(), arg2.GetTaggedValue()); JSHandle slowHandle4(thread, resInSlowPath4); JSTaggedValue resInICPath4 = ICBinaryOP::AddWithTSType(thread, JSTaggedValue::Undefined(), arg2.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER_GEN))); EXPECT_EQ(slowHandle4.GetTaggedValue(), resInICPath4); JSTaggedValue resInSlowPath5 = SlowRuntimeStub::Add2(thread, arg3.GetTaggedValue(), Str1.GetTaggedValue()); JSHandle slowHandle5(thread, reinterpret_cast(resInSlowPath5.GetRawData())); JSTaggedValue resInICPath5 = ICBinaryOP::AddWithTSType(thread, arg3.GetTaggedValue(), Str1.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::STRING_GEN))); ASSERT_TRUE(resInICPath5.IsString()); EXPECT_EQ(EcmaStringAccessor::Compare(ecmaVm, slowHandle5, JSHandle(thread, resInICPath5)), 0); JSTaggedValue resInSlowPath6 = SlowRuntimeStub::Add2(thread, Str1.GetTaggedValue(), JSTaggedValue::Null()); JSHandle slowHandle6(thread, reinterpret_cast(resInSlowPath6.GetRawData())); JSTaggedValue resInICPath6 = ICBinaryOP::AddWithTSType(thread, Str1.GetTaggedValue(), JSTaggedValue::Null(), JSTaggedValue(static_cast(BinaryType::STRING_GEN))); ASSERT_TRUE(resInICPath6.IsString()); EXPECT_EQ(EcmaStringAccessor::Compare(ecmaVm, slowHandle6, JSHandle(thread, resInICPath6)), 0); JSTaggedValue resInSlowPath7 = SlowRuntimeStub::Add2(thread, arg1.GetTaggedValue(), JSTaggedValue::True()); JSHandle slowHandle7(thread, resInSlowPath7); JSTaggedValue resInICPath7 = ICBinaryOP::AddWithTSType(thread, arg1.GetTaggedValue(), JSTaggedValue::True(), JSTaggedValue(static_cast(BinaryType::NUMBER_GEN))); EXPECT_EQ(slowHandle7.GetTaggedValue(), resInICPath7); JSTaggedValue resInSlowPath8 = SlowRuntimeStub::Add2(thread, arg4.GetTaggedValue(), JSTaggedValue::Null()); JSHandle slowHandle8(thread, reinterpret_cast(resInSlowPath8.GetRawData())); JSTaggedValue resInICPath8 = ICBinaryOP::AddWithTSType(thread, arg4.GetTaggedValue(), JSTaggedValue::Null(), JSTaggedValue(static_cast(BinaryType::GENERIC))); ASSERT_TRUE(resInICPath8.IsString()); EXPECT_EQ(EcmaStringAccessor::Compare(ecmaVm, slowHandle8, JSHandle(thread, resInICPath8)), 0); }; HWTEST_F_L0(ICBinaryOPTest, SubWithTSType) { JSTaggedValue arg1Value(static_cast(-2)); JSTaggedValue arg2Value(static_cast(INT32_MAX-1)); JSTaggedValue arg3Value(static_cast(9.5561)); JSHandle arg1(thread, arg1Value); JSHandle arg2(thread, arg2Value); JSHandle arg3(thread, arg3Value); JSTaggedValue resInSlowPath1 = SlowRuntimeStub::Sub2(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue()); JSHandle slowHandle1(thread, resInSlowPath1); JSTaggedValue resInICPath1 = ICBinaryOP::SubWithTSType(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle1.GetTaggedValue(), resInICPath1); JSTaggedValue resInSlowPath2 = SlowRuntimeStub::Sub2(thread, arg2.GetTaggedValue(), arg3.GetTaggedValue()); JSHandle slowHandle2(thread, resInSlowPath2); JSTaggedValue resInICPath2 = ICBinaryOP::SubWithTSType(thread, arg2.GetTaggedValue(), arg3.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle2.GetTaggedValue(), resInICPath2); JSTaggedValue resInSlowPath3 = SlowRuntimeStub::Sub2(thread, arg1.GetTaggedValue(), JSTaggedValue::True()); JSHandle slowHandle3(thread, resInSlowPath3); JSTaggedValue resInICPath3 = ICBinaryOP::SubWithTSType(thread, arg1.GetTaggedValue(), JSTaggedValue::True(), JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(slowHandle3.GetTaggedValue(), resInICPath3); }; HWTEST_F_L0(ICBinaryOPTest, MulWithTSType) { JSTaggedValue arg1Value(static_cast(28.5)); JSTaggedValue arg2Value(static_cast(354)); JSTaggedValue arg3Value(static_cast(9.5561)); JSHandle arg1(thread, arg1Value); JSHandle arg2(thread, arg2Value); JSHandle arg3(thread, arg3Value); JSTaggedValue resInSlowPath1 = SlowRuntimeStub::Mul2(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue()); JSHandle slowHandle1(thread, resInSlowPath1); JSTaggedValue resInICPath1 = ICBinaryOP::MulWithTSType(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle1.GetTaggedValue(), resInICPath1); JSTaggedValue resInSlowPath2 = SlowRuntimeStub::Mul2(thread, arg2.GetTaggedValue(), arg3.GetTaggedValue()); JSHandle slowHandle2(thread, resInSlowPath2); JSTaggedValue resInICPath2 = ICBinaryOP::MulWithTSType(thread, arg2.GetTaggedValue(), arg3.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle2.GetTaggedValue(), resInICPath2); JSTaggedValue resInSlowPath3 = SlowRuntimeStub::Mul2(thread, arg1.GetTaggedValue(), JSTaggedValue::True()); JSHandle slowHandle3(thread, resInSlowPath3); JSTaggedValue resInICPath3 = ICBinaryOP::MulWithTSType(thread, arg1.GetTaggedValue(), JSTaggedValue::True(), JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(slowHandle3.GetTaggedValue(), resInICPath3); }; HWTEST_F_L0(ICBinaryOPTest, DivWithTSType) { JSTaggedValue arg1Value(static_cast(2)); JSTaggedValue arg2Value(static_cast(39884)); JSTaggedValue arg3Value(static_cast(0)); JSTaggedValue arg4Value(static_cast(934.5561)); JSHandle arg1(thread, arg1Value); JSHandle arg2(thread, arg2Value); JSHandle arg3(thread, arg3Value); JSHandle arg4(thread, arg4Value); JSTaggedValue resInSlowPath1 = SlowRuntimeStub::Div2(thread, arg3.GetTaggedValue(), arg2.GetTaggedValue()); JSHandle slowHandle1(thread, resInSlowPath1); JSTaggedValue resInICPath1 = ICBinaryOP::DivWithTSType(thread, arg3.GetTaggedValue(), arg2.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle1.GetTaggedValue(), resInICPath1); JSTaggedValue resInSlowPath2 = SlowRuntimeStub::Div2(thread, arg2.GetTaggedValue(), arg3.GetTaggedValue()); JSHandle slowHandle2(thread, resInSlowPath2); JSTaggedValue resInICPath2 = ICBinaryOP::DivWithTSType(thread, arg2.GetTaggedValue(), arg3.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle2.GetTaggedValue(), resInICPath2); JSTaggedValue resInSlowPath3 = SlowRuntimeStub::Div2(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue()); JSHandle slowHandle3(thread, resInSlowPath3); JSTaggedValue resInICPath3 = ICBinaryOP::DivWithTSType(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle3.GetTaggedValue(), resInICPath3); JSTaggedValue resInSlowPath4 = SlowRuntimeStub::Div2(thread, arg2.GetTaggedValue(), JSTaggedValue::True()); JSHandle slowHandle4(thread, resInSlowPath4); JSTaggedValue resInICPath4 = ICBinaryOP::DivWithTSType(thread, arg2.GetTaggedValue(), JSTaggedValue::True(), JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(slowHandle4.GetTaggedValue(), resInICPath4); JSTaggedValue resInSlowPath5 = SlowRuntimeStub::Div2(thread, arg4.GetTaggedValue(), JSTaggedValue::False()); JSHandle slowHandle5(thread, resInSlowPath5); JSTaggedValue resInICPath5 = ICBinaryOP::DivWithTSType(thread, arg4.GetTaggedValue(), JSTaggedValue::False(), JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(slowHandle5.GetTaggedValue(), resInICPath5); }; HWTEST_F_L0(ICBinaryOPTest, ModWithTSType) { JSTaggedValue arg1Value(static_cast(2)); JSTaggedValue arg2Value(static_cast(39884)); JSTaggedValue arg3Value(static_cast(0)); JSTaggedValue arg4Value(static_cast(934.5561)); JSHandle arg1(thread, arg1Value); JSHandle arg2(thread, arg2Value); JSHandle arg3(thread, arg3Value); JSHandle arg4(thread, arg4Value); JSTaggedValue resInSlowPath1 = SlowRuntimeStub::Mod2(thread, arg3.GetTaggedValue(), arg2.GetTaggedValue()); JSHandle slowHandle1(thread, resInSlowPath1); JSTaggedValue resInICPath1 = ICBinaryOP::ModWithTSType(thread, arg3.GetTaggedValue(), arg2.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle1.GetTaggedValue(), resInICPath1); JSTaggedValue resInSlowPath2 = SlowRuntimeStub::Mod2(thread, arg2.GetTaggedValue(), arg3.GetTaggedValue()); JSHandle slowHandle2(thread, resInSlowPath2); JSTaggedValue resInICPath2 = ICBinaryOP::ModWithTSType(thread, arg2.GetTaggedValue(), arg3.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle2.GetTaggedValue(), resInICPath2); JSTaggedValue resInSlowPath3 = SlowRuntimeStub::Mod2(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue()); JSHandle slowHandle3(thread, resInSlowPath3); JSTaggedValue resInICPath3 = ICBinaryOP::ModWithTSType(thread, arg1.GetTaggedValue(), arg2.GetTaggedValue(), JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(slowHandle3.GetTaggedValue(), resInICPath3); JSTaggedValue resInSlowPath4 = SlowRuntimeStub::Mod2(thread, arg2.GetTaggedValue(), JSTaggedValue::True()); JSHandle slowHandle4(thread, resInSlowPath4); JSTaggedValue resInICPath4 = ICBinaryOP::ModWithTSType(thread, arg2.GetTaggedValue(), JSTaggedValue::True(), JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(slowHandle4.GetTaggedValue(), resInICPath4); JSTaggedValue resInSlowPath5 = SlowRuntimeStub::Mod2(thread, arg4.GetTaggedValue(), JSTaggedValue::False()); JSHandle slowHandle5(thread, resInSlowPath5); JSTaggedValue resInICPath5 = ICBinaryOP::ModWithTSType(thread, arg4.GetTaggedValue(), JSTaggedValue::False(), JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(slowHandle5.GetTaggedValue(), resInICPath5); }; HWTEST_F_L0(ICBinaryOPTest, ShlWithTSType) { ObjectFactory *factory = ecmaVm->GetFactory(); JSHandle Str1 = factory->NewFromASCII("225"); JSTaggedValue arg1(static_cast(286)); JSTaggedValue arg3(static_cast(5)); JSTaggedValue resInICPath1 = ICBinaryOP::ShlWithTSType(thread, arg1, arg3, JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(JSTaggedValue(9152), resInICPath1); JSTaggedValue resInICPath2 = ICBinaryOP::ShlWithTSType(thread, Str1.GetTaggedValue(), arg3, JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(JSTaggedValue(7200), resInICPath2); }; HWTEST_F_L0(ICBinaryOPTest, ShrWithTSType) { ObjectFactory *factory = ecmaVm->GetFactory(); JSHandle Str1 = factory->NewFromASCII("225"); JSTaggedValue arg1(static_cast(286)); JSTaggedValue arg3(static_cast(5)); JSTaggedValue resInICPath1 = ICBinaryOP::ShrWithTSType(thread, arg1, arg3, JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(JSTaggedValue(8), resInICPath1); JSTaggedValue resInICPath2 = ICBinaryOP::ShrWithTSType(thread, Str1.GetTaggedValue(), arg3, JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(JSTaggedValue(7), resInICPath2); }; HWTEST_F_L0(ICBinaryOPTest, AshrWithTSType) { ObjectFactory *factory = ecmaVm->GetFactory(); JSHandle Str1 = factory->NewFromASCII("225"); JSTaggedValue arg1(static_cast(286)); JSTaggedValue arg2(static_cast(-286)); JSTaggedValue arg3(static_cast(5)); JSTaggedValue resInICPath1 = ICBinaryOP::AshrWithTSType(thread, arg1, arg3, JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(JSTaggedValue(8), resInICPath1); JSTaggedValue resInICPath3 = ICBinaryOP::AshrWithTSType(thread, arg2, arg3, JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(JSTaggedValue(134217719), resInICPath3); JSTaggedValue resInICPath2 = ICBinaryOP::AshrWithTSType(thread, Str1.GetTaggedValue(), arg3, JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(JSTaggedValue(7), resInICPath2); }; HWTEST_F_L0(ICBinaryOPTest, AndWithTSType) { ObjectFactory *factory = ecmaVm->GetFactory(); JSHandle Str1 = factory->NewFromASCII("225"); JSTaggedValue arg1(static_cast(286)); JSTaggedValue arg3(static_cast(541)); JSTaggedValue resInICPath1 = ICBinaryOP::AndWithTSType(thread, arg1, arg3, JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(JSTaggedValue(28), resInICPath1); JSTaggedValue resInICPath2 = ICBinaryOP::AndWithTSType(thread, Str1.GetTaggedValue(), arg3, JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(JSTaggedValue(1), resInICPath2); }; HWTEST_F_L0(ICBinaryOPTest, OrWithTSType) { ObjectFactory *factory = ecmaVm->GetFactory(); JSHandle Str1 = factory->NewFromASCII("225"); JSTaggedValue arg1(static_cast(286)); JSTaggedValue arg3(static_cast(523)); JSTaggedValue resInICPath1 = ICBinaryOP::OrWithTSType(thread, arg1, arg3, JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(JSTaggedValue(799), resInICPath1); JSTaggedValue resInICPath2 = ICBinaryOP::OrWithTSType(thread, Str1.GetTaggedValue(), arg3, JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(JSTaggedValue(747), resInICPath2); }; HWTEST_F_L0(ICBinaryOPTest, XorWithTSType) { ObjectFactory *factory = ecmaVm->GetFactory(); JSHandle Str1 = factory->NewFromASCII("1225"); JSTaggedValue arg1(static_cast(286)); JSTaggedValue arg3(static_cast(523)); JSTaggedValue resInICPath1 = ICBinaryOP::XorWithTSType(thread, arg1, arg3, JSTaggedValue(static_cast(BinaryType::NUMBER))); EXPECT_EQ(JSTaggedValue(789), resInICPath1); JSTaggedValue resInICPath2 = ICBinaryOP::XorWithTSType(thread, Str1.GetTaggedValue(), arg3, JSTaggedValue(static_cast(BinaryType::GENERIC))); EXPECT_EQ(JSTaggedValue(1730), resInICPath2); }; } // namespace panda::test