clib: new raw_alloc and register_static_object services
[nit.git] / clib / nit_main.c
1 /* This file is part of NIT ( http://www.nitlanguage.org ).
2 *
3 * Copyright 2006-2009 Jean Privat <jean@pryen.org>
4 *
5 * This file is free software, which comes along with NIT. This software is
6 * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
7 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
8 * PARTICULAR PURPOSE. You can modify it is you want, provided this header
9 * is kept unaltered, and a notification of the changes is added.
10 * You are allowed to redistribute it and sell it, alone or is a part of
11 * another product.
12 */
13
14 #include "nit_common.h"
15 #include <signal.h>
16 #include <stdarg.h>
17
18 bigint object_id_counter = 1000000;
19 enum gc_option { large, boehm } gc_option;
20
21 #ifdef WITH_LIBGC
22 #define GC_DEBUG
23 #include <gc/gc.h>
24 #endif
25
26 void *raw_alloc(size_t s0)
27 {
28 return alloc(s0);
29 }
30
31 void register_static_object(val_t *o)
32 {
33 return;
34 }
35
36 void *large_alloc(size_t s0)
37 {
38 static char * alloc_pos = NULL;
39 static size_t alloc_size = 0;
40 void * res;
41 size_t s = ((s0+3)/4)*4;
42 if(alloc_size < s) {
43 alloc_size = s + 1024*1024;
44 alloc_pos = (char *)calloc(alloc_size, 1);
45 }
46 res = alloc_pos;
47 alloc_size -= s;
48 alloc_pos += s;
49 return res;
50 }
51
52 void * alloc(size_t s0)
53 {
54 switch (gc_option) {
55 #ifdef WITH_LIBGC
56 case boehm: return GC_MALLOC(s0);
57 #endif
58 case large:
59 default: return large_alloc(s0);
60 }
61 }
62
63 int glob_argc;
64 char **glob_argv;
65 val_t G_sys;
66
67 void exithandler(int s) {
68 fprintf(stderr, "Recieved signal %d\n", s);
69 nit_exit(1);
70 }
71 void initialize_gc_option(void) {
72 /* GC default */
73 #ifdef WITH_LIBGC
74 gc_option = boehm;
75 #else
76 gc_option = large;
77 #endif
78
79 /* Process GC runtime selection */
80 if (getenv("NIT_GC_OPTION") != NULL) {
81 char *opt=getenv("NIT_GC_OPTION");
82 if (strcmp(opt, "boehm")==0) {
83 #ifdef WITH_LIBGC
84 gc_option = boehm;
85 #else
86 fprintf(stderr, "Compiled without Boehm GC support. Using default.\n");
87 #endif
88 } else if (strcmp(opt, "large")==0) {
89 gc_option = large;
90 } else {
91 fprintf(stderr, "Invalid GC option in NIT_GC_OPTION environment variable. Using default.\n");
92 }
93 }
94
95 /* Initialize GC (if needed) */
96 switch(gc_option) {
97 #ifdef WITH_LIBGC
98 case boehm: GC_INIT(); break;
99 #endif
100 default: break; /* Nothing */
101 }
102 }
103 void prepare_signals(void) {
104 initialize_gc_option();
105
106 signal(SIGINT,exithandler);
107 signal(SIGABRT,exithandler);
108 signal(SIGSEGV,exithandler);
109 signal(SIGILL, exithandler);
110 signal(SIGFPE, exithandler);
111 signal(SIGTERM,exithandler);
112 signal(SIGBUS, exithandler);
113 }
114 struct trace_t *tracehead = NULL;
115 void nit_exit(int i) {
116 fprintf(stderr, ",---- Stack trace -- - - -\n");
117 while(tracehead != NULL) {
118 fprintf(stderr, "| %s (%s:%d)\n", tracehead->meth, tracehead->file, tracehead->line);
119 if (tracehead == tracehead->prev) break;
120 tracehead = tracehead->prev;
121 }
122 fprintf(stderr, "`------------------- - - -\n");
123 exit(i);
124 }