⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 runtime.c

📁 Scheme跨平台编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
  p = (C_byte *)mmap (NULL, size, (PROT_READ | PROT_WRITE),                      (MAP_PRIVATE | MAP_ANON), -1, 0);  if (p != NULL && page_aligned) *page_aligned = p;#else  p = (C_byte *)C_malloc (size + page_size);  if (p != NULL && page_aligned) *page_aligned = align_to_page (p);#endif  /* . */  return p;}static voidheap_free (C_byte *ptr, size_t size){#ifdef C_LOCK_TOSPACE  int r = munmap (ptr, size);  assert (r == 0);#else  C_free (ptr);#endif  /* . */}static C_byte *heap_realloc (C_byte *ptr, size_t old_size,	      size_t new_size, C_byte **page_aligned){  C_byte *p;#ifdef C_LOCK_TOSPACE  p = (C_byte *)mmap (NULL, new_size, (PROT_READ | PROT_WRITE),                      (MAP_PRIVATE | MAP_ANON), -1, 0);  if (ptr != NULL) {    memcpy (p, ptr, old_size);    heap_free (ptr, old_size);  }  if (p != NULL && page_aligned) *page_aligned = p;#else  p = (C_byte *)C_realloc (ptr, new_size + page_size);  if (p != NULL && page_aligned) *page_aligned = align_to_page (p);#endif  /* . */  return p;}/* Modify heap size at runtime: */void C_set_or_change_heap_size(C_word heap, int reintern){  C_byte *ptr1, *ptr2, *ptr1a, *ptr2a;  C_word size = heap / 2;  if(heap_size_changed && fromspace_start) return;  if(fromspace_start && heap_size >= heap) return;  if(debug_mode) C_printf(C_text("[debug] heap resized to %d bytes\n"), (int)heap);  heap_size = heap;  if((ptr1 = heap_realloc (fromspace_start,			   C_fromspace_limit - fromspace_start,			   size, &ptr1a)) == NULL ||     (ptr2 = heap_realloc (tospace_start,			   tospace_limit - tospace_start,			   size, &ptr2a)) == NULL)    panic(C_text("out of memory - can not allocate heap"));  heapspace1 = ptr1, heapspace1_size = size;  heapspace2 = ptr2, heapspace2_size = size;  fromspace_start = ptr1a;  C_fromspace_top = fromspace_start;  C_fromspace_limit = fromspace_start + size;  tospace_start = ptr2a;  tospace_top = tospace_start;  tospace_limit = tospace_start + size;  mutation_stack_top = mutation_stack_bottom;  lock_tospace(1);  if(reintern) initialize_symbol_table();} /* Modify stack-size at runtime: */void C_do_resize_stack(C_word stack){  C_uword old = stack_size,          diff = stack - old;  if(diff != 0 && !stack_size_changed) {    if(debug_mode) C_printf(C_text("[debug] stack resized to %d bytes\n"), (int)stack);    stack_size = stack;#if C_STACK_GROWS_DOWNWARD    C_stack_limit = (C_word *)((C_byte *)C_stack_limit - diff);#else    C_stack_limit = (C_word *)((C_byte *)C_stack_limit + diff);#endif  }}/* Check whether nursery is sufficiently big: */void C_check_nursery_minimum(C_word words){  if(words >= C_bytestowords(stack_size))    panic(C_text("nursery is too small - try higher setting using the `-:s' option"));}C_word C_resize_pending_finalizers(C_word size) {  int sz = C_num_to_int(size);  FINALIZER_NODE **newmem =     (FINALIZER_NODE **)C_realloc(pending_finalizer_indices, sz * sizeof(FINALIZER_NODE *));    if (newmem == NULL)    return C_SCHEME_FALSE;  pending_finalizer_indices = newmem;  C_max_pending_finalizers = sz;  return C_SCHEME_TRUE;}/* Parse runtime options from command-line: */void CHICKEN_parse_command_line(int argc, char *argv[], C_word *heap, C_word *stack, C_word *symbols){  int i;  char *ptr;  C_word x;  C_main_argc = argc;  C_main_argv = argv;  *heap = DEFAULT_HEAP_SIZE;  *stack = DEFAULT_STACK_SIZE;  *symbols = DEFAULT_SYMBOL_TABLE_SIZE;  for(i = 1; i < C_main_argc; ++i)    if(!strncmp(C_main_argv[ i ], C_text("-:"), 2)) {      for(ptr = &C_main_argv[ i ][ 2 ]; *ptr != '\0';) {	switch(*(ptr++)) {	case '?':	  C_printf("\nRuntime options:\n\n"		 " -:?              display this text\n"		 " -:c              always treat stdin as console\n"		 " -:d              enable debug output\n"		 " -:D              enable more debug output\n"		 " -:o              disable stack overflow checks\n"		 " -:hiSIZE         set initial heap size\n"		 " -:hmSIZE         set maximal heap size\n"		 " -:hgPERCENTAGE   set heap growth percentage\n"		 " -:hsPERCENTAGE   set heap shrink percentage\n"		 " -:hSIZE          set fixed heap size\n"		 " -:r              write trace output to stderr\n"		 " -:sSIZE          set nursery (stack) size\n"		 " -:tSIZE          set symbol-table size\n"                 " -:fSIZE          set maximal number of pending finalizers\n"		 " -:w              enable garbage collection of unused symbols\n"		 " -:x              deliver uncaught exceptions of other threads to primordial one\n"		 " -:b              enter REPL on error\n"		 " -:B              sound bell on major GC\n"		 " -:aSIZE          set trace-buffer/call-chain size\n"		 "\n  SIZE may have a `k' (`K'), `m' (`M') or `g' (`G') suffix, meaning size\n"		 "  times 1024, 1048576, and 1073741824, respectively.\n\n");	  exit(0);	case 'h':	  switch(*ptr) {	  case 'i':	    *heap = arg_val(ptr + 1); 	    heap_size_changed = 1;	    goto next;	  case 'g':	    C_heap_growth = arg_val(ptr + 1);	    goto next;	  case 'm':	    C_maximal_heap_size = arg_val(ptr + 1);	    goto next;	  case 's':	    C_heap_shrinkage = arg_val(ptr + 1);	    goto next;	  default:	    *heap = arg_val(ptr); 	    heap_size_changed = 1;	    C_heap_size_is_fixed = 1;	    goto next;	  }	case 'o':	  C_disable_overflow_check = 1;	  break;	case 'B':	  gc_bell = 1;	  break;	case 's':	  *stack = arg_val(ptr);	  stack_size_changed = 1;	  goto next;	case 'f':	  C_max_pending_finalizers = arg_val(ptr);	  goto next;	case 'a':	  C_trace_buffer_size = arg_val(ptr);	  goto next;	case 't':	  *symbols = arg_val(ptr);	  goto next;	case 'c':	  fake_tty_flag = 1;	  break;	case 'd':	  debug_mode = 1;	  break;	case 'D':	  debug_mode = 2;	  break;	case 'w':	  C_enable_gcweak = 1;	  break;	case 'r':	  show_trace = 1;	  break;	case 'x':	  C_abort_on_thread_exceptions = 1;	  break;	case 'b':	  C_enable_repl = 1;	  break;	default: panic(C_text("illegal runtime option"));	}      }    next:;    }}C_word arg_val(C_char *arg){     int len;          if (arg == NULL) panic(C_text("illegal runtime-option argument"));          len = C_strlen(arg);          if(len < 1) panic(C_text("illegal runtime-option argument"));          switch(arg[ len - 1 ]) {     case 'k':     case 'K':	  return atol(arg) * 1024;	       case 'm':     case 'M':	  return atol(arg) * 1024 * 1024;	       case 'g':     case 'G':	  return atol(arg) * 1024 * 1024 * 1024;	       default:	  return atol(arg);     }}/* Run embedded code with arguments: */C_word CHICKEN_run(void *toplevel){  if(!chicken_is_initialized && !CHICKEN_initialize(0, 0, 0, toplevel))    panic(C_text("could not initialize"));  if(chicken_is_running)    panic(C_text("re-invocation of Scheme world while process is already running"));  chicken_is_running = chicken_ran_once = 1;  return_to_host = 0;#if C_STACK_GROWS_DOWNWARD  C_stack_limit = (C_word *)((C_byte *)C_stack_pointer - stack_size);#else  C_stack_limit = (C_word *)((C_byte *)C_stack_pointer + stack_size);#endif  stack_bottom = C_stack_pointer;  if(debug_mode)    C_printf(C_text("[debug] stack bottom is 0x%lx.\n"), (long)stack_bottom);  /* The point of (usually) no return... */  C_setjmp(C_restart);  if(!return_to_host)    (C_restart_trampoline)(C_restart_address);  chicken_is_running = 0;  return C_restore;}C_word CHICKEN_continue(C_word k){  if(C_temporary_stack_bottom != C_temporary_stack)    panic(C_text("invalid temporary stack level"));  if(!chicken_is_initialized)    panic(C_text("runtime system has not been initialized - `CHICKEN_run' has probably not been called"));  C_save(k);  return CHICKEN_run(NULL);}/* Trampoline called at system startup: */C_regparm void C_fcall initial_trampoline(void *proc){  TOPLEVEL top = (TOPLEVEL)proc;  C_word closure = (C_word)C_alloc(2);  ((C_SCHEME_BLOCK *)closure)->header = C_CLOSURE_TYPE | 1;  C_set_block_item(closure, 0, (C_word)termination_continuation);  (top)(2, C_SCHEME_UNDEFINED, closure);}/* The final continuation: */void C_ccall termination_continuation(C_word c, C_word self, C_word result){  if(debug_mode) C_printf(C_text("[debug] application terminated normally.\n"));  exit(0);}/* Signal unrecoverable runtime error: */void panic(C_char *msg){  C_panic_hook(msg);  usual_panic(msg);}void usual_panic(C_char *msg){  C_char *dmp = C_dump_trace(0);  C_dbg_hook(C_SCHEME_UNDEFINED);#ifdef C_MICROSOFT_WINDOWS  C_sprintf(buffer, C_text("%s\n\n%s"), msg, dmp);  MessageBox(NULL, buffer, C_text("CHICKEN runtime"), MB_OK);  ExitProcess(1);#else  C_fprintf(C_stderr, C_text("\n%s - execution terminated\n\n%s"), msg, dmp);  # if defined(__MWERKS__) && !defined(__INTEL__) && !defined(MACINTOSH_GUI)  C_printf("\n[press RETURN to exit...]");  C_fflush(C_stdout);  C_getchar();# endif  C_exit(1);#endif}void horror(C_char *msg){  C_dbg_hook(C_SCHEME_UNDEFINED);#ifdef C_MICROSOFT_WINDOWS  C_sprintf(buffer, C_text("%s"), msg);  MessageBox(NULL, buffer, C_text("CHICKEN runtime"), MB_OK);  ExitProcess(1);#else  C_fprintf(C_stderr, C_text("\n%s - execution terminated"), msg);  # if defined(__MWERKS__) && !defined(__INTEL__) && !defined(MACINTOSH_GUI)  C_printf("\n[press RETURN to exit...]");  C_fflush(C_stdout);  C_getchar();# endif  C_exit(1);#endif}/* Error-hook, called from C-level runtime routines: */void barf(int code, char *loc, ...){  C_char *msg;  C_word err = error_hook_symbol;  int c, i;  va_list v;  C_dbg_hook(C_SCHEME_UNDEFINED);  C_temporary_stack = C_temporary_stack_bottom;  err = C_u_i_car(err);  if(C_immediatep(err))    panic(C_text("`##sys#error-hook' is not defined - the `library' unit was probably not linked with this executable"));  switch(code) {  case C_BAD_ARGUMENT_COUNT_ERROR:    msg = C_text("wrong number of arguments in function call");    c = 3;    break;  case C_BAD_MINIMUM_ARGUMENT_COUNT_ERROR:    msg = C_text("too few arguments in function call");    c = 3;    break;    case C_BAD_ARGUMENT_TYPE_ERROR:    msg = C_text("bad argument type");    c = 1;    break;  case C_UNBOUND_VARIABLE_ERROR:    msg = C_text("unbound variable");    c = 1;    break;  case C_TOO_MANY_PARAMETERS_ERROR:    msg = C_text("parameter limit exceeded");    c = 0;    break;  case C_OUT_OF_MEMORY_ERROR:    msg = C_text("not enough memory");    c = 0;    break;  case C_DIVISION_BY_ZERO_ERROR:    msg = C_text("division by zero");    c = 0;    break;  case C_OUT_OF_RANGE_ERROR:    msg = C_text("out of range");    c = 2;    break;  case C_NOT_A_CLOSURE_ERROR:    msg = C_text("call of non-procedure");    c = 1;    break;  case C_CONTINUATION_CANT_RECEIVE_VALUES_ERROR:    msg = C_text("continuation can not receive multiple values");    c = 1;    break;  case C_TOO_DEEP_RECURSION_ERROR:    msg = C_text("recursion too deep");    c = 0;    break;  case C_CANT_REPRESENT_INEXACT_ERROR:    msg = C_text("inexact number can not be represented as an exact number");    c = 1;    break;  case C_NOT_A_PROPER_LIST_ERROR:    msg = C_text("argument is not a proper list");    c = 1;    break;  case C_BAD_ARGUMENT_TYPE_NO_FIXNUM_ERROR:    msg = C_text("bad argument type - not a fixnum");    c = 1;    break;  case C_BAD_ARGUMENT_TYPE_NO_STRING_ERROR:    msg = C_text("bad argument type - not a string");    c = 1;    break;  case C_BAD_ARGUMENT_TYPE_NO_PAIR_ERROR:    msg = C_text("bad argument type - not a pair");    c = 1;    break;  case C_BAD_ARGUMENT_TYPE_NO_LIST_ERROR:    msg = C_text("bad argument type - not a list");    c = 1;    break;  case C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR:    msg = C_text("bad argument type - not a number");    c = 1;    break;  case C_BAD_ARGUMENT_TYPE_NO_SYMBOL_ERROR:    msg = C_text("bad argument type - not a symbol");    c = 1;    break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -