1// -*- c -*- 2// 3// %CopyrightBegin% 4// 5// Copyright Ericsson AB 2020. All Rights Reserved. 6// 7// Licensed under the Apache License, Version 2.0 (the "License"); 8// you may not use this file except in compliance with the License. 9// You may obtain a copy of the License at 10// 11// http://www.apache.org/licenses/LICENSE-2.0 12// 13// Unless required by applicable law or agreed to in writing, software 14// distributed under the License is distributed on an "AS IS" BASIS, 15// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16// See the License for the specific language governing permissions and 17// limitations under the License. 18// 19// %CopyrightEnd% 20// 21 22pred.is_mfa_bif(M, F, A) { 23 Export *e; 24 25 ASSERT(M.type == TAG_a && F.type == TAG_a && A.type == TAG_u); 26 e = erts_active_export_entry(M.val, F.val, A.val); 27 28 if (e != NULL) { 29 return e->bif_number != -1; 30 } 31 32 return 0; 33} 34 35pred.needs_nif_padding() { 36 /* If the module may load a NIF all functions must be able to hold a NIF 37 * stub, so we'll pad to that size at the end of every function. */ 38 return S->may_load_nif; 39} 40 41pred.never_fails(Bif) { 42 static Eterm nofail_bifs[] = 43 {am_Neqeq, 44 am_Le, 45 am_Neq, 46 am_Eq, 47 am_Le, 48 am_Eqeq, 49 am_Gt, 50 am_Ge, 51 am_is_atom, 52 am_is_boolean, 53 am_is_binary, 54 am_is_bitstring, 55 am_is_float, 56 am_is_integer, 57 am_is_list, 58 am_is_map, 59 am_is_number, 60 am_is_pid, 61 am_is_port, 62 am_is_reference, 63 am_is_tuple, 64 }; 65 66 Uint index = Bif.val; 67 68 if (Bif.type == TAG_u && index < S->beam.imports.count) { 69 BeamFile_ImportEntry *entry = &S->beam.imports.entries[index]; 70 int i; 71 72 if (entry->module != am_erlang) { 73 return 0; 74 } 75 76 if (entry->function == am_is_function) { 77 /* Note that is_function/2 may fail. */ 78 return entry->arity == 1; 79 } 80 81 for (i = 0; i < sizeof(nofail_bifs) / sizeof(nofail_bifs[0]); i++) { 82 if (entry->function == nofail_bifs[i]) { 83 return 1; 84 } 85 } 86 } 87 return 0; 88} 89 90pred.is_eq_exact_bif(Bif) { 91 Uint index = Bif.val; 92 93 if (Bif.type == TAG_u && index < S->beam.imports.count) { 94 BeamFile_ImportEntry *entry = &S->beam.imports.entries[index]; 95 96 return entry->module == am_erlang && entry->function == am_Eq && entry->arity == 2; 97 } 98 return 0; 99} 100 101pred.is_ne_exact_bif(Bif) { 102 Uint index = Bif.val; 103 104 if (Bif.type == TAG_u && index < S->beam.imports.count) { 105 BeamFile_ImportEntry *entry = &S->beam.imports.entries[index]; 106 107 return entry->module == am_erlang && entry->function == am_Neq && entry->arity == 2; 108 } 109 return 0; 110} 111 112pred.consecutive_words(S1, D1, S2, D2) { 113 return S1.type == S2.type && S1.val + 1 == S2.val && 114 D1.type == D2.type && D1.val + 1 == D2.val; 115} 116