From d3174a46c3c59a022a2d37d4cb5fe20da5aa19e0 Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Fri, 11 Apr 2025 21:34:56 +0300 Subject: [PATCH 1/2] VerifyANI: Skeleton for verify mode Issue: #ICQISM Signed-off-by: Vyacheslav Cherkashin --- .../plugins/ets/runtime/CMakeLists.txt | 6 + static_core/plugins/ets/runtime/ani/ani.h | 43 +- .../plugins/ets/runtime/ani/ani_converters.h | 124 + .../ets/runtime/ani/ani_interaction_api.cpp | 121 +- .../plugins/ets/runtime/ani/ani_options.cpp | 17 + .../plugins/ets/runtime/ani/ani_options.h | 7 + .../ets/runtime/ani/ani_options_parser.cpp | 13 +- .../ets/runtime/ani/ani_options_parser.h | 1 + .../ets/runtime/ani/verify/ani_verifier.cpp | 49 + .../ets/runtime/ani/verify/ani_verifier.h | 62 + .../runtime/ani/verify/env_ani_verifier.cpp | 196 + .../ets/runtime/ani/verify/env_ani_verifier.h | 113 + .../ets/runtime/ani/verify/types/venv.cpp | 81 + .../ets/runtime/ani/verify/types/venv.h | 62 + .../ets/runtime/ani/verify/types/vref.h | 86 + .../ets/runtime/ani/verify/types/vvm.h | 40 + .../runtime/ani/verify/verify_ani_cast_api.h | 111 + .../runtime/ani/verify/verify_ani_checker.cpp | 779 +++ .../runtime/ani/verify/verify_ani_checker.h | 241 + .../ani/verify/verify_ani_interaction_api.cpp | 4333 +++++++++++++++++ .../ani/verify/verify_ani_interaction_api.h | 25 + .../runtime/ani/verify/verify_ani_vm_api.cpp | 104 + .../runtime/ani/verify/verify_ani_vm_api.h | 25 + .../plugins/ets/runtime/ets_napi_env.cpp | 6 + .../plugins/ets/runtime/ets_napi_env.h | 13 + static_core/plugins/ets/runtime/ets_vm.cpp | 9 + static_core/plugins/ets/runtime/ets_vm.h | 17 + .../plugins/ets/runtime/ets_vm_options.h | 56 + static_core/plugins/ets/subproject_sources.gn | 6 + .../ets/tests/ani/ani_gtest/ani_gtest.h | 18 + .../tests/ani/ani_gtest/verify_ani_gtest.h | 139 + .../ets/tests/ani/cmake/ani_tests.cmake | 12 +- .../tests/ani/tests/verifyani/CMakeLists.txt | 19 + .../verifyani/cmake/ani_verify_tests.cmake | 57 + .../tests/verifyani/object_ops/CMakeLists.txt | 22 + .../object_ops/verify_object_new_a_test.cpp | 329 ++ .../object_ops/verify_object_new_a_test.ets | 38 + .../object_ops/verify_object_new_test.cpp | 555 +++ .../object_ops/verify_object_new_test.ets | 38 + .../tests/verifyani/ref_ops/CMakeLists.txt | 21 + .../ref_ops/verify_get_undefined_test.cpp | 63 + .../ref_ops/verify_reference_delete_test.cpp | 193 + .../ref_ops/verify_reference_delete_test.ets | 16 + .../tests/verifyani/scope_ops/CMakeLists.txt | 28 + .../verify_create_escape_local_scope_test.cpp | 94 + .../verify_create_local_scope_test.cpp | 92 + ...verify_destroy_escape_local_scope_test.cpp | 246 + .../verify_destroy_local_scope_test.cpp | 80 + .../ani/tests/verifyani/vm_ops/CMakeLists.txt | 20 + .../verify_attach_current_thread_test.cpp | 154 + .../verifyani/vm_ops/verify_get_env_test.cpp | 76 + .../ets/tests/ani/tests/vm_ops/CMakeLists.txt | 4 +- .../tests/libani_helpers/tests/CMakeLists.txt | 11 +- .../native/exclusive_worker/CMakeLists.txt | 11 +- .../exclusive_worker_tests.cpp | 2 +- .../native/sync_primitives/CMakeLists.txt | 9 +- static_core/runtime/include/runtime_options.h | 11 + 57 files changed, 8960 insertions(+), 144 deletions(-) create mode 100644 static_core/plugins/ets/runtime/ani/ani_converters.h create mode 100644 static_core/plugins/ets/runtime/ani/verify/ani_verifier.cpp create mode 100644 static_core/plugins/ets/runtime/ani/verify/ani_verifier.h create mode 100644 static_core/plugins/ets/runtime/ani/verify/env_ani_verifier.cpp create mode 100644 static_core/plugins/ets/runtime/ani/verify/env_ani_verifier.h create mode 100644 static_core/plugins/ets/runtime/ani/verify/types/venv.cpp create mode 100644 static_core/plugins/ets/runtime/ani/verify/types/venv.h create mode 100644 static_core/plugins/ets/runtime/ani/verify/types/vref.h create mode 100644 static_core/plugins/ets/runtime/ani/verify/types/vvm.h create mode 100644 static_core/plugins/ets/runtime/ani/verify/verify_ani_cast_api.h create mode 100644 static_core/plugins/ets/runtime/ani/verify/verify_ani_checker.cpp create mode 100644 static_core/plugins/ets/runtime/ani/verify/verify_ani_checker.h create mode 100644 static_core/plugins/ets/runtime/ani/verify/verify_ani_interaction_api.cpp create mode 100644 static_core/plugins/ets/runtime/ani/verify/verify_ani_interaction_api.h create mode 100644 static_core/plugins/ets/runtime/ani/verify/verify_ani_vm_api.cpp create mode 100644 static_core/plugins/ets/runtime/ani/verify/verify_ani_vm_api.h create mode 100644 static_core/plugins/ets/runtime/ets_vm_options.h create mode 100644 static_core/plugins/ets/tests/ani/ani_gtest/verify_ani_gtest.h create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/CMakeLists.txt create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/cmake/ani_verify_tests.cmake create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/object_ops/CMakeLists.txt create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/object_ops/verify_object_new_a_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/object_ops/verify_object_new_a_test.ets create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/object_ops/verify_object_new_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/object_ops/verify_object_new_test.ets create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/ref_ops/CMakeLists.txt create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/ref_ops/verify_get_undefined_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/ref_ops/verify_reference_delete_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/ref_ops/verify_reference_delete_test.ets create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/scope_ops/CMakeLists.txt create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/scope_ops/verify_create_escape_local_scope_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/scope_ops/verify_create_local_scope_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/scope_ops/verify_destroy_escape_local_scope_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/scope_ops/verify_destroy_local_scope_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/vm_ops/CMakeLists.txt create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/vm_ops/verify_attach_current_thread_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/verifyani/vm_ops/verify_get_env_test.cpp diff --git a/static_core/plugins/ets/runtime/CMakeLists.txt b/static_core/plugins/ets/runtime/CMakeLists.txt index 3bdff69aa7..1267ec544d 100644 --- a/static_core/plugins/ets/runtime/CMakeLists.txt +++ b/static_core/plugins/ets/runtime/CMakeLists.txt @@ -20,6 +20,12 @@ set(ETS_RUNTIME_SOURCES ${ETS_EXT_SOURCES}/ani/ani_options.cpp ${ETS_EXT_SOURCES}/ani/ani_options_parser.cpp ${ETS_EXT_SOURCES}/ani/ani_vm_api.cpp + ${ETS_EXT_SOURCES}/ani/verify/ani_verifier.cpp + ${ETS_EXT_SOURCES}/ani/verify/env_ani_verifier.cpp + ${ETS_EXT_SOURCES}/ani/verify/types/venv.cpp + ${ETS_EXT_SOURCES}/ani/verify/verify_ani_checker.cpp + ${ETS_EXT_SOURCES}/ani/verify/verify_ani_interaction_api.cpp + ${ETS_EXT_SOURCES}/ani/verify/verify_ani_vm_api.cpp ${ETS_EXT_SOURCES}/ets_annotation.cpp ${ETS_EXT_SOURCES}/ets_class_linker.cpp ${ETS_EXT_SOURCES}/ets_class_linker_context.cpp diff --git a/static_core/plugins/ets/runtime/ani/ani.h b/static_core/plugins/ets/runtime/ani/ani.h index 2b88b1a115..5522cd671e 100644 --- a/static_core/plugins/ets/runtime/ani/ani.h +++ b/static_core/plugins/ets/runtime/ani/ani.h @@ -305,12 +305,12 @@ struct __ani_interaction_api { * * @param[in] env A pointer to the environment structure. * @param[in] cls The class of the object to create. - * @param[in] method The constructor method to invoke. - * @param[in] ... Variadic arguments to pass to the constructor method. + * @param[in] ctor The constructor method to invoke. * @param[out] result A pointer to store the object return value. + * @param[in] ... Variadic arguments to pass to the constructor method. * @return Returns a status code of type `ani_status` indicating success or failure. */ - ani_status (*Object_New)(ani_env *env, ani_class cls, ani_method method, ani_object *result, ...); + ani_status (*Object_New)(ani_env *env, ani_class cls, ani_method ctor, ani_object *result, ...); /** * @brief Creates a new object of a specified class using a constructor method (array-based). @@ -320,13 +320,12 @@ struct __ani_interaction_api { * * @param[in] env A pointer to the environment structure. * @param[in] cls The class of the object to create. - * @param[in] method The constructor method to invoke. - * @param[in] args An array of arguments to pass to the constructor method. + * @param[in] ctor The constructor method to invoke. * @param[out] result A pointer to store the object return value. + * @param[in] args An array of arguments to pass to the constructor method. * @return Returns a status code of type `ani_status` indicating success or failure. */ - ani_status (*Object_New_A)(ani_env *env, ani_class cls, ani_method method, ani_object *result, - const ani_value *args); + ani_status (*Object_New_A)(ani_env *env, ani_class cls, ani_method ctor, ani_object *result, const ani_value *args); /** * @brief Creates a new object of a specified class using a constructor method (variadic arguments). @@ -336,12 +335,12 @@ struct __ani_interaction_api { * * @param[in] env A pointer to the environment structure. * @param[in] cls The class of the object to create. - * @param[in] method The constructor method to invoke. - * @param[in] args A `va_list` of arguments to pass to the constructor method. + * @param[in] ctor The constructor method to invoke. * @param[out] result A pointer to store the object return value. + * @param[in] args A `va_list` of arguments to pass to the constructor method. * @return Returns a status code of type `ani_status` indicating success or failure. */ - ani_status (*Object_New_V)(ani_env *env, ani_class cls, ani_method method, ani_object *result, va_list args); + ani_status (*Object_New_V)(ani_env *env, ani_class cls, ani_method ctor, ani_object *result, va_list args); /** * @brief Retrieves the type of a given object. @@ -626,10 +625,10 @@ struct __ani_interaction_api { * This function deletes a specified local reference to free up resources. * * @param[in] env A pointer to the environment structure. - * @param[in] ref The reference to be deleted. + * @param[in] lref The local reference to be deleted. * @return Returns a status code of type `ani_status` indicating success or failure. */ - ani_status (*Reference_Delete)(ani_env *env, ani_ref ref); + ani_status (*Reference_Delete)(ani_env *env, ani_ref lref); /** * @brief Ensures enough local references are available. @@ -6283,21 +6282,21 @@ struct __ani_env { { return c_api->GetVM(this, result); } - ani_status Object_New(ani_class cls, ani_method method, ani_object *result, ...) + ani_status Object_New(ani_class cls, ani_method ctor, ani_object *result, ...) { va_list args; va_start(args, result); - ani_status status = c_api->Object_New_V(this, cls, method, result, args); + ani_status status = c_api->Object_New_V(this, cls, ctor, result, args); va_end(args); return status; } - ani_status Object_New_A(ani_class cls, ani_method method, ani_object *result, const ani_value *args) + ani_status Object_New_A(ani_class cls, ani_method ctor, ani_object *result, const ani_value *args) { - return c_api->Object_New_A(this, cls, method, result, args); + return c_api->Object_New_A(this, cls, ctor, result, args); } - ani_status Object_New_V(ani_class cls, ani_method method, ani_object *result, va_list args) + ani_status Object_New_V(ani_class cls, ani_method ctor, ani_object *result, va_list args) { - return c_api->Object_New_V(this, cls, method, result, args); + return c_api->Object_New_V(this, cls, ctor, result, args); } ani_status Object_GetType(ani_object object, ani_type *result) { @@ -6385,9 +6384,9 @@ struct __ani_env { { return c_api->Class_BindNativeMethods(this, cls, methods, nr_methods); } - ani_status Reference_Delete(ani_ref ref) + ani_status Reference_Delete(ani_ref lref) { - return c_api->Reference_Delete(this, ref); + return c_api->Reference_Delete(this, lref); } ani_status EnsureEnoughReferences(ani_size nr_refs) { @@ -8215,9 +8214,9 @@ struct __ani_env { { return c_api->GlobalReference_Create(this, ref, result); } - ani_status GlobalReference_Delete(ani_ref ref) + ani_status GlobalReference_Delete(ani_ref gref) { - return c_api->GlobalReference_Delete(this, ref); + return c_api->GlobalReference_Delete(this, gref); } ani_status WeakReference_Create(ani_ref ref, ani_wref *result) { diff --git a/static_core/plugins/ets/runtime/ani/ani_converters.h b/static_core/plugins/ets/runtime/ani/ani_converters.h new file mode 100644 index 0000000000..2923a808cd --- /dev/null +++ b/static_core/plugins/ets/runtime/ani/ani_converters.h @@ -0,0 +1,124 @@ +/** + * Copyright (c) 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. + */ + +#ifndef PANDA_PLUGINS_ETS_RUNTIME_ANI_ANI_CONVERTERS_H +#define PANDA_PLUGINS_ETS_RUNTIME_ANI_ANI_CONVERTERS_H + +#include "ani.h" +#include "plugins/ets/runtime/types/ets_field.h" +#include "plugins/ets/runtime/types/ets_method.h" +#include "plugins/ets/runtime/types/ets_variable.h" + +namespace ark::ets::ani { + +static inline ani_field ToAniField(EtsField *field) +{ + ASSERT(field != nullptr); + ASSERT(!field->IsStatic()); + return reinterpret_cast(field); +} + +static inline EtsField *ToInternalField(ani_field field) +{ + auto *f = reinterpret_cast(field); + ASSERT(f != nullptr); + ASSERT(!f->IsStatic()); + return f; +} + +static inline ani_static_field ToAniStaticField(EtsField *field) +{ + ASSERT(field != nullptr); + ASSERT(field->IsStatic()); + return reinterpret_cast(field); +} + +static inline EtsField *ToInternalField(ani_static_field field) +{ + auto *f = reinterpret_cast(field); + ASSERT(f != nullptr); + ASSERT(f->IsStatic()); + return f; +} + +static inline ani_variable ToAniVariable(EtsVariable *variable) +{ + ASSERT(variable != nullptr); + ASSERT(variable->AsField()->IsStatic()); + return reinterpret_cast(variable); +} + +static inline EtsVariable *ToInternalVariable(ani_variable variable) +{ + auto *v = reinterpret_cast(variable); + ASSERT(v != nullptr); + ASSERT(v->AsField()->IsStatic()); + return v; +} + +static inline EtsMethod *ToInternalMethod(ani_method method) +{ + auto *m = reinterpret_cast(method); + ASSERT(m != nullptr); + ASSERT(!m->IsStatic()); + ASSERT(!m->IsFunction()); + return m; +} + +static inline ani_method ToAniMethod(EtsMethod *method) +{ + ASSERT(method != nullptr); + ASSERT(!method->IsStatic()); + ASSERT(!method->IsFunction()); + return reinterpret_cast(method); +} + +static inline EtsMethod *ToInternalMethod(ani_static_method method) +{ + auto *m = reinterpret_cast(method); + ASSERT(m != nullptr); + ASSERT(m->IsStatic()); + ASSERT(!m->IsFunction()); + return m; +} + +static inline ani_static_method ToAniStaticMethod(EtsMethod *method) +{ + ASSERT(method != nullptr); + ASSERT(method->IsStatic()); + ASSERT(!method->IsFunction()); + return reinterpret_cast(method); +} + +static inline EtsMethod *ToInternalFunction(ani_function fn) +{ + auto *m = reinterpret_cast(fn); + ASSERT(m != nullptr); + ASSERT(m->IsStatic()); + ASSERT(m->IsFunction()); + return m; +} + +static inline ani_function ToAniFunction(EtsMethod *method) +{ + ASSERT(method != nullptr); + ASSERT(method->IsStatic()); + ASSERT(method->IsFunction()); + return reinterpret_cast(method); +} + +} // namespace ark::ets::ani + +#endif // PANDA_PLUGINS_ETS_RUNTIME_ANI_ANI_CONVERTERS_H diff --git a/static_core/plugins/ets/runtime/ani/ani_interaction_api.cpp b/static_core/plugins/ets/runtime/ani/ani_interaction_api.cpp index 9498dca201..829a3c1e26 100644 --- a/static_core/plugins/ets/runtime/ani/ani_interaction_api.cpp +++ b/static_core/plugins/ets/runtime/ani/ani_interaction_api.cpp @@ -24,6 +24,7 @@ #include "libpandabase/macros.h" #include "libpandabase/utils/logger.h" #include "plugins/ets/runtime/ani/ani_checkers.h" +#include "plugins/ets/runtime/ani/ani_converters.h" #include "plugins/ets/runtime/ani/ani_interaction_api.h" #include "plugins/ets/runtime/ani/ani_mangle.h" #include "plugins/ets/runtime/ani/ani_type_info.h" @@ -46,10 +47,16 @@ // CC-OFFNXT(G.PRE.02) should be with define #define CHECK_PTR_ARG(arg) ANI_CHECK_RETURN_IF_EQ(arg, nullptr, ANI_INVALID_ARGS) +// CC-OFFNXT(G.PRE.02) should be with define +#define CHECK_ENV_THAT_CAN_HAVE_PENDING_ERROR(env) \ + do { \ + ANI_CHECK_RETURN_IF_EQ(env, nullptr, ANI_INVALID_ARGS); \ + } while (false) + // CC-OFFNXT(G.PRE.02) should be with define #define CHECK_ENV(env) \ do { \ - ANI_CHECK_RETURN_IF_EQ(env, nullptr, ANI_INVALID_ARGS); \ + CHECK_ENV_THAT_CAN_HAVE_PENDING_ERROR(env); \ bool hasPendingException = ::ark::ets::PandaEnv::FromAniEnv(env)->HasPendingException(); \ ANI_CHECK_RETURN_IF_EQ(hasPendingException, true, ANI_PENDING_ERROR); \ } while (false) @@ -68,96 +75,6 @@ static inline bool IsUndefined(ani_ref ref) return ManagedCodeAccessor::IsUndefined(ref); } -static inline ani_field ToAniField(EtsField *field) -{ - ASSERT(field != nullptr); - ASSERT(!field->IsStatic()); - return reinterpret_cast(field); -} - -static inline EtsField *ToInternalField(ani_field field) -{ - auto *f = reinterpret_cast(field); - ASSERT(f != nullptr); - ASSERT(!f->IsStatic()); - return f; -} - -static inline ani_static_field ToAniStaticField(EtsField *field) -{ - ASSERT(field != nullptr); - ASSERT(field->IsStatic()); - return reinterpret_cast(field); -} - -[[maybe_unused]] static inline EtsField *ToInternalField(ani_static_field field) -{ - auto *f = reinterpret_cast(field); - ASSERT(f->IsStatic()); - return f; -} - -static inline ani_variable ToAniVariable(EtsVariable *variable) -{ - return reinterpret_cast(variable); -} - -static inline EtsVariable *ToInternalVariable(ani_variable variable) -{ - return reinterpret_cast(variable); -} - -static inline EtsMethod *ToInternalMethod(ani_method method) -{ - auto *m = reinterpret_cast(method); - ASSERT(m != nullptr); - ASSERT(!m->IsStatic()); - ASSERT(!m->IsFunction()); - return m; -} - -static inline ani_method ToAniMethod(EtsMethod *method) -{ - ASSERT(method != nullptr); - ASSERT(!method->IsStatic()); - ASSERT(!method->IsFunction()); - return reinterpret_cast(method); -} - -static inline EtsMethod *ToInternalMethod(ani_static_method method) -{ - auto *m = reinterpret_cast(method); - ASSERT(m != nullptr); - ASSERT(m->IsStatic()); - ASSERT(!m->IsFunction()); - return m; -} - -static inline ani_static_method ToAniStaticMethod(EtsMethod *method) -{ - ASSERT(method != nullptr); - ASSERT(method->IsStatic()); - ASSERT(!method->IsFunction()); - return reinterpret_cast(method); -} - -static inline EtsMethod *ToInternalFunction(ani_function fn) -{ - auto *m = reinterpret_cast(fn); - ASSERT(m != nullptr); - ASSERT(m->IsStatic()); - ASSERT(m->IsFunction()); - return m; -} - -static inline ani_function ToAniFunction(EtsMethod *method) -{ - ASSERT(method != nullptr); - ASSERT(method->IsStatic()); - ASSERT(method->IsFunction()); - return reinterpret_cast(method); -} - static void CheckStaticMethodReturnType(ani_static_method method, EtsType type) { EtsMethod *m = ToInternalMethod(method); @@ -808,30 +725,30 @@ static ani_status DoNewObject(ani_env *env, ani_class cls, ani_method method, an } // NOLINTNEXTLINE(readability-identifier-naming) -NO_UB_SANITIZE static ani_status Object_New_A(ani_env *env, ani_class cls, ani_method method, ani_object *result, +NO_UB_SANITIZE static ani_status Object_New_A(ani_env *env, ani_class cls, ani_method ctor, ani_object *result, const ani_value *args) { ANI_DEBUG_TRACE(env); CHECK_ENV(env); CHECK_PTR_ARG(cls); - CHECK_PTR_ARG(method); + CHECK_PTR_ARG(ctor); CHECK_PTR_ARG(result); CHECK_PTR_ARG(args); - return DoNewObject(env, cls, method, result, args); + return DoNewObject(env, cls, ctor, result, args); } // NOLINTNEXTLINE(readability-identifier-naming) -NO_UB_SANITIZE static ani_status Object_New_V(ani_env *env, ani_class cls, ani_method method, ani_object *result, +NO_UB_SANITIZE static ani_status Object_New_V(ani_env *env, ani_class cls, ani_method ctor, ani_object *result, va_list args) { ANI_DEBUG_TRACE(env); CHECK_ENV(env); CHECK_PTR_ARG(cls); - CHECK_PTR_ARG(method); + CHECK_PTR_ARG(ctor); CHECK_PTR_ARG(result); - return DoNewObject(env, cls, method, result, args); + return DoNewObject(env, cls, ctor, result, args); } // NOLINTNEXTLINE(readability-identifier-naming) @@ -853,11 +770,11 @@ NO_UB_SANITIZE static ani_status Object_GetType(ani_env *env, ani_object object, } // NOLINTNEXTLINE(readability-identifier-naming) -NO_UB_SANITIZE static ani_status Object_New(ani_env *env, ani_class cls, ani_method method, ani_object *result, ...) +NO_UB_SANITIZE static ani_status Object_New(ani_env *env, ani_class cls, ani_method ctor, ani_object *result, ...) { va_list args; // NOLINT(cppcoreguidelines-pro-type-vararg) va_start(args, result); - ani_status status = Object_New_V(env, cls, method, result, args); + ani_status status = Object_New_V(env, cls, ctor, result, args); va_end(args); return status; } @@ -2169,13 +2086,13 @@ NO_UB_SANITIZE static ani_status Class_BindStaticNativeMethods(ani_env *env, ani } // NOLINTNEXTLINE(readability-identifier-naming) -NO_UB_SANITIZE static ani_status Reference_Delete(ani_env *env, ani_ref ref) +NO_UB_SANITIZE static ani_status Reference_Delete(ani_env *env, ani_ref lref) { ANI_DEBUG_TRACE(env); - CHECK_ENV(env); + CHECK_ENV_THAT_CAN_HAVE_PENDING_ERROR(env); ScopedManagedCodeFix s(env); - return s.DelLocalRef(ref); + return s.DelLocalRef(lref); } template diff --git a/static_core/plugins/ets/runtime/ani/ani_options.cpp b/static_core/plugins/ets/runtime/ani/ani_options.cpp index b55856a665..6fc790c898 100644 --- a/static_core/plugins/ets/runtime/ani/ani_options.cpp +++ b/static_core/plugins/ets/runtime/ani/ani_options.cpp @@ -70,6 +70,23 @@ const std::map &ANIOptions::GetOpti }, }, }, + { + "--verify:ani", + { + OptionKey::VERIFY_ANI, + [](std::string_view value, void *extra) -> Expected, std::string> { + if (!value.empty()) { + std::stringstream ss; + ss << "'--verify:ani' option mustn't have value, value='" << value << "'"; + return Unexpected(ss.str()); + } + if (extra != nullptr) { + return Unexpected(std::string("'--verify:ani' option has 'extra != NULL'")); + } + return std::make_unique(OptionValue {true, extra}); + }, + }, + }, #ifdef PANDA_ETS_INTEROP_JS // clang-format off { diff --git a/static_core/plugins/ets/runtime/ani/ani_options.h b/static_core/plugins/ets/runtime/ani/ani_options.h index 940671db2c..756bfed93b 100644 --- a/static_core/plugins/ets/runtime/ani/ani_options.h +++ b/static_core/plugins/ets/runtime/ani/ani_options.h @@ -33,6 +33,7 @@ class ANIOptions final { public: enum class OptionKey { LOGGER, + VERIFY_ANI, #ifdef PANDA_ETS_INTEROP_JS INTEROP, #endif // PANDA_ETS_INTEROP_JS @@ -47,6 +48,12 @@ public: LoggerCallback GetLoggerCallback() const; + bool IsVerifyANI() const + { + const OptionValue *v = GetValue(OptionKey::VERIFY_ANI); + return v != nullptr ? std::get<0>(v->value) : false; + } + #ifdef PANDA_ETS_INTEROP_JS bool IsInteropMode() const { diff --git a/static_core/plugins/ets/runtime/ani/ani_options_parser.cpp b/static_core/plugins/ets/runtime/ani/ani_options_parser.cpp index b8254c79d7..aa14388179 100644 --- a/static_core/plugins/ets/runtime/ani/ani_options_parser.cpp +++ b/static_core/plugins/ets/runtime/ani/ani_options_parser.cpp @@ -17,6 +17,7 @@ #include "compiler/compiler_options.h" #include "plugins/ets/compiler/product_options.h" +#include "plugins/ets/runtime/ets_vm_options.h" #include "plugins/ets/runtime/product_options.h" namespace ark::ets::ani { @@ -122,7 +123,12 @@ OptionsParser::ErrorMsg OptionsParser::Parse(const ani_options *options) } extOptionsMap[op->name] = std::move(op); } - return ParseExtOptions(std::move(extOptionsMap)); + ErrorMsg errorMsg = ParseExtOptions(std::move(extOptionsMap)); + if (errorMsg) { + return errorMsg; + } + PrepareEtsVmOptions(); + return {}; } OptionsParser::ErrorMsg OptionsParser::ParseExtOptions(OptionsMap extOptionsMap) @@ -234,4 +240,9 @@ OptionsParser::ErrorMsg OptionsParser::RunOptionsParser(PandArgParser &parser, c return {}; } +void OptionsParser::PrepareEtsVmOptions() +{ + SetEtsVmOptions(runtimeOptions_, std::make_unique(aniOptions_.IsVerifyANI())); +} + } // namespace ark::ets::ani diff --git a/static_core/plugins/ets/runtime/ani/ani_options_parser.h b/static_core/plugins/ets/runtime/ani/ani_options_parser.h index a8398e0086..1dc92d4f89 100644 --- a/static_core/plugins/ets/runtime/ani/ani_options_parser.h +++ b/static_core/plugins/ets/runtime/ani/ani_options_parser.h @@ -67,6 +67,7 @@ private: ErrorMsg RunCompilerOptionsParser(const std::vector &args); std::unique_ptr