diff --git a/libabckit/include/libabckit/c/isa/isa_static.h b/libabckit/include/libabckit/c/isa/isa_static.h index 2da3d2637a86c4224cc95cfa11c801a5cfa884ca..62914d10d125be829bdc2452b665495ae0e1fb6b 100644 --- a/libabckit/include/libabckit/c/isa/isa_static.h +++ b/libabckit/include/libabckit/c/isa/isa_static.h @@ -83,6 +83,7 @@ enum AbckitIsaApiStaticOpcode { ABCKIT_ISA_API_STATIC_OPCODE_LOADNULLVALUE, ABCKIT_ISA_API_STATIC_OPCODE_EQUALS, ABCKIT_ISA_API_STATIC_OPCODE_STRICTEQUALS, + ABCKIT_ISA_API_STATIC_OPCODE_NULLCHECK, /* Return: */ ABCKIT_ISA_API_STATIC_OPCODE_RETURN_VOID, @@ -839,6 +840,16 @@ struct CAPI_EXPORT AbckitIsaApiStatic { * @note are not the same. */ AbckitInst *(*iCreateIsUndefined)(AbckitGraph *graph /* in */, AbckitInst *inputObj /* in */); + + /** + * @brief Creates `NullCheck` inst. + * @return AbckitInst *. + * @param [ in ] AbckitGraph *graph . + * @param [ in ] AbckitInst *input0 . + * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if AbckitGraph *graph is NULL. + * @note Set `ABCKIT_STATUS_BAD_ARGUMENT` error if AbckitInst *input0 is NULL. + */ + AbckitInst *(*iCreateNullCheck)(AbckitGraph *graph /* in */, AbckitInst *inputObj /* in */); }; /** diff --git a/libabckit/src/abckit_compiler_intrinsics.yaml b/libabckit/src/abckit_compiler_intrinsics.yaml index d1917df5b98cbcd15a5e5d8ba017b460ac7a3b3e..7dfceb6eaf6ed6c0e8d8204722063b5c049be6c3 100644 --- a/libabckit/src/abckit_compiler_intrinsics.yaml +++ b/libabckit/src/abckit_compiler_intrinsics.yaml @@ -632,3 +632,23 @@ intrinsics: need_nullcheck: [] is_fastpath: false need_param_locations: false + +- name: AbckitNullCheck + space: abckit + class_name: "NullCheck" + method_name: "ets.nullcheck" + compiler_only: true + private: false + static: true + safepoint_after_call: false + signature: + ret: none + args: [ ref ] + clear_flags: ["call", "heap_inv", "barrier", "acc_read", "acc_write" ] + set_flags: [ "can_throw", "no_dst","no_nullptr" ] + is_stub: false + additional_temps: 0 + codegen_arch: [] + need_nullcheck: [] + is_fastpath: false + need_param_locations: false \ No newline at end of file diff --git a/libabckit/src/adapter_static/abckit_inst_builder-inl.h b/libabckit/src/adapter_static/abckit_inst_builder-inl.h index 1ef0e33bb57ae30eb2f2e736f4cace29c9c939a7..1a842fb1bdd9340ac0b38f2f0c16c16b7b533ea4 100644 --- a/libabckit/src/adapter_static/abckit_inst_builder-inl.h +++ b/libabckit/src/adapter_static/abckit_inst_builder-inl.h @@ -33,6 +33,10 @@ void AbcKitInstBuilder::AbcKitBuildStoreObject(const BytecodeInstruction *bcInst BuildAbcKitStoreObjectIntrinsic(bcInst, type); } +void AbcKitInstBuilder::BuildNullcheck(const BytecodeInstruction *bcInst) +{ + BuildDefaultAbcKitIntrinsic(bcInst, ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_NULL_CHECK); +} void AbcKitInstBuilder::BuildIsNullValue(const BytecodeInstruction *bcInst) { BuildDefaultAbcKitIntrinsic(bcInst, ark::compiler::RuntimeInterface::IntrinsicId::INTRINSIC_ABCKIT_IS_NULL_VALUE); diff --git a/libabckit/src/adapter_static/abckit_inst_builder.h b/libabckit/src/adapter_static/abckit_inst_builder.h index f04c25789578c3df01c554af8ffb435eb184a5f6..df87f893a3b75ed7f94c6288d1cab66a6720cfd8 100644 --- a/libabckit/src/adapter_static/abckit_inst_builder.h +++ b/libabckit/src/adapter_static/abckit_inst_builder.h @@ -39,6 +39,7 @@ public: void BuildDefaultAbcKitIntrinsic(const BytecodeInstruction *bcInst, RuntimeInterface::IntrinsicId intrinsicId); private: + void BuildNullcheck(const BytecodeInstruction *bcInst) override; void BuildIsNullValue(const BytecodeInstruction *bcInst) override; void BuildLoadStatic(const BytecodeInstruction *bcInst, DataType::Type type) override; void BuildStoreStatic(const BytecodeInstruction *bcInst, DataType::Type type) override; diff --git a/libabckit/src/adapter_static/ir_static.h b/libabckit/src/adapter_static/ir_static.h index 2eaf9bb2a5f37ae24bed0fc7291aa61e3ac4d593..947ed342c5df379204f221f5b79d7151b1c86cb4 100644 --- a/libabckit/src/adapter_static/ir_static.h +++ b/libabckit/src/adapter_static/ir_static.h @@ -149,6 +149,7 @@ AbckitInst *IcreateIsInstanceStatic(AbckitGraph *graph, AbckitInst *inputObj, Ab AbckitInst *IcreateLoadNullValueStatic(AbckitGraph *graph); AbckitInst *IcreateCastStatic(AbckitGraph *graph, AbckitInst *input0, AbckitTypeId targetTypeId); AbckitInst *IcreateIsUndefinedStatic(AbckitGraph *graph, AbckitInst *inputObj); +AbckitInst *IcreateNullCheckStatic(AbckitGraph *graph, AbckitInst *inputObj); AbckitInst *IcreateThrowStatic(AbckitGraph *graph, AbckitInst *input0); diff --git a/libabckit/src/adapter_static/ir_static_instr_1.cpp b/libabckit/src/adapter_static/ir_static_instr_1.cpp index 1531e78b13c8642ab551f7fa5235a4cb87856724..92c66d9099bc0f0fb6cc3f81fbdee89a27bf1577 100644 --- a/libabckit/src/adapter_static/ir_static_instr_1.cpp +++ b/libabckit/src/adapter_static/ir_static_instr_1.cpp @@ -2023,6 +2023,18 @@ AbckitInst *IcreateIsUndefinedStatic(AbckitGraph *graph, AbckitInst *inputObj) return CreateInstFromImpl(graph, intrImpl); } +AbckitInst *IcreateNullCheckStatic(AbckitGraph *graph, AbckitInst *inputObj) +{ + LIBABCKIT_LOG_FUNC; + auto intrImpl = graph->impl->CreateInstIntrinsic(compiler::DataType::VOID, 0, + compiler::IntrinsicInst::IntrinsicId::INTRINSIC_ABCKIT_NULL_CHECK); + size_t argsCount {1U}; + intrImpl->ReserveInputs(argsCount); + intrImpl->AllocateInputTypes(graph->impl->GetAllocator(), argsCount); + intrImpl->AppendInput(inputObj->impl, compiler::DataType::REFERENCE); + return CreateInstFromImpl(graph, intrImpl); +} + AbckitInst *IcreateReturnStatic(AbckitGraph *graph, AbckitInst *input0) { auto instImpl = graph->impl->CreateInstReturn(input0->impl->GetType(), compiler::INVALID_PC, input0->impl); diff --git a/libabckit/src/adapter_static/metadata_modify_static.cpp b/libabckit/src/adapter_static/metadata_modify_static.cpp index d58ae83e73549afbaef4dba20650875527065e70..b0dee3d6eca23344f235e6171ef53f72d884cb90 100644 --- a/libabckit/src/adapter_static/metadata_modify_static.cpp +++ b/libabckit/src/adapter_static/metadata_modify_static.cpp @@ -99,7 +99,7 @@ void FunctionSetGraphStatic(AbckitCoreFunction *function, AbckitGraph *graph) graphImpl->RunPass(); - graphImpl->RunPass(false); + //graphImpl->RunPass(false); graphImpl->RunPass(); diff --git a/libabckit/src/codegen/codegen_static_isapi.rb b/libabckit/src/codegen/codegen_static_isapi.rb index 4f270712366202befca5b918d3cd37dd80dad6e5..a3cbe498f450a6822be15a603f77f01991d2ae9b 100644 --- a/libabckit/src/codegen/codegen_static_isapi.rb +++ b/libabckit/src/codegen/codegen_static_isapi.rb @@ -538,7 +538,10 @@ def call_me_from_template visit('IsNullValueIntrinsic') do plain('ets.isnullvalue') end - + visit('NullCheckIntrinsic') do + plain('ets.nullcheck') + end + # Empty visitors for IR instructions we want to ignore # (Add missing IRs on demand) %w[NullCheck BoundsCheck ZeroCheck NegativeCheck SafePoint diff --git a/libabckit/src/isa_static_impl.cpp b/libabckit/src/isa_static_impl.cpp index 3a3230b095ba728f4112f83379af786c3f5165ed..cee640ee3f024991703db5c4eb130de797435f63 100644 --- a/libabckit/src/isa_static_impl.cpp +++ b/libabckit/src/isa_static_impl.cpp @@ -898,6 +898,20 @@ extern "C" AbckitInst *IcreateIsUndefined(AbckitGraph *graph, AbckitInst *inputO return IcreateIsUndefinedStatic(graph, inputObj); } +extern "C" AbckitInst *IcreateNullCheck(AbckitGraph *graph, AbckitInst *inputObj) +{ + LIBABCKIT_CLEAR_LAST_ERROR; + LIBABCKIT_IMPLEMENTED; + LIBABCKIT_TIME_EXEC; + + LIBABCKIT_BAD_ARGUMENT(graph, nullptr); + LIBABCKIT_BAD_ARGUMENT(inputObj, nullptr); + + LIBABCKIT_WRONG_CTX(graph, inputObj->graph, nullptr); + LIBABCKIT_WRONG_MODE(graph, Mode::STATIC, nullptr); + return IcreateNullCheckStatic(graph, inputObj); +} + AbckitIsaApiStatic g_isaApiStaticImpl = { IgetClass, @@ -956,6 +970,7 @@ AbckitIsaApiStatic g_isaApiStaticImpl = { IcreateXorI, IcreateThrow, IcreateIsUndefined, + IcreateNullCheck, }; } // namespace libabckit diff --git a/libabckit/tests/BUILD.gn b/libabckit/tests/BUILD.gn index 14b68126e8331d444914c9e5f1d019776bd5c399..715c2322ae5b50b4a4dead19d99728dc319a1f06 100644 --- a/libabckit/tests/BUILD.gn +++ b/libabckit/tests/BUILD.gn @@ -203,6 +203,7 @@ abckit_gtests_sources = [ "ut/isa/isa_static/get_opcode/get_opcode_static.cpp", "ut/isa/isa_static/is_instance/is_instance.cpp", "ut/isa/isa_static/is_nullvalue/is_nullvalue.cpp", + "ut/isa/isa_static/nullcheck/nullcheck_test.cpp", "ut/isa/isa_static/load_nullvalue/load_nullvalue_static.cpp", "ut/isa/isa_static/load_string/load_string_static.cpp", "ut/isa/isa_static/objects/objects.cpp", @@ -485,6 +486,7 @@ test_ets_files = [ "ut/isa/isa_static/get_opcode/get_opcode_static", "ut/isa/isa_static/is_instance/is_instance_static", "ut/isa/isa_static/is_nullvalue/is_nullvalue_static", + "ut/isa/isa_static/nullcheck/nullcheck_static", "ut/isa/isa_static/create_if/create_if_static", "ut/isa/isa_static/objects/objects", "ut/isa/isa_static/throw/throw_static", diff --git a/libabckit/tests/mock/isa_api_static_impl_mock.cpp b/libabckit/tests/mock/isa_api_static_impl_mock.cpp index 1188bad297c1b2206d95f6041b117921f573e059..eef9de440e38bb06d06bb54368362ff244d80963 100644 --- a/libabckit/tests/mock/isa_api_static_impl_mock.cpp +++ b/libabckit/tests/mock/isa_api_static_impl_mock.cpp @@ -559,6 +559,14 @@ AbckitInst *IcreateIsUndefined(AbckitGraph *graph, AbckitInst *inputObj) return DEFAULT_INST; } +AbckitInst *IcreateNullCheck(AbckitGraph *graph, AbckitInst *inputObj) +{ + g_calledFuncs.push(__func__); + EXPECT_TRUE(graph == DEFAULT_GRAPH); + EXPECT_TRUE(inputObj == DEFAULT_INST); + return DEFAULT_INST; +} + AbckitIsaApiStatic g_isaApiStaticImpl = { IgetClass, IsetClass, @@ -615,6 +623,7 @@ AbckitIsaApiStatic g_isaApiStaticImpl = { IcreateXorI, IcreateThrow, IcreateIsUndefined, + IcreateNullCheck, }; // NOLINTEND(readability-identifier-naming) diff --git a/libabckit/tests/null_args_tests/null_args_tests_IsaApiStaticImpl_0.cpp b/libabckit/tests/null_args_tests/null_args_tests_IsaApiStaticImpl_0.cpp index 0ff768559e34eb7a4a3d390a436d207e23205ea0..7113a7fc6306038791f01abf063779955d4e240b 100644 --- a/libabckit/tests/null_args_tests/null_args_tests_IsaApiStaticImpl_0.cpp +++ b/libabckit/tests/null_args_tests/null_args_tests_IsaApiStaticImpl_0.cpp @@ -174,6 +174,13 @@ TEST_F(LibAbcKitNullptrTestsIsaApiStaticImpl0, iCreateIsUndefined) helpers_nullptr::TestNullptr(g_isaApiStaticImp->iCreateIsUndefined); } +// Test: test-kind=api, api=IsaApiStaticImpl::iCreateNullCheck, +// abc-kind=NoABC, category=negative-nullptr, extension=c +TEST_F(LibAbcKitNullptrTestsIsaApiStaticImpl0, iCreateNullCheck) +{ + helpers_nullptr::TestNullptr(g_isaApiStaticImp->iCreateNullCheck); +} + // Test: test-kind=api, api=IsaApiStaticImpl::iCreateLenArray, // abc-kind=NoABC, category=negative-nullptr, extension=c TEST_F(LibAbcKitNullptrTestsIsaApiStaticImpl0, iCreateLenArray) diff --git a/libabckit/tests/ut/isa/isa_static/nullcheck/nullcheck_static.ets b/libabckit/tests/ut/isa/isa_static/nullcheck/nullcheck_static.ets new file mode 100644 index 0000000000000000000000000000000000000000..87d80ae0383729d544098c86063f29b0a9e72363 --- /dev/null +++ b/libabckit/tests/ut/isa/isa_static/nullcheck/nullcheck_static.ets @@ -0,0 +1,22 @@ + + +class A {} + +function foo() : A|null { + let a = new A(); + // AOP add ets.nullcheck(a|nullptr) here + // for nullptr should throw NPE + return a +} + + + +function main() { + try { + let b: A|null = foo(); + console.log(b); + } catch(e) { + console.log(e); + } +} + diff --git a/libabckit/tests/ut/isa/isa_static/nullcheck/nullcheck_test.cpp b/libabckit/tests/ut/isa/isa_static/nullcheck/nullcheck_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a3bb9ba59b398a362c8364bd2cb3427c958c410 --- /dev/null +++ b/libabckit/tests/ut/isa/isa_static/nullcheck/nullcheck_test.cpp @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2024-2025 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 "libabckit/c/abckit.h" +#include "libabckit/c/isa/isa_static.h" +#include "libabckit/c/isa/isa_dynamic.h" +#include "libabckit/c/metadata_core.h" + +#include "helpers/helpers_runtime.h" +#include "helpers/helpers.h" + +#include + +// NOLINTBEGIN(readability-magic-numbers) +namespace libabckit::test { + +namespace { +auto g_impl = AbckitGetApiImpl(ABCKIT_VERSION_RELEASE_1_0_0); +auto g_implI = AbckitGetInspectApiImpl(ABCKIT_VERSION_RELEASE_1_0_0); +auto g_implM = AbckitGetModifyApiImpl(ABCKIT_VERSION_RELEASE_1_0_0); +auto g_implG = AbckitGetGraphApiImpl(ABCKIT_VERSION_RELEASE_1_0_0); +auto g_statG = AbckitGetIsaApiStaticImpl(ABCKIT_VERSION_RELEASE_1_0_0); +} // namespace + +class LibAbcKitNullCheckStaticTest : public ::testing::Test {}; + +// Test: test-kind=api, api=IsaApiStaticImpl::iCreateNullCheck, abc-kind=ArkTS2, category=positive, extension=c +TEST_F(LibAbcKitNullCheckStaticTest, LibAbcKitTestNullCheck) +{ + auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/nullcheck/nullcheck_static.abc", + "nullcheck_static", "main"); + EXPECT_NE(output.find("nullcheck_static.A"), std::string::npos); + helpers::TransformMethod( + ABCKIT_ABC_DIR "ut/isa/isa_static/nullcheck/nullcheck_static.abc", + ABCKIT_ABC_DIR "ut/isa/isa_static/nullcheck/nullcheck_static_modified.abc", "foo", + [](AbckitFile * /*file*/, AbckitCoreFunction *method, AbckitGraph *graph) { + AbckitInst *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN); + ASSERT_NE(ret, nullptr); + ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR); + AbckitInst *inputObj = g_implG->iGetInput(ret, 0); + + AbckitInst *nullCheck = g_statG->iCreateNullCheck(graph, inputObj); + ASSERT_NE(nullCheck, nullptr); + ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR); + g_implG->iInsertBefore(nullCheck, ret); + ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR); + g_implG->gDump(graph, 1); + }, + [](AbckitGraph *graph) { + std::vector> insts1({}); + + std::vector> insts0({ + {0, ABCKIT_ISA_API_STATIC_OPCODE_INITOBJECT, {}}, + {2, ABCKIT_ISA_API_STATIC_OPCODE_NULLCHECK, {0}}, + {1, ABCKIT_ISA_API_STATIC_OPCODE_RETURN, {0}}, + }); + + std::vector> insts2({}); + + helpers::BBSchema bb1({{}, {1}, insts1}); + helpers::BBSchema bb0({{0}, {2}, insts0}); + helpers::BBSchema bb2({{1}, {}, insts2}); + + std::vector> bbSchemas({bb1, bb0, bb2}); + + helpers::VerifyGraph(graph, bbSchemas); + }); + + auto modified_output = helpers::ExecuteStaticAbc( + ABCKIT_ABC_DIR "ut/isa/isa_static/nullcheck/nullcheck_static_modified.abc", "nullcheck_static", "main"); + EXPECT_EQ(modified_output, output); +} + +TEST_F(LibAbcKitNullCheckStaticTest, LibAbcKitTestNullCheck2) +{ + auto output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/nullcheck/nullcheck_static.abc", + "nullcheck_static", "main"); + helpers::TransformMethod( + ABCKIT_ABC_DIR "ut/isa/isa_static/nullcheck/nullcheck_static.abc", + ABCKIT_ABC_DIR "ut/isa/isa_static/nullcheck/nullcheck_static_modified.abc", "foo", + [](AbckitFile * /*file*/, AbckitCoreFunction *method, AbckitGraph *graph) { + AbckitInst *ret = helpers::FindFirstInst(graph, ABCKIT_ISA_API_STATIC_OPCODE_RETURN); + ASSERT_NE(ret, nullptr); + ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR); + + AbckitInst *ldaNull = g_statG->gCreateNullPtr(graph); + ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR); + + AbckitInst *nullCheck = g_statG->iCreateNullCheck(graph, ldaNull); + ASSERT_NE(nullCheck, nullptr); + ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR); + g_implG->iInsertBefore(nullCheck, ret); + ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR); + + AbckitInst *createReturn = g_statG->iCreateReturn(graph, ldaNull); + ASSERT_NE(createReturn, nullptr); + ASSERT_EQ(g_impl->getLastError(), ABCKIT_STATUS_NO_ERROR); + helpers::ReplaceInst(ret, createReturn); + g_implG->gDump(graph, 1); + }, + [](AbckitGraph *graph) { + std::vector> insts1({ + {2, ABCKIT_ISA_API_STATIC_OPCODE_NULLPTR, {}}, + }); + + std::vector> insts0({ + {0, ABCKIT_ISA_API_STATIC_OPCODE_INITOBJECT, {}}, + {3, ABCKIT_ISA_API_STATIC_OPCODE_NULLCHECK, {2}}, + {4, ABCKIT_ISA_API_STATIC_OPCODE_RETURN, {2}}, + }); + + std::vector> insts2({}); + + helpers::BBSchema bb1({{}, {1}, insts1}); + helpers::BBSchema bb0({{0}, {2}, insts0}); + helpers::BBSchema bb2({{1}, {}, insts2}); + + std::vector> bbSchemas({bb1, bb0, bb2}); + helpers::VerifyGraph(graph, bbSchemas); + }); + output = helpers::ExecuteStaticAbc(ABCKIT_ABC_DIR "ut/isa/isa_static/nullcheck/nullcheck_static_modified.abc", + "nullcheck_static", "main"); + EXPECT_TRUE(helpers::Match(output, "NullPointerError\n")); +} + +} // namespace libabckit::test +// NOLINTEND(readability-magic-numbers) diff --git a/libabckit/tests/wrong_ctx_tests/wrong_ctx_tests_IsaApiStaticImpl_0.cpp b/libabckit/tests/wrong_ctx_tests/wrong_ctx_tests_IsaApiStaticImpl_0.cpp index efb84ff3c334b5d397c377c866cd871867e9d918..d9703c17847dab6cd647da28aa6ba7179dd0fb54 100644 --- a/libabckit/tests/wrong_ctx_tests/wrong_ctx_tests_IsaApiStaticImpl_0.cpp +++ b/libabckit/tests/wrong_ctx_tests/wrong_ctx_tests_IsaApiStaticImpl_0.cpp @@ -53,6 +53,13 @@ TEST_F(LibAbcKitWrongCtxTestsIsaApiStaticImpl0, iCreateIsUndefined) helpers_wrong_ctx::TestWrongCtx(g_isaApiStaticImp->iCreateIsUndefined); } +// Test: test-kind=api, api=IsaApiStaticImpl::iCreateNullCheck, +// abc-kind=NoABC, category=negative-file +TEST_F(LibAbcKitWrongCtxTestsIsaApiStaticImpl0, iCreateNullCheck) +{ + helpers_wrong_ctx::TestWrongCtx(g_isaApiStaticImp->iCreateNullCheck); +} + // Test: test-kind=api, api=IsaApiStaticImpl::iCreateDivI, // abc-kind=NoABC, category=negative-file TEST_F(LibAbcKitWrongCtxTestsIsaApiStaticImpl0, iCreateDivI) diff --git a/static_core/plugins/ets/compiler/optimizer/ir_builder/ets_inst_builder.h b/static_core/plugins/ets/compiler/optimizer/ir_builder/ets_inst_builder.h index 6e29b9c6427572a67b801cc5151db5be23507438..1a94da938c2049755e29830a94f5b57ff38e4243 100644 --- a/static_core/plugins/ets/compiler/optimizer/ir_builder/ets_inst_builder.h +++ b/static_core/plugins/ets/compiler/optimizer/ir_builder/ets_inst_builder.h @@ -33,6 +33,6 @@ template void BuildEquals(const BytecodeInstruction *bcInst); void BuildTypeof(const BytecodeInstruction *bcInst); void BuildIstrue(const BytecodeInstruction *bcInst); -void BuildNullcheck(const BytecodeInstruction *bcInst); +virtual void BuildNullcheck(const BytecodeInstruction *bcInst); #endif // PLUGINS_ETS_COMPILER_OPTIMIZER_IR_BUILDER_ETS_INST_BUILDER_H