/* * Copyright (c) 2021 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_RUNTIME_INCLUDE_INTRINSICS_GEN_H_ #define PANDA_RUNTIME_INCLUDE_INTRINSICS_GEN_H_ namespace panda::intrinsics { // Autogenerated file -- DO NOT EDIT! % Runtime::intrinsics.each do |intrinsic| % params = intrinsic.impl_signature.args.each_with_index.map {|cpp_type, index| cpp_type + " " + "arg#{index}" } % params = params.unshift("[[maybe_unused]] Method* /* unused */") % entrypoint = intrinsic.name + "EntryPoint" % if intrinsic.private == true #ifndef PANDA_PRODUCT_BUILD % end // NOLINTNEXTLINE(misc-definitions-in-headers) <%= intrinsic.impl_signature.ret %> <%= entrypoint %>(<%= params.join(", ") %>) { // NOLINT % nargs = intrinsic.impl_signature.args.size % arg_list = (0...nargs).map { |i| "arg#{i}" }.join(", ") % ret_type = intrinsic.impl_signature.ret % if ret_type == 'void' <%= intrinsic.impl %>(<%= arg_list %>); % else return <%= intrinsic.impl %>(<%= arg_list %>); % end } % if intrinsic.private == true #endif // PANDA_PRODUCT_BUILD % end % end // NOLINTNEXTLINE(readability-function-size,misc-definitions-in-headers) bool Initialize() { Runtime *runtime = Runtime::GetCurrent(); ClassLinker *class_linker = runtime->GetClassLinker(); auto spaces = Runtime::GetOptions().GetBootIntrinsicSpaces(); std::string_view space; % Runtime::intrinsics.each do |intrinsic| % if intrinsic.private == true #ifndef PANDA_PRODUCT_BUILD % end space = std::string_view("<%= intrinsic.space %>"); if (std::find(spaces.begin(), spaces.end(), space) != spaces.end()) { auto ctx = runtime->GetLanguageContext(std::string(space)); auto mutf8_name = reinterpret_cast("<%= get_object_descriptor(intrinsic.class_name) %>"); auto klass = class_linker->GetExtension(ctx)->GetClass(mutf8_name); if (klass == nullptr) { LOG(ERROR, RUNTIME) << "Cannot find class '" << mutf8_name << "'"; return false; } mutf8_name = reinterpret_cast("<%= intrinsic.method_name %>"); PandaVector shorty; PandaVector ref_types; % types = [intrinsic.signature.ret] + intrinsic.signature.args % types.each do |t| shorty.emplace_back(panda_file::Type::TypeId::<%= get_shorty_type(t) %>); % if object_type?(t) ref_types.emplace_back("<%= get_object_descriptor(t) %>"); % end % end auto proto = Method::Proto(shorty, ref_types); auto method = klass->GetDirectMethod(mutf8_name, proto); if (method == nullptr) { LOG(ERROR, RUNTIME) << "Cannot find method '<%= intrinsic.class_name %>.<%= intrinsic.method_name %>' in space '<%= intrinsic.space %>'"; return false; } method->SetIntrinsic(Intrinsic::<%= intrinsic.enum_name %>); % entrypoint = intrinsic.name + "EntryPoint" method->SetCompiledEntryPoint(reinterpret_cast(<%= entrypoint %>)); } % if intrinsic.private == true #endif // PANDA_PRODUCT_BUILD % end % end return true; } } // namespace panda::intrinsics % Runtime::intrinsics.uniq { |i| i.impl }.each do |intrinsic| % next if !intrinsic.need_abi_wrapper? % namespace, _, funcname = intrinsic.impl.rpartition('::') namespace <%= namespace %> { % params = intrinsic.impl_signature.args.each_with_index.map {|cpp_type, index| cpp_type + " " + "arg#{index}" } <%= intrinsic.impl_signature.ret %> <%= funcname %>(<%= params.join(", ") %>) { // NOLINT % nargs = intrinsic.impl_signature.args.size % arg_list = (0...nargs).map do |i| % if intrinsic.impl_signature.args[i] == intrinsic.orig_impl_signature.args[i] % "arg#{i}" % else % "static_cast<#{intrinsic.orig_impl_signature.args[i]}>(arg#{i})" % end % end % arg_list = arg_list.join(", ") % ret_type = intrinsic.orig_impl_signature.ret % if ret_type == 'void' <%= intrinsic.orig_impl %>(<%= arg_list %>); % else return <%= intrinsic.orig_impl %>(<%= arg_list %>); % end } } // namespace <%= namespace %> % end #endif // PANDA_RUNTIME_INCLUDE_INTRINSICS_GEN_H_