• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16namespace panda::intrinsics {
17
18// Autogenerated file -- DO NOT EDIT!
19% Runtime::intrinsics.select(&:has_impl?).uniq { |intrn| intrn.impl + ", " + intrn.impl_signature.args.count.to_s + ";;" + intrn.private.to_s}.each do |intrinsic|
20%   params = intrinsic.impl_signature.args.each_with_index.map {|cpp_type, index| cpp_type + " " + "arg#{index}" }
21%   params = params.unshift("[[maybe_unused]] Method* /* unused */")
22%   implementation = intrinsic.impl.rpartition("::").last
23%     if intrinsic.private
24#ifndef PANDA_PRODUCT_BUILD
25%     end
26extern "C" <%= intrinsic.impl_signature.ret %> <%= implementation %>BridgeSelectorEntryPoint(<%= params.join(", ") %>);
27// NOLINTNEXTLINE(misc-definitions-in-headers)
28extern "C" <%= intrinsic.impl_signature.ret %> <%= implementation %>CompiledAbi(<%= params.join(", ") %>) {  // NOLINT
29%   nargs = intrinsic.impl_signature.args.size
30%   arg_list = (0...nargs).map { |i| "arg#{i}" }.join(", ")
31%   ret_type = intrinsic.impl_signature.ret
32%   if ret_type == 'void'
33    <%= intrinsic.impl %>(<%= arg_list %>);
34%   else
35    return <%= intrinsic.impl %>(<%= arg_list %>);
36% end
37}
38%     if intrinsic.private
39#endif  // PANDA_PRODUCT_BUILD
40%     end
41
42% end
43
44// NOLINTNEXTLINE(readability-function-size,misc-definitions-in-headers)
45bool Initialize(panda::panda_file::SourceLang vm_lang) {
46    Runtime *runtime = Runtime::GetCurrent();
47    ClassLinker *class_linker = runtime->GetClassLinker();
48    const auto& runtime_options = Runtime::GetOptions();
49
50    if (!runtime_options.ShouldInitializeIntrinsics()) {
51        return true;
52    }
53
54    if (!class_linker->HasExtension(vm_lang)) {
55        // No extension here.
56        return true;
57    }
58
59    ClassLinkerExtension *cle = class_linker->GetExtension(vm_lang);
60
61    auto spaces = runtime_options.GetBootIntrinsicSpaces();
62
63#ifndef PANDA_PRODUCT_BUILD
64    auto blacklist = runtime_options.GetIntrinsicsBlacklist();
65#endif // PANDA_PRODUCT_BUILD
66
67    std::string_view space;
68    for (const auto &space_arg : spaces) {
69        if (runtime->GetLanguageContext(space_arg).GetLanguage() == vm_lang) {
70            space = space_arg;
71            break;
72        }
73    }
74
75    if (space.empty()) {
76        // Current space was disabled in options.
77        return true;
78    }
79
80% Runtime::intrinsics.select(&:has_impl?).each do |intrinsic|
81%     if intrinsic.private
82#ifndef PANDA_PRODUCT_BUILD
83%     end
84    // Init intrinsics only for current vm.
85    if (space == "<%= intrinsic.space %>") {
86        auto mutf8_name = reinterpret_cast<const uint8_t *>("<%= get_object_descriptor(intrinsic.class_name) %>");
87        auto klass = cle->GetClass(mutf8_name);
88        if (klass == nullptr) {
89            LOG(ERROR, RUNTIME) << "Cannot find class '" << mutf8_name << "'";
90            return false;
91        }
92        mutf8_name = reinterpret_cast<const uint8_t *>("<%= intrinsic.method_name %>");
93
94        Method::Proto proto;
95        auto &shorty = proto.GetShorty();
96
97%   types = [intrinsic.signature.ret] + intrinsic.signature.args
98%   types.each do |t|
99        shorty.emplace_back(panda_file::Type::TypeId::<%= get_shorty_type(t) %>);
100%     if object_type?(t)
101        proto.GetRefTypes().emplace_back("<%= get_object_descriptor(t) %>");
102%     end
103%   end
104
105        auto method = klass->GetDirectMethod(mutf8_name, proto);
106        if (method == nullptr) {
107            LOG(ERROR, RUNTIME) << "Cannot find method '<%= intrinsic.class_name %>.<%= intrinsic.method_name %>' in space '<%= intrinsic.space %>'";
108            return false;
109        }
110
111%       method_full_name = intrinsic.class_name + "::" + intrinsic.method_name
112#ifndef PANDA_PRODUCT_BUILD
113        if (!blacklist.empty() && std::find(blacklist.begin(), blacklist.end(), static_cast<const char *>("<%= method_full_name %>")) != blacklist.end()) {
114           LOG(DEBUG, RUNTIME) << "Skipping intrinsic linkage for blacklisted method <%= method_full_name %>";
115        } else {
116#endif // PANDA_PRODUCT_BUILD
117            method->SetIntrinsic(Intrinsic::<%= intrinsic.enum_name %>);
118% if intrinsic.static
119            method->SetCompiledEntryPoint(reinterpret_cast<const void *>(<%= intrinsic.impl.rpartition("::").last + "CompiledAbi" %>));
120% else
121            method->SetCompiledEntryPoint(reinterpret_cast<const void *>(<%= intrinsic.impl.rpartition("::").last + "BridgeSelectorEntryPoint" %>));
122% end
123#ifndef PANDA_PRODUCT_BUILD
124        }
125#endif // PANDA_PRODUCT_BUILD
126    }
127%     if intrinsic.private
128#endif  // PANDA_PRODUCT_BUILD
129%     end
130% end
131    return true;
132}
133
134}  // namespace panda::intrinsics
135
136% Runtime::intrinsics.select(&:has_impl?).uniq { |i| i.impl }.each do |intrinsic|
137%   next if !intrinsic.need_abi_wrapper?
138%   namespace, _, funcname = intrinsic.impl.rpartition('::')
139namespace <%= namespace %> {
140%   params = intrinsic.impl_signature.args.each_with_index.map {|cpp_type, index| cpp_type + " " + "arg#{index}" }
141<%= intrinsic.impl_signature.ret %> <%= funcname %>(<%= params.join(", ") %>) {  // NOLINT
142%   nargs = intrinsic.impl_signature.args.size
143%   arg_list = (0...nargs).map do |i|
144%     if intrinsic.impl_signature.args[i] == intrinsic.orig_impl_signature.args[i]
145%       "arg#{i}"
146%     else
147%       "static_cast<#{intrinsic.orig_impl_signature.args[i]}>(arg#{i})"
148%     end
149%   end
150%   arg_list = arg_list.join(", ")
151%   ret_type = intrinsic.orig_impl_signature.ret
152%   if ret_type == 'void'
153    <%= intrinsic.orig_impl %>(<%= arg_list %>);
154%   else
155    return <%= intrinsic.orig_impl %>(<%= arg_list %>);
156%   end
157}
158}  // namespace <%= namespace %>
159
160% end
161