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// NOLINTBEGIN(cppcoreguidelines-avoid-goto) 16// NOLINTNEXTLINE(readability-function-size) 17inline VerificationStatus AbstractInterpret(VerificationContext& verifCtx, const uint8_t* pc, EntryPointType codeType) { 18#if defined(__clang__) 19#pragma clang diagnostic push 20#pragma clang diagnostic ignored "-Wvoid-ptr-dereference" 21#pragma clang diagnostic ignored "-Wgnu-label-as-value" 22#elif defined(__GNUC__) 23#pragma GCC diagnostic push 24#pragma GCC diagnostic ignored "-Wpedantic" 25#endif 26 constexpr std::size_t DISPATCH_TABLE_HANDLER_NAMES_SIZE = <%= Panda::dispatch_table.handler_names.size %>; 27 std::array<const void*, DISPATCH_TABLE_HANDLER_NAMES_SIZE> dispatchTable{ 28% Panda::dispatch_table.handler_names.each do |name| 29 &&HANDLE_<%= name %>, 30% end 31 }; 32 33 AbsIntInstructionHandler handler(verifCtx, pc, codeType); 34 uint8_t secondaryOpcode; 35 36 if (!handler.IsPrimaryOpcodeValid()) { 37 LOG(ERROR, VERIFIER) << "Incorrect opcode"; 38 return VerificationStatus::ERROR; 39 } 40 goto* dispatchTable[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% if i.namespace == 'ecmascript' 49 LOG(ERROR, VERIFIER) << "<%= i.namespace %> verification is not yet supported"; 50 return VerificationStatus::ERROR; 51% else 52 if (!handler.template Handle<%= mnemonic %><BytecodeInstructionSafe::Format::<%= i.format.pretty.upcase %>>()) { 53 return handler.GetStatus(); 54 } 55% end 56 goto COMMON_BODY; 57% if i.namespace != 'core' 58#endif // PANDA_WITH_<%= i.namespace.upcase %> 59% end 60% end 61COMMON_BODY: 62{ 63 if (!handler.IsPrimaryOpcodeValid()) { 64 LOG(ERROR, VERIFIER) << "Incorrect opcode"; 65 return VerificationStatus::ERROR; 66 } 67 goto* dispatchTable[handler.GetPrimaryOpcode()]; 68} 69HANDLE_INVALID: 70 LOG(ERROR, VERIFIER) << "Incorrect opcode"; 71 return VerificationStatus::ERROR; 72% Panda::prefixes.each do |p| 73HANDLE_<%= p.handler_name %>: 74 secondaryOpcode = handler.GetSecondaryOpcode(); 75 LOG(DEBUG, VERIFIER) << "ABSINT: Prefix subdispatch: " << "<%= p.name %>, " << static_cast<int32_t>(secondaryOpcode); 76 // NOLINTNEXTLINE(readability-magic-numbers) 77 if (secondaryOpcode > <%= Panda::dispatch_table.secondary_opcode_bound(p) %> ) { 78 LOG(ERROR, VERIFIER) << "Incorrect opcode"; 79 return VerificationStatus::ERROR; 80 } 81 // NOLINTNEXTLINE(readability-magic-numbers) 82 goto *dispatchTable[<%= Panda::dispatch_table.secondary_opcode_offset(p) %> + secondaryOpcode]; 83% end 84 85#if defined(__clang__) 86#pragma clang diagnostic pop 87#elif defined(__GNUC__) 88#pragma GCC diagnostic pop 89#endif 90} 91 92// NOLINTEND(cppcoreguidelines-avoid-goto) 93