X-Git-Url: http://nitlanguage.org diff --git a/clib/nit_main.c b/clib/nit_main.c index 6f7daba..9b20edb 100644 --- a/clib/nit_main.c +++ b/clib/nit_main.c @@ -16,6 +16,13 @@ #include #include "gc.h" +#ifdef ANDROID + #include + #define PRINT_ERROR(...) ((void)__android_log_print(ANDROID_LOG_WARN, "nit", __VA_ARGS__)) +#else + #define PRINT_ERROR(...) ((void)fprintf(stderr, __VA_ARGS__)) +#endif + bigint object_id_counter = 1000000; enum gc_option { large, gc_opt_malloc, boehm, nitgc } gc_option; @@ -76,19 +83,14 @@ char **glob_argv; val_t G_sys; void exithandler(int s) { - fprintf(stderr, "Recieved signal %d\n", s); + PRINT_ERROR( "Recieved signal %d\n", s); nit_exit(1); } void initialize_gc_option(void) { /* GC default */ char *def; -#ifdef WITH_LIBGC - gc_option = boehm; - def = "boehm"; -#else gc_option = nitgc; def = "nitgc"; -#endif /* Process GC runtime selection */ if (getenv("NIT_GC_OPTION") != NULL) { @@ -97,7 +99,7 @@ void initialize_gc_option(void) { #ifdef WITH_LIBGC gc_option = boehm; #else - fprintf(stderr, "Compiled without Boehm GC support. Using default '%s'.\n", def); + PRINT_ERROR( "Compiled without Boehm GC support. Using default '%s'.\n", def); #endif } else if (strcmp(opt, "nitgc")==0) { gc_option = nitgc; @@ -106,14 +108,14 @@ void initialize_gc_option(void) { } else if (strcmp(opt, "large")==0) { gc_option = large; } else if (strcmp(opt, "help")==0) { - fprintf(stderr, "NIT_GC_OPTION accepts 'nitgc'" + PRINT_ERROR( "NIT_GC_OPTION accepts 'nitgc'" #ifdef WITH_LIBGC ", 'boehm'" #endif ", 'large', 'malloc'. Default is '%s'.\n", def); exit(1); } else { - fprintf(stderr, "Invalid GC option in NIT_GC_OPTION environment variable. Using default '%s'.\n", def); + PRINT_ERROR( "Invalid GC option in NIT_GC_OPTION environment variable. Using default '%s'.\n", def); } } @@ -125,6 +127,9 @@ void initialize_gc_option(void) { case nitgc: Nit_gc_init(); break; default: break; /* Nothing */ } + + /* Initialize global references list */ + nitni_global_ref_list_init(); } void prepare_signals(void) { initialize_gc_option(); @@ -141,22 +146,23 @@ struct stack_frame_t *stack_frame_head = NULL; void nit_exit(int i) { char *opt=getenv("NIT_NO_STACK"); if (opt == NULL || strcmp(opt, "0")==0) { - fprintf(stderr, ",---- Stack trace -- - - -\n"); + PRINT_ERROR( ",---- Stack trace -- - - -\n"); while(stack_frame_head != NULL) { - fprintf(stderr, "| %s (%s:%d)\n", stack_frame_head->meth, stack_frame_head->file, stack_frame_head->line); + PRINT_ERROR( "| %s (%s:%d)\n", stack_frame_head->meth, stack_frame_head->file, stack_frame_head->line); if (stack_frame_head == stack_frame_head->prev) break; stack_frame_head = stack_frame_head->prev; } - fprintf(stderr, "`------------------- - - -\n"); + PRINT_ERROR( "`------------------- - - -\n"); } exit(i); } void nit_abort(const char* s, const char* msg, const char* loc, int line) { - fprintf(stderr, s, msg); - fprintf(stderr, " (%s", loc); - if (line != 0) fprintf(stderr, ":%d", line); - fprintf(stderr, ")\n"); + PRINT_ERROR( "Runtime error: "); + PRINT_ERROR( s, msg); + PRINT_ERROR( " (%s", loc); + if (line != 0) PRINT_ERROR( ":%d", line); + PRINT_ERROR( ")\n"); nit_exit(1); } @@ -198,7 +204,9 @@ void nitni_local_ref_clean( void ) { while ( link != NULL ) { for ( i = 0; i < link->count; i ++ ) { - free( link->reg[ i ] ); + if ( link->reg[i]->count == 0 ) { /* not registered globally */ + free( link->reg[ i ] ); + } } last_link = link; @@ -212,3 +220,57 @@ void nitni_local_ref_clean( void ) { stack_frame_head->nitni_local_ref_head = NULL; } + +struct nitni_global_ref_list_t *nitni_global_ref_list; +void nitni_global_ref_list_init() { + nitni_global_ref_list = (struct nitni_global_ref_list_t*)malloc(sizeof(struct nitni_global_ref_list_t)); + nitni_global_ref_list->head = NULL; + nitni_global_ref_list->tail = NULL; +} + +void nitni_global_ref_add( struct nitni_ref *ref ) { + if ( nitni_global_ref_list->head == NULL ) { + nitni_global_ref_list->head = ref; + ref->prev = NULL; + } else { + nitni_global_ref_list->tail->next = ref; + ref->prev = nitni_global_ref_list->tail; + } + nitni_global_ref_list->tail = ref; + + ref->next = NULL; +} + +void nitni_global_ref_remove( struct nitni_ref *ref ) { + if ( ref->prev == NULL ) { + nitni_global_ref_list->head = ref->next; + } else { + ref->prev->next = ref->next; + } + + if ( ref->next == NULL ) { + nitni_global_ref_list->tail = ref->prev; + } else { + ref->next->prev = ref->prev; + } +} + +extern void nitni_global_ref_incr( struct nitni_ref *ref ) { + if ( ref->count == 0 ) /* not registered */ + { + /* add to list */ + nitni_global_ref_add( ref ); + } + + ref->count ++; +} + +extern void nitni_global_ref_decr( struct nitni_ref *ref ) { + if ( ref->count == 1 ) /* was last reference */ + { + /* remove from list */ + nitni_global_ref_remove( ref ); + } + + ref->count --; +}