📄 runtime.c
字号:
double compute_symbol_table_load(double *avg_bucket_len, int *total_n){ C_word bucket; int i, j, alen = 0, bcount = 0, total = 0; for(i = 0; i < symbol_table->size; ++i) { bucket = symbol_table->table[ i ]; for(j = 0; bucket != C_SCHEME_END_OF_LIST; ++j) bucket = C_u_i_cdr(bucket); if(j > 0) { alen += j; ++bcount; } total += j; } if(avg_bucket_len != NULL) *avg_bucket_len = (double)alen / (double)bcount; *total_n = total; /* return load: */ return (double)total / (double)symbol_table->size;}C_word add_symbol(C_word **ptr, C_word key, C_word string, C_SYMBOL_TABLE *stable){ C_word bucket, sym, b2, *p; int keyw = C_header_size(string) > 0 && *((char *)C_data_pointer(string)) == 0; p = *ptr; sym = (C_word)p; p += C_SIZEOF_SYMBOL; ((C_SCHEME_BLOCK *)sym)->header = C_SYMBOL_TYPE | (C_SIZEOF_SYMBOL - 1); C_set_block_item(sym, 0, keyw ? sym : C_SCHEME_UNBOUND); /* keyword? */ C_set_block_item(sym, 1, string); C_set_block_item(sym, 2, C_SCHEME_END_OF_LIST); *ptr = p; b2 = stable->table[ key ]; /* previous bucket */ bucket = C_pair(ptr, sym, b2); /* create new bucket */ ((C_SCHEME_BLOCK *)bucket)->header = (((C_SCHEME_BLOCK *)bucket)->header & ~C_HEADER_TYPE_BITS) | C_BUCKET_TYPE; if(ptr != C_heaptop) C_mutate(&stable->table[ key ], bucket); else { /* If a stack-allocated bucket was here, and we allocate from heap-top (say, in a toplevel literal frame allocation) then we have to inform the memory manager that a 2nd gen. block points to a 1st gen. block, hence the mutation: */ C_mutate(&C_u_i_cdr(bucket), b2); stable->table[ key ] = bucket; } return sym;}/* Check block allocation: */C_regparm C_word C_fcall C_permanentp(C_word x){ return C_mk_bool(!C_immediatep(x) && !C_in_stackp(x) && !C_in_heapp(x));}C_regparm int C_in_stackp(C_word x){ C_word *ptr = (C_word *)(C_uword)x;#if C_STACK_GROWS_DOWNWARD return ptr >= C_stack_pointer_test && ptr <= stack_bottom;#else return ptr < C_stack_pointer_test && ptr >= stack_bottom;#endif}C_regparm int C_fcall C_in_heapp(C_word x){ C_byte *ptr = (C_byte *)(C_uword)x; return (ptr >= fromspace_start && ptr < C_fromspace_limit) || (ptr >= tospace_start && ptr < tospace_limit);}C_regparm int C_fcall C_in_fromspacep(C_word x){ C_byte *ptr = (C_byte *)(C_uword)x; return (ptr >= fromspace_start && ptr < C_fromspace_limit);}/* Cons the rest-aguments together: */C_regparm C_word C_fcall C_restore_rest(C_word *ptr, int num){ C_word x = C_SCHEME_END_OF_LIST; C_SCHEME_BLOCK *node; while(num--) { node = (C_SCHEME_BLOCK *)ptr; ptr += 3; node->header = C_PAIR_TYPE | (C_SIZEOF_PAIR - 1); node->data[ 0 ] = C_restore; node->data[ 1 ] = x; x = (C_word)node; } return x;}C_regparm C_word C_fcall C_restore_rest_vector(C_word *ptr, int num){ C_word *p0 = ptr; *(ptr++) = C_VECTOR_TYPE | num; ptr += num; while(num--) *(--ptr) = C_restore; return (C_word)p0;}/* Print error messages and exit: */void C_bad_memory(void){ panic(C_text("there is not enough stack-space to run this executable"));}void C_bad_memory_2(void){ panic(C_text("there is not enough heap-space to run this executable - try using the '-:h...' option"));}/* The following two can be thrown out in the next release... */void C_bad_argc(int c, int n){ C_bad_argc_2(c, n, C_SCHEME_FALSE);}void C_bad_min_argc(int c, int n){ C_bad_min_argc_2(c, n, C_SCHEME_FALSE);}void C_bad_argc_2(int c, int n, C_word closure){ barf(C_BAD_ARGUMENT_COUNT_ERROR, NULL, C_fix(n - 2), C_fix(c - 2), closure);}void C_bad_min_argc_2(int c, int n, C_word closure){ barf(C_BAD_MINIMUM_ARGUMENT_COUNT_ERROR, NULL, C_fix(n - 2), C_fix(c - 2), closure);}void C_stack_overflow(void){ barf(C_STACK_OVERFLOW_ERROR, NULL);}void C_unbound_error(C_word sym){ barf(C_UNBOUND_VARIABLE_ERROR, NULL, sym);}void C_no_closure_error(C_word x){ barf(C_NOT_A_CLOSURE_ERROR, NULL, x);}/* Allocate and initialize record: */C_regparm C_word C_fcall C_string(C_word **ptr, int len, C_char *str){ C_word strblock = (C_word)(*ptr); *ptr = (C_word *)((C_word)(*ptr) + sizeof(C_header) + C_align(len)); ((C_SCHEME_BLOCK *)strblock)->header = C_STRING_TYPE | len; C_memcpy(C_data_pointer(strblock), str, len); return strblock;}C_regparm C_word C_fcall C_static_string(C_word **ptr, int len, C_char *str){ C_word *dptr = (C_word *)C_malloc(sizeof(C_header) + C_align(len)); C_word strblock; if(dptr == NULL) panic(C_text("out of memory - can not allocate static string")); strblock = (C_word)dptr; ((C_SCHEME_BLOCK *)strblock)->header = C_STRING_TYPE | len; C_memcpy(C_data_pointer(strblock), str, len); return strblock;}C_regparm C_word C_fcall C_static_lambda_info(C_word **ptr, int len, C_char *str){ int dlen = sizeof(C_header) + C_align(len); void *dptr = C_malloc(dlen); C_word strblock; if(dptr == NULL) panic(C_text("out of memory - can not allocate static lambda info")); strblock = (C_word)dptr; ((C_SCHEME_BLOCK *)strblock)->header = C_LAMBDA_INFO_TYPE | len; C_memcpy(C_data_pointer(strblock), str, len); return strblock;}C_regparm C_word C_fcall C_bytevector(C_word **ptr, int len, C_char *str){ C_word strblock = C_string(ptr, len, str); C_string_to_bytevector(strblock); return strblock;}C_regparm C_word C_fcall C_pbytevector(int len, C_char *str){ C_SCHEME_BLOCK *pbv = C_malloc(len + sizeof(C_header)); if(pbv == NULL) panic(C_text("out of memory - can not allocate permanent blob")); pbv->header = C_BYTEVECTOR_TYPE | len; C_memcpy(pbv->data, str, len); return (C_word)pbv;}C_regparm C_word C_fcall C_string_aligned8(C_word **ptr, int len, C_char *str){ C_word *p = *ptr, *p0;#ifndef C_SIXTY_FOUR /* Align on 8-byte boundary: */ if(aligned8(p)) ++p;#endif p0 = p; *ptr = p + 1 + C_bytestowords(len); *(p++) = C_STRING_TYPE | C_8ALIGN_BIT | len; C_memcpy(p, str, len); return (C_word)p0;}C_regparm C_word C_fcall C_string2(C_word **ptr, C_char *str){ C_word strblock = (C_word)(*ptr); int len; if(str == NULL) return C_SCHEME_FALSE; len = C_strlen(str); *ptr = (C_word *)((C_word)(*ptr) + sizeof(C_header) + C_align(len)); ((C_SCHEME_BLOCK *)strblock)->header = C_STRING_TYPE | len; C_memcpy(((C_SCHEME_BLOCK *)strblock)->data, str, len); return strblock;}C_regparm C_word C_fcall C_string2_safe(C_word **ptr, int max, C_char *str){ C_word strblock = (C_word)(*ptr); int len; if(str == NULL) return C_SCHEME_FALSE; len = C_strlen(str); if(len >= max) { C_sprintf(buffer, C_text("foreign string result exceeded maximum of %d bytes"), max); panic(buffer); } *ptr = (C_word *)((C_word)(*ptr) + sizeof(C_header) + C_align(len)); ((C_SCHEME_BLOCK *)strblock)->header = C_STRING_TYPE | len; C_memcpy(((C_SCHEME_BLOCK *)strblock)->data, str, len); return strblock;}C_word C_fcall C_closure(C_word **ptr, int cells, C_word proc, ...){ va_list va; C_word *p = *ptr, *p0 = p; *p = C_CLOSURE_TYPE | cells; *(++p) = proc; for(va_start(va, proc); --cells; *(++p) = va_arg(va, C_word)); va_end(va); *ptr = p + 1; return (C_word)p0;}C_regparm C_word C_fcall C_pair(C_word **ptr, C_word car, C_word cdr){ C_word *p = *ptr, *p0 = p; *(p++) = C_PAIR_TYPE | (C_SIZEOF_PAIR - 1); *(p++) = car; *(p++) = cdr; *ptr = p; return (C_word)p0;}C_regparm C_word C_fcall C_h_pair(C_word car, C_word cdr){ /* Allocate on heap and check for non-heap slots: */ C_word *p = (C_word *)C_fromspace_top, *p0 = p; *(p++) = C_PAIR_TYPE | (C_SIZEOF_PAIR - 1); if(C_in_stackp(car)) C_mutate(p++, car); else *(p++) = car; if(C_in_stackp(cdr)) C_mutate(p++, cdr); else *(p++) = cdr; C_fromspace_top = (C_byte *)p; return (C_word)p0;}C_regparm C_word C_fcall C_flonum(C_word **ptr, double n){ C_word *p = *ptr, *p0;#ifndef C_SIXTY_FOUR#ifndef C_DOUBLE_IS_32_BITS /* Align double on 8-byte boundary: */ if(aligned8(p)) ++p;#endif#endif p0 = p; *(p++) = C_FLONUM_TAG; *((double *)p) = n; *ptr = p + sizeof(double) / sizeof(C_word); return (C_word)p0;}C_regparm C_word C_fcall C_number(C_word **ptr, double n){ C_word *p = *ptr, *p0; double m; if(n <= (double)C_MOST_POSITIVE_FIXNUM && n >= (double)C_MOST_NEGATIVE_FIXNUM && modf(n, &m) == 0.0) return C_fix(n);#ifndef C_SIXTY_FOUR#ifndef C_DOUBLE_IS_32_BITS /* Align double on 8-byte boundary: */ if(aligned8(p)) ++p;#endif#endif p0 = p; *(p++) = C_FLONUM_TAG; *((double *)p) = n; *ptr = p + sizeof(double) / sizeof(C_word); return (C_word)p0;}C_regparm C_word C_fcall C_mpointer(C_word **ptr, void *mp){ C_word *p = *ptr, *p0 = p; *(p++) = C_POINTER_TYPE | 1; *((void **)p) = mp; *ptr = p + 1; return (C_word)p0;}C_regparm C_word C_fcall C_mpointer_or_false(C_word **ptr, void *mp){ C_word *p = *ptr, *p0 = p; if(mp == NULL) return C_SCHEME_FALSE; *(p++) = C_POINTER_TYPE | 1; *((void **)p) = mp; *ptr = p + 1; return (C_word)p0;}C_regparm C_word C_fcall C_taggedmpointer(C_word **ptr, C_word tag, void *mp){ C_word *p = *ptr, *p0 = p; *(p++) = C_TAGGED_POINTER_TAG; *((void **)p) = mp; *(++p) = tag; *ptr = p + 1; return (C_word)p0;}C_regparm C_word C_fcall C_taggedmpointer_or_false(C_word **ptr, C_word tag, void *mp){ C_word *p = *ptr, *p0 = p; if(mp == NULL) return C_SCHEME_FALSE; *(p++) = C_TAGGED_POINTER_TAG; *((void **)p) = mp; *(++p) = tag; *ptr = p + 1; return (C_word)p0;}C_regparm C_word C_fcall C_swigmpointer(C_word **ptr, void *mp, void *sdata){ C_word *p = *ptr, *p0 = p; *(p++) = C_SWIG_POINTER_TAG; *((void **)p) = mp; *((void **)p + 1) = sdata; *ptr = p + 2; return (C_word)p0;}C_word C_vector(C_word **ptr, int n, ...){ va_list v; C_word *p = *ptr, *p0 = p; *(p++) = C_VECTOR_TYPE | n; va_start(v, n); while(n--) *(p++) = va_arg(v, C_word); *ptr = p; va_end(v); return (C_word)p0;}C_word C_structure(C_word **ptr, int n, ...){ va_list v; C_word *p = *ptr, *p0 = p; *(p++) = C_STRUCTURE_TYPE | n; va_start(v, n); while(n--) *(p++) = va_arg(v, C_word); *ptr = p; va_end(v); return (C_word)p0;}C_word C_h_vector(int n, ...){ /* As C_vector(), but remember slots containing nursery pointers: */ va_list v; C_word *p = (C_word *)C_fromspace_top, *p0 = p, x; *(p++) = C_VECTOR_TYPE | n; va_start(v
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -