1 /*
2  * %CopyrightBegin%
3  *
4  * Copyright Ericsson AB 2009-2017. All Rights Reserved.
5  *
6  * The contents of this file are subject to the Erlang Public License,
7  * Version 1.1, (the "License"); you may not use this file except in
8  * compliance with the License. You should have received a copy of the
9  * Erlang Public License along with this software. If not, it can be
10  * retrieved online at http://www.erlang.org/.
11  *
12  * Software distributed under the License is distributed on an "AS IS"
13  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14  * the License for the specific language governing rights and limitations
15  * under the License.
16  *
17  * %CopyrightEnd%
18  */
19 
20 /* Include file for writers of Native Implemented Functions.
21 */
22 
23 #ifndef __ERL_NIF_H__
24 #define __ERL_NIF_H__
25 
26 
27 #include "erl_drv_nif.h"
28 
29 /* Version history:
30 ** 0.1: R13B03
31 ** 1.0: R13B04
32 ** 2.0: R14A
33 ** 2.1: R14B02 "vm_variant"
34 ** 2.2: R14B03 enif_is_exception
35 ** 2.3: R15 enif_make_reverse_list, enif_is_number
36 ** 2.4: R16 enif_consume_timeslice
37 */
38 #define ERL_NIF_MAJOR_VERSION 2
39 #define ERL_NIF_MINOR_VERSION 4
40 
41 #include <stdlib.h>
42 
43 #ifdef SIZEOF_CHAR
44 #  define SIZEOF_CHAR_SAVED__ SIZEOF_CHAR
45 #  undef SIZEOF_CHAR
46 #endif
47 #ifdef SIZEOF_SHORT
48 #  define SIZEOF_SHORT_SAVED__ SIZEOF_SHORT
49 #  undef SIZEOF_SHORT
50 #endif
51 #ifdef SIZEOF_INT
52 #  define SIZEOF_INT_SAVED__ SIZEOF_INT
53 #  undef SIZEOF_INT
54 #endif
55 #ifdef SIZEOF_LONG
56 #  define SIZEOF_LONG_SAVED__ SIZEOF_LONG
57 #  undef SIZEOF_LONG
58 #endif
59 #ifdef SIZEOF_LONG_LONG
60 #  define SIZEOF_LONG_LONG_SAVED__ SIZEOF_LONG_LONG
61 #  undef SIZEOF_LONG_LONG
62 #endif
63 #ifdef HALFWORD_HEAP_EMULATOR
64 #  define HALFWORD_HEAP_EMULATOR_SAVED__ HALFWORD_HEAP_EMULATOR
65 #  undef HALFWORD_HEAP_EMULATOR
66 #endif
67 #include "erl_int_sizes_config.h"
68 
69 #ifdef __cplusplus
70 extern "C" {
71 #endif
72 
73 #if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
74 typedef unsigned __int64 ErlNifUInt64;
75 typedef __int64 ErlNifSInt64;
76 #elif SIZEOF_LONG == 8
77 typedef unsigned long ErlNifUInt64;
78 typedef long ErlNifSInt64;
79 #elif SIZEOF_LONG_LONG == 8
80 typedef unsigned long long ErlNifUInt64;
81 typedef long long ErlNifSInt64;
82 #else
83 #error No 64-bit integer type
84 #endif
85 
86 #ifdef HALFWORD_HEAP_EMULATOR
87 #  define ERL_NIF_VM_VARIANT "beam.halfword"
88 typedef unsigned int ERL_NIF_TERM;
89 #else
90 #  define ERL_NIF_VM_VARIANT "beam.vanilla"
91 #  if SIZEOF_LONG == SIZEOF_VOID_P
92 typedef unsigned long ERL_NIF_TERM;
93 #  elif SIZEOF_LONG_LONG == SIZEOF_VOID_P
94 typedef unsigned long long ERL_NIF_TERM;
95 #  endif
96 #endif
97 
98 struct enif_environment_t;
99 typedef struct enif_environment_t ErlNifEnv;
100 
101 typedef struct
102 {
103     const char* name;
104     unsigned arity;
105     ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
106 }ErlNifFunc;
107 
108 typedef struct enif_entry_t
109 {
110     int major;
111     int minor;
112     const char* name;
113     int num_of_funcs;
114     ErlNifFunc* funcs;
115     int  (*load)   (ErlNifEnv*, void** priv_data, ERL_NIF_TERM load_info);
116     int  (*reload) (ErlNifEnv*, void** priv_data, ERL_NIF_TERM load_info);
117     int  (*upgrade)(ErlNifEnv*, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info);
118     void (*unload) (ErlNifEnv*, void* priv_data);
119     const char* vm_variant;
120 }ErlNifEntry;
121 
122 
123 
124 typedef struct
125 {
126     size_t size;
127     unsigned char* data;
128 
129     /* Internals (avert your eyes) */
130     ERL_NIF_TERM bin_term;
131     void* ref_bin;
132 }ErlNifBinary;
133 
134 typedef struct enif_resource_type_t ErlNifResourceType;
135 typedef void ErlNifResourceDtor(ErlNifEnv*, void*);
136 typedef enum
137 {
138     ERL_NIF_RT_CREATE = 1,
139     ERL_NIF_RT_TAKEOVER = 2
140 }ErlNifResourceFlags;
141 
142 typedef enum
143 {
144     ERL_NIF_LATIN1 = 1
145 }ErlNifCharEncoding;
146 
147 typedef struct
148 {
149     ERL_NIF_TERM pid;  /* internal, may change */
150 }ErlNifPid;
151 
152 typedef ErlDrvSysInfo ErlNifSysInfo;
153 
154 typedef struct ErlDrvTid_ *ErlNifTid;
155 typedef struct ErlDrvMutex_ ErlNifMutex;
156 typedef struct ErlDrvCond_ ErlNifCond;
157 typedef struct ErlDrvRWLock_ ErlNifRWLock;
158 typedef int ErlNifTSDKey;
159 
160 typedef ErlDrvThreadOpts ErlNifThreadOpts;
161 
162 #if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
163 #  define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) RET_TYPE (*NAME) ARGS
164 typedef struct {
165 #  include "erl_nif_api_funcs.h"
166 } TWinDynNifCallbacks;
167 extern TWinDynNifCallbacks WinDynNifCallbacks;
168 #  undef ERL_NIF_API_FUNC_DECL
169 #endif
170 
171 #if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_)) && !defined(STATIC_ERLANG_DRIVER)
172 #  define ERL_NIF_API_FUNC_MACRO(NAME) (WinDynNifCallbacks.NAME)
173 #  include "erl_nif_api_funcs.h"
174 /* note that we have to keep ERL_NIF_API_FUNC_MACRO defined */
175 
176 #else /* non windows or included from emulator itself */
177 
178 #  define ERL_NIF_API_FUNC_DECL(RET_TYPE, NAME, ARGS) extern RET_TYPE NAME ARGS
179 #  include "erl_nif_api_funcs.h"
180 #  undef ERL_NIF_API_FUNC_DECL
181 #endif
182 
183 
184 #if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
185 #  define ERL_NIF_INIT_GLOB TWinDynNifCallbacks WinDynNifCallbacks;
186 #  define ERL_NIF_INIT_DECL(MODNAME) __declspec(dllexport) ErlNifEntry* nif_init(TWinDynNifCallbacks* callbacks)
187 #  define ERL_NIF_INIT_BODY memcpy(&WinDynNifCallbacks,callbacks,sizeof(TWinDynNifCallbacks))
188 #else
189 #  define ERL_NIF_INIT_GLOB
190 #  define ERL_NIF_INIT_BODY
191 #  define ERL_NIF_INIT_DECL(MODNAME) ErlNifEntry* nif_init(void)
192 #endif
193 
194 
195 #ifdef __cplusplus
196 }
197 #  define ERL_NIF_INIT_PROLOGUE extern "C" {
198 #  define ERL_NIF_INIT_EPILOGUE }
199 #else
200 #  define ERL_NIF_INIT_PROLOGUE
201 #  define ERL_NIF_INIT_EPILOGUE
202 #endif
203 
204 
205 #define ERL_NIF_INIT(NAME, FUNCS, LOAD, RELOAD, UPGRADE, UNLOAD) \
206 ERL_NIF_INIT_PROLOGUE                   \
207 ERL_NIF_INIT_GLOB                       \
208 ERL_NIF_INIT_DECL(NAME);		\
209 ERL_NIF_INIT_DECL(NAME)			\
210 {					\
211     static ErlNifEntry entry = 		\
212     {					\
213 	ERL_NIF_MAJOR_VERSION,		\
214 	ERL_NIF_MINOR_VERSION,		\
215 	#NAME,				\
216 	sizeof(FUNCS) / sizeof(*FUNCS),	\
217 	FUNCS,				\
218 	LOAD, RELOAD, UPGRADE, UNLOAD,	\
219 	ERL_NIF_VM_VARIANT		\
220     };                                  \
221     ERL_NIF_INIT_BODY;                  \
222     return &entry;			\
223 }                                       \
224 ERL_NIF_INIT_EPILOGUE
225 
226 #if defined(USE_DYNAMIC_TRACE) && (defined(USE_DTRACE) || defined(USE_SYSTEMTAP))
227 #define HAVE_USE_DTRACE 1
228 #endif
229 
230 #ifdef HAVE_USE_DTRACE
231 ERL_NIF_TERM erl_nif_user_trace_s1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
232 ERL_NIF_TERM erl_nif_user_trace_i4s4(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
233 ERL_NIF_TERM erl_nif_user_trace_n(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
234 #endif
235 
236 #endif /* __ERL_NIF_H__ */
237 
238