• 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
16// NOLINTNEXTLINE(readability-function-size)
17
18VerificationStatus AbstractInterpret(VerificationContext& verif_ctx, const uint8_t* pc, EntryPointType code_type) {
19#if defined(__clang__)
20#pragma clang diagnostic push
21#pragma clang diagnostic ignored "-Wvoid-ptr-dereference"
22#pragma clang diagnostic ignored "-Wgnu-label-as-value"
23#elif defined(__GNUC__)
24#pragma GCC diagnostic push
25#pragma GCC diagnostic ignored "-Wpedantic"
26#endif
27    std::array<const void*, <%= Panda::dispatch_table.handler_names.size %>> dispatch_table{
28% Panda::dispatch_table.handler_names.each do |name|
29        &&HANDLE_<%= name %>,
30% end
31    };
32
33    AbsIntInstructionHandler handler(verif_ctx, pc, code_type);
34    uint8_t secondary_opcode;
35
36    if (!handler.IsPrimaryOpcodeValid()) {
37        LOG(ERROR, VERIFIER) << "Incorrect opcode";
38        return VerificationStatus::ERROR;
39    }
40    goto* dispatch_table[handler.GetPrimaryOpcode()];
41
42% Panda::instructions.each do |i|
43%   mnemonic = i.mnemonic.split('.').map { |p| p == '64' ? 'Wide' : p.capitalize }.join
44HANDLE_<%= i.handler_name %>:
45% if i.namespace != 'core'
46#ifdef PANDA_WITH_<%= i.namespace.upcase %>
47% end
48% unless i.namespace == 'ecmascript'
49    if (!handler.template Handle<%= mnemonic %><BytecodeInstructionSafe::Format::<%= i.format.pretty.upcase %>>()) {
50        return handler.GetStatus();
51    }
52% end
53
54    if (!handler.IsPrimaryOpcodeValid()) {
55        LOG(ERROR, VERIFIER) << "Incorrect opcode";
56        return VerificationStatus::ERROR;
57    }
58% if i.namespace != 'core'
59#endif // PANDA_WITH_<%= i.namespace.upcase %>
60% end
61    goto* dispatch_table[handler.GetPrimaryOpcode()];
62% end
63HANDLE_INVALID:
64    LOG(ERROR, VERIFIER) << "Incorrect opcode";
65    return VerificationStatus::ERROR;
66% Panda::prefixes.each do |p|
67HANDLE_<%= p.handler_name %>:
68    secondary_opcode = handler.GetSecondaryOpcode();
69    LOG(DEBUG, VERIFIER) << "CFLOW: Prefix subdispatch: " << "<%= p.name %>, " << static_cast<int32_t>(secondary_opcode);
70
71    if (secondary_opcode > <%= Panda::dispatch_table.secondary_opcode_bound(p) %> ) {
72        LOG(ERROR, VERIFIER) << "Incorrect opcode";
73        return VerificationStatus::ERROR;
74    }
75    goto *dispatch_table[<%= Panda::dispatch_table.secondary_opcode_offset(p) %> + secondary_opcode];
76% end
77
78#if defined(__clang__)
79#pragma clang diagnostic pop
80#elif defined(__GNUC__)
81#pragma GCC diagnostic pop
82#endif
83}
84