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