]> git.lizzy.rs Git - rust.git/blob - src/rt/rust_builtin.c
debuginfo: Make debuginfo source location assignment more stable (Pt. 1)
[rust.git] / src / rt / rust_builtin.c
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #include <stdint.h>
12 #include <time.h>
13 #include <string.h>
14 #include <assert.h>
15 #include <stdlib.h>
16
17 #if !defined(__WIN32__)
18 #include <sys/time.h>
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <signal.h>
22 #include <unistd.h>
23 #include <pthread.h>
24 #else
25 #include <windows.h>
26 #include <wincrypt.h>
27 #include <stdio.h>
28 #include <tchar.h>
29 #endif
30
31 #ifdef __APPLE__
32 #include <TargetConditionals.h>
33 #include <mach/mach_time.h>
34
35 #if !(TARGET_OS_IPHONE)
36 #include <crt_externs.h>
37 #endif
38 #endif
39
40 /* Foreign builtins. */
41 //include valgrind.h after stdint.h so that uintptr_t is defined for msys2 w64
42 #include "valgrind/valgrind.h"
43
44 #ifdef __ANDROID__
45 time_t
46 timegm(struct tm *tm)
47 {
48     time_t ret;
49     char *tz;
50
51     tz = getenv("TZ");
52     if (tz)
53         tz = strdup(tz);
54     setenv("TZ", "", 1);
55     tzset();
56     ret = mktime(tm);
57     if (tz) {
58         setenv("TZ", tz, 1);
59         free(tz);
60     } else
61         unsetenv("TZ");
62     tzset();
63     return ret;
64 }
65 #endif
66
67 #ifdef __APPLE__
68 #if (TARGET_OS_IPHONE)
69 extern char **environ;
70 #endif
71 #endif
72
73 #if defined(__FreeBSD__) || defined(__linux__) || defined(__ANDROID__) || defined(__DragonFly__)
74 extern char **environ;
75 #endif
76
77 #if defined(__WIN32__)
78 char**
79 rust_env_pairs() {
80     return 0;
81 }
82 #else
83 char**
84 rust_env_pairs() {
85 #if defined(__APPLE__) && !(TARGET_OS_IPHONE)
86     char **environ = *_NSGetEnviron();
87 #endif
88     return environ;
89 }
90 #endif
91
92 char*
93 #if defined(__WIN32__)
94 rust_list_dir_val(WIN32_FIND_DATA* entry_ptr) {
95     return entry_ptr->cFileName;
96 }
97 #else
98 rust_list_dir_val(struct dirent* entry_ptr) {
99     return entry_ptr->d_name;
100 }
101 #endif
102
103 typedef struct {
104     int32_t tm_sec;
105     int32_t tm_min;
106     int32_t tm_hour;
107     int32_t tm_mday;
108     int32_t tm_mon;
109     int32_t tm_year;
110     int32_t tm_wday;
111     int32_t tm_yday;
112     int32_t tm_isdst;
113     int32_t tm_gmtoff;
114     int32_t tm_nsec;
115 } rust_tm;
116
117 void rust_tm_to_tm(rust_tm* in_tm, struct tm* out_tm) {
118     memset(out_tm, 0, sizeof(struct tm));
119     out_tm->tm_sec = in_tm->tm_sec;
120     out_tm->tm_min = in_tm->tm_min;
121     out_tm->tm_hour = in_tm->tm_hour;
122     out_tm->tm_mday = in_tm->tm_mday;
123     out_tm->tm_mon = in_tm->tm_mon;
124     out_tm->tm_year = in_tm->tm_year;
125     out_tm->tm_wday = in_tm->tm_wday;
126     out_tm->tm_yday = in_tm->tm_yday;
127     out_tm->tm_isdst = in_tm->tm_isdst;
128 }
129
130 void tm_to_rust_tm(struct tm* in_tm,
131                    rust_tm* out_tm,
132                    int32_t gmtoff,
133                    int32_t nsec) {
134     out_tm->tm_sec = in_tm->tm_sec;
135     out_tm->tm_min = in_tm->tm_min;
136     out_tm->tm_hour = in_tm->tm_hour;
137     out_tm->tm_mday = in_tm->tm_mday;
138     out_tm->tm_mon = in_tm->tm_mon;
139     out_tm->tm_year = in_tm->tm_year;
140     out_tm->tm_wday = in_tm->tm_wday;
141     out_tm->tm_yday = in_tm->tm_yday;
142     out_tm->tm_isdst = in_tm->tm_isdst;
143     out_tm->tm_gmtoff = gmtoff;
144     out_tm->tm_nsec = nsec;
145 }
146
147 #if defined(__WIN32__)
148 #define TZSET() _tzset()
149 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
150 #define GMTIME(clock, result) gmtime_s((result), (clock))
151 #define LOCALTIME(clock, result) localtime_s((result), (clock))
152 #define TIMEGM(result) _mkgmtime64(result)
153 #else
154 struct tm* GMTIME(const time_t *clock, struct tm *result) {
155     struct tm* t = gmtime(clock);
156     if (t == NULL || result == NULL) { return NULL; }
157     *result = *t;
158     return result;
159 }
160 struct tm* LOCALTIME(const time_t *clock, struct tm *result) {
161     struct tm* t = localtime(clock);
162     if (t == NULL || result == NULL) { return NULL; }
163     *result = *t;
164     return result;
165 }
166 #define TIMEGM(result) mktime((result)) - _timezone
167 #endif
168 #else
169 #define TZSET() tzset()
170 #define GMTIME(clock, result) gmtime_r((clock), (result))
171 #define LOCALTIME(clock, result) localtime_r((clock), (result))
172 #define TIMEGM(result) timegm(result)
173 #endif
174
175 void
176 rust_tzset() {
177     TZSET();
178 }
179
180 void
181 rust_gmtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
182     struct tm tm;
183     time_t s = sec;
184     GMTIME(&s, &tm);
185
186     tm_to_rust_tm(&tm, timeptr, 0, nsec);
187 }
188
189 void
190 rust_localtime(int64_t sec, int32_t nsec, rust_tm *timeptr) {
191     struct tm tm;
192     time_t s = sec;
193     LOCALTIME(&s, &tm);
194
195 #if defined(__WIN32__)
196     int32_t gmtoff = -timezone;
197 #else
198     int32_t gmtoff = tm.tm_gmtoff;
199 #endif
200
201     tm_to_rust_tm(&tm, timeptr, gmtoff, nsec);
202 }
203
204 int64_t
205 rust_timegm(rust_tm* timeptr) {
206     struct tm t;
207     rust_tm_to_tm(timeptr, &t);
208     return TIMEGM(&t);
209 }
210
211 int64_t
212 rust_mktime(rust_tm* timeptr) {
213     struct tm t;
214     rust_tm_to_tm(timeptr, &t);
215     return mktime(&t);
216 }
217
218 #ifndef _WIN32
219
220 DIR*
221 rust_opendir(char *dirname) {
222     return opendir(dirname);
223 }
224
225 int
226 rust_readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
227     return readdir_r(dirp, entry, result);
228 }
229
230 int
231 rust_dirent_t_size() {
232     return sizeof(struct dirent);
233 }
234
235 #else
236
237 void
238 rust_opendir() {
239 }
240
241 void
242 rust_readdir() {
243 }
244
245 void
246 rust_dirent_t_size() {
247 }
248
249 #endif
250
251 uintptr_t
252 rust_running_on_valgrind() {
253     return RUNNING_ON_VALGRIND;
254 }
255
256 #if defined(__WIN32__)
257 int
258 get_num_cpus() {
259     SYSTEM_INFO sysinfo;
260     GetSystemInfo(&sysinfo);
261
262     return (int) sysinfo.dwNumberOfProcessors;
263 }
264 #elif defined(__BSD__)
265 int
266 get_num_cpus() {
267     /* swiped from http://stackoverflow.com/questions/150355/
268        programmatically-find-the-number-of-cores-on-a-machine */
269
270     unsigned int numCPU;
271     int mib[4];
272     size_t len = sizeof(numCPU);
273
274     /* set the mib for hw.ncpu */
275     mib[0] = CTL_HW;
276     mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
277
278     /* get the number of CPUs from the system */
279     sysctl(mib, 2, &numCPU, &len, NULL, 0);
280
281     if( numCPU < 1 ) {
282         mib[1] = HW_NCPU;
283         sysctl( mib, 2, &numCPU, &len, NULL, 0 );
284
285         if( numCPU < 1 ) {
286             numCPU = 1;
287         }
288     }
289     return numCPU;
290 }
291 #elif defined(__GNUC__)
292 int
293 get_num_cpus() {
294     return sysconf(_SC_NPROCESSORS_ONLN);
295 }
296 #endif
297
298 uintptr_t
299 rust_get_num_cpus() {
300     return get_num_cpus();
301 }
302
303 unsigned int
304 rust_valgrind_stack_register(void *start, void *end) {
305   return VALGRIND_STACK_REGISTER(start, end);
306 }
307
308 void
309 rust_valgrind_stack_deregister(unsigned int id) {
310   VALGRIND_STACK_DEREGISTER(id);
311 }
312
313 #if defined(__WIN32__)
314
315 void
316 rust_unset_sigprocmask() {
317     // empty stub for windows to keep linker happy
318 }
319
320 #else
321
322 void
323 rust_unset_sigprocmask() {
324     // this can't be safely converted to rust code because the
325     // representation of sigset_t is platform-dependent
326     sigset_t sset;
327     sigemptyset(&sset);
328     sigprocmask(SIG_SETMASK, &sset, NULL);
329 }
330
331 #endif
332
333 #if defined(__DragonFly__)
334 #include <errno.h>
335 // In DragonFly __error() is an inline function and as such
336 // no symbol exists for it.
337 int *__dfly_error(void) { return __error(); }
338 #endif
339
340 //
341 // Local Variables:
342 // mode: C++
343 // fill-column: 78;
344 // indent-tabs-mode: nil
345 // c-basic-offset: 4
346 // buffer-file-coding-system: utf-8-unix
347 // End:
348 //