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